sokol_gfx_imgui.h 196 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865
  1. #if defined(SOKOL_IMPL) && !defined(SOKOL_GFX_IMGUI_IMPL)
  2. #define SOKOL_GFX_IMGUI_IMPL
  3. #endif
  4. #ifndef SOKOL_GFX_IMGUI_INCLUDED
  5. /*
  6. sokol_gfx_imgui.h -- debug-inspection UI for sokol_gfx.h using Dear ImGui
  7. Project URL: https://github.com/floooh/sokol
  8. Do this:
  9. #define SOKOL_IMPL or
  10. #define SOKOL_GFX_IMGUI_IMPL
  11. before you include this file in *one* C or C++ file to create the
  12. implementation.
  13. NOTE that the implementation can be compiled either as C++ or as C.
  14. When compiled as C++, sokol_gfx_imgui.h will directly call into the
  15. Dear ImGui C++ API. When compiled as C, sokol_gfx_imgui.h will call
  16. cimgui.h functions instead.
  17. Include the following file(s) before including sokol_gfx_imgui.h:
  18. sokol_gfx.h
  19. Additionally, include the following headers before including the
  20. implementation:
  21. If the implementation is compiled as C++:
  22. imgui.h
  23. If the implementation is compiled as C:
  24. cimgui.h
  25. The sokol_gfx.h implementation must be compiled with debug trace hooks
  26. enabled by defining:
  27. SOKOL_TRACE_HOOKS
  28. ...before including the sokol_gfx.h implementation.
  29. Before including the sokol_gfx_imgui.h implementation, optionally
  30. override the following macros:
  31. SOKOL_ASSERT(c) -- your own assert macro, default: assert(c)
  32. SOKOL_UNREACHABLE -- your own macro to annotate unreachable code,
  33. default: SOKOL_ASSERT(false)
  34. SOKOL_GFX_IMGUI_API_DECL - public function declaration prefix (default: extern)
  35. SOKOL_API_DECL - same as SOKOL_GFX_IMGUI_API_DECL
  36. SOKOL_API_IMPL - public function implementation prefix (default: -)
  37. If sokol_gfx_imgui.h is compiled as a DLL, define the following before
  38. including the declaration or implementation:
  39. SOKOL_DLL
  40. On Windows, SOKOL_DLL will define SOKOL_GFX_IMGUI_API_DECL as __declspec(dllexport)
  41. or __declspec(dllimport) as needed.
  42. STEP BY STEP:
  43. =============
  44. --- create an sgimgui_t struct (which must be preserved between frames)
  45. and initialize it with:
  46. sgimgui_init(&sgimgui, &(sgimgui_desc_t){ 0 });
  47. Note that from C++ you can't inline the desc structure initialization:
  48. const sgimgui_desc_t desc = { };
  49. sgimgui_init(&sgimgui, &desc);
  50. Provide optional memory allocator override functions (compatible with malloc/free) like this:
  51. sgimgui_init(&sgimgui, &(sgimgui_desc_t){
  52. .allocator = {
  53. .alloc_fn = my_malloc,
  54. .free_fn = my_free,
  55. }
  56. });
  57. --- somewhere in the per-frame code call:
  58. sgimgui_draw(&sgimgui)
  59. this won't draw anything yet, since no windows are open.
  60. --- call the convenience function sgimgui_draw_menu(ctx, title)
  61. to render a menu which allows to open/close the provided debug windows
  62. sgimgui_draw_menu(&sgimgui, "sokol-gfx");
  63. --- alternative, open and close windows directly by setting the following public
  64. booleans in the sgimgui_t struct:
  65. sgimgui.caps_window.open = true;
  66. sgimgui.frame_stats_window.open = true;
  67. sgimgui.buffer_window.open = true;
  68. sgimgui.image_window.open = true;
  69. sgimgui.sampler_window.open = true;
  70. sgimgui.shader_window.open = true;
  71. sgimgui.pipeline_window.open = true;
  72. sgimgui.attachments_window.open = true;
  73. sgimgui.capture_window.open = true;
  74. sgimgui.frame_stats_window.open = true;
  75. ...for instance, to control the window visibility through
  76. menu items, the following code can be used:
  77. if (ImGui::BeginMainMenuBar()) {
  78. if (ImGui::BeginMenu("sokol-gfx")) {
  79. ImGui::MenuItem("Capabilities", 0, &sgimgui.caps_window.open);
  80. ImGui::MenuItem("Frame Stats", 0, &sgimgui.frame_stats_window.open);
  81. ImGui::MenuItem("Buffers", 0, &sgimgui.buffer_window.open);
  82. ImGui::MenuItem("Images", 0, &sgimgui.image_window.open);
  83. ImGui::MenuItem("Samplers", 0, &sgimgui.sampler_window.open);
  84. ImGui::MenuItem("Shaders", 0, &sgimgui.shader_window.open);
  85. ImGui::MenuItem("Pipelines", 0, &sgimgui.pipeline_window.open);
  86. ImGui::MenuItem("Attachments", 0, &sgimgui.attachments_window.open);
  87. ImGui::MenuItem("Calls", 0, &sgimgui.capture_window.open);
  88. ImGui::EndMenu();
  89. }
  90. ImGui::EndMainMenuBar();
  91. }
  92. --- before application shutdown, call:
  93. sgimgui_discard(&sgimgui);
  94. ...this is not strictly necessary because the application exits
  95. anyway, but not doing this may trigger memory leak detection tools.
  96. --- finally, your application needs an ImGui renderer, you can either
  97. provide your own, or drop in the sokol_imgui.h utility header
  98. ALTERNATIVE DRAWING FUNCTIONS:
  99. ==============================
  100. Instead of the convenient, but all-in-one sgimgui_draw() function,
  101. you can also use the following granular functions which might allow
  102. better integration with your existing UI:
  103. The following functions only render the window *content* (so you
  104. can integrate the UI into you own windows):
  105. void sgimgui_draw_buffer_window_content(sgimgui_t* ctx);
  106. void sgimgui_draw_image_window_content(sgimgui_t* ctx);
  107. void sgimgui_draw_sampler_window_content(sgimgui_t* ctx);
  108. void sgimgui_draw_shader_window_content(sgimgui_t* ctx);
  109. void sgimgui_draw_pipeline_window_content(sgimgui_t* ctx);
  110. void sgimgui_draw_attachments_window_content(sgimgui_t* ctx);
  111. void sgimgui_draw_capture_window_content(sgimgui_t* ctx);
  112. And these are the 'full window' drawing functions:
  113. void sgimgui_draw_buffer_window(sgimgui_t* ctx);
  114. void sgimgui_draw_image_window(sgimgui_t* ctx);
  115. void sgimgui_draw_sampler_window(sgimgui_t* ctx);
  116. void sgimgui_draw_shader_window(sgimgui_t* ctx);
  117. void sgimgui_draw_pipeline_window(sgimgui_t* ctx);
  118. void sgimgui_draw_attachments_window(sgimgui_t* ctx);
  119. void sgimgui_draw_capture_window(sgimgui_t* ctx);
  120. Finer-grained drawing functions may be moved to the public API
  121. in the future as needed.
  122. MEMORY ALLOCATION OVERRIDE
  123. ==========================
  124. You can override the memory allocation functions at initialization time
  125. like this:
  126. void* my_alloc(size_t size, void* user_data) {
  127. return malloc(size);
  128. }
  129. void my_free(void* ptr, void* user_data) {
  130. free(ptr);
  131. }
  132. ...
  133. sgimgui_init(&(&ctx, &(sgimgui_desc_t){
  134. // ...
  135. .allocator = {
  136. .alloc_fn = my_alloc,
  137. .free_fn = my_free,
  138. .user_data = ...;
  139. }
  140. });
  141. ...
  142. This only affects memory allocation calls done by sokol_gfx_imgui.h
  143. itself though, not any allocations in OS libraries.
  144. LICENSE
  145. =======
  146. zlib/libpng license
  147. Copyright (c) 2018 Andre Weissflog
  148. This software is provided 'as-is', without any express or implied warranty.
  149. In no event will the authors be held liable for any damages arising from the
  150. use of this software.
  151. Permission is granted to anyone to use this software for any purpose,
  152. including commercial applications, and to alter it and redistribute it
  153. freely, subject to the following restrictions:
  154. 1. The origin of this software must not be misrepresented; you must not
  155. claim that you wrote the original software. If you use this software in a
  156. product, an acknowledgment in the product documentation would be
  157. appreciated but is not required.
  158. 2. Altered source versions must be plainly marked as such, and must not
  159. be misrepresented as being the original software.
  160. 3. This notice may not be removed or altered from any source
  161. distribution.
  162. */
  163. #define SOKOL_GFX_IMGUI_INCLUDED (1)
  164. #include <stdint.h>
  165. #include <stdbool.h>
  166. #include <stddef.h> // size_t
  167. #if !defined(SOKOL_GFX_INCLUDED)
  168. #error "Please include sokol_gfx.h before sokol_gfx_imgui.h"
  169. #endif
  170. #if defined(SOKOL_API_DECL) && !defined(SOKOL_GFX_IMGUI_API_DECL)
  171. #define SOKOL_GFX_IMGUI_API_DECL SOKOL_API_DECL
  172. #endif
  173. #ifndef SOKOL_GFX_IMGUI_API_DECL
  174. #if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_GFX_IMGUI_IMPL)
  175. #define SOKOL_GFX_IMGUI_API_DECL __declspec(dllexport)
  176. #elif defined(_WIN32) && defined(SOKOL_DLL)
  177. #define SOKOL_GFX_IMGUI_API_DECL __declspec(dllimport)
  178. #else
  179. #define SOKOL_GFX_IMGUI_API_DECL extern
  180. #endif
  181. #endif
  182. #if defined(__cplusplus)
  183. extern "C" {
  184. #endif
  185. #define sgimgui_STRBUF_LEN (96)
  186. /* max number of captured calls per frame */
  187. #define sgimgui_MAX_FRAMECAPTURE_ITEMS (4096)
  188. typedef struct sgimgui_str_t {
  189. char buf[sgimgui_STRBUF_LEN];
  190. } sgimgui_str_t;
  191. typedef struct sgimgui_buffer_t {
  192. sg_buffer res_id;
  193. sgimgui_str_t label;
  194. sg_buffer_desc desc;
  195. } sgimgui_buffer_t;
  196. typedef struct sgimgui_image_t {
  197. sg_image res_id;
  198. float ui_scale;
  199. sgimgui_str_t label;
  200. sg_image_desc desc;
  201. } sgimgui_image_t;
  202. typedef struct sgimgui_sampler_t {
  203. sg_sampler res_id;
  204. sgimgui_str_t label;
  205. sg_sampler_desc desc;
  206. } sgimgui_sampler_t;
  207. typedef struct sgimgui_shader_t {
  208. sg_shader res_id;
  209. sgimgui_str_t label;
  210. sgimgui_str_t vs_entry;
  211. sgimgui_str_t vs_d3d11_target;
  212. sgimgui_str_t fs_entry;
  213. sgimgui_str_t fs_d3d11_target;
  214. sgimgui_str_t glsl_image_sampler_name[SG_MAX_IMAGE_SAMPLER_PAIRS];
  215. sgimgui_str_t glsl_uniform_name[SG_MAX_UNIFORMBLOCK_BINDSLOTS][SG_MAX_UNIFORMBLOCK_MEMBERS];
  216. sgimgui_str_t attr_glsl_name[SG_MAX_VERTEX_ATTRIBUTES];
  217. sgimgui_str_t attr_hlsl_sem_name[SG_MAX_VERTEX_ATTRIBUTES];
  218. sg_shader_desc desc;
  219. } sgimgui_shader_t;
  220. typedef struct sgimgui_pipeline_t {
  221. sg_pipeline res_id;
  222. sgimgui_str_t label;
  223. sg_pipeline_desc desc;
  224. } sgimgui_pipeline_t;
  225. typedef struct sgimgui_attachments_t {
  226. sg_attachments res_id;
  227. sgimgui_str_t label;
  228. float color_image_scale[SG_MAX_COLOR_ATTACHMENTS];
  229. float resolve_image_scale[SG_MAX_COLOR_ATTACHMENTS];
  230. float ds_image_scale;
  231. float storage_image_scale[SG_MAX_STORAGE_ATTACHMENTS];
  232. sg_attachments_desc desc;
  233. } sgimgui_attachments_t;
  234. typedef struct sgimgui_buffer_window_t {
  235. bool open;
  236. int num_slots;
  237. sg_buffer sel_buf;
  238. sgimgui_buffer_t* slots;
  239. } sgimgui_buffer_window_t;
  240. typedef struct sgimgui_image_window_t {
  241. bool open;
  242. int num_slots;
  243. sg_image sel_img;
  244. sgimgui_image_t* slots;
  245. } sgimgui_image_window_t;
  246. typedef struct sgimgui_sampler_window_t {
  247. bool open;
  248. int num_slots;
  249. sg_sampler sel_smp;
  250. sgimgui_sampler_t* slots;
  251. } sgimgui_sampler_window_t;
  252. typedef struct sgimgui_shader_window_t {
  253. bool open;
  254. int num_slots;
  255. sg_shader sel_shd;
  256. sgimgui_shader_t* slots;
  257. } sgimgui_shader_window_t;
  258. typedef struct sgimgui_pipeline_window_t {
  259. bool open;
  260. int num_slots;
  261. sg_pipeline sel_pip;
  262. sgimgui_pipeline_t* slots;
  263. } sgimgui_pipeline_window_t;
  264. typedef struct sgimgui_attachments_window_t {
  265. bool open;
  266. int num_slots;
  267. sg_attachments sel_atts;
  268. sgimgui_attachments_t* slots;
  269. } sgimgui_attachments_window_t;
  270. typedef enum sgimgui_cmd_t {
  271. SGIMGUI_CMD_INVALID,
  272. SGIMGUI_CMD_RESET_STATE_CACHE,
  273. SGIMGUI_CMD_MAKE_BUFFER,
  274. SGIMGUI_CMD_MAKE_IMAGE,
  275. SGIMGUI_CMD_MAKE_SAMPLER,
  276. SGIMGUI_CMD_MAKE_SHADER,
  277. SGIMGUI_CMD_MAKE_PIPELINE,
  278. SGIMGUI_CMD_MAKE_ATTACHMENTS,
  279. SGIMGUI_CMD_DESTROY_BUFFER,
  280. SGIMGUI_CMD_DESTROY_IMAGE,
  281. SGIMGUI_CMD_DESTROY_SAMPLER,
  282. SGIMGUI_CMD_DESTROY_SHADER,
  283. SGIMGUI_CMD_DESTROY_PIPELINE,
  284. SGIMGUI_CMD_DESTROY_ATTACHMENTS,
  285. SGIMGUI_CMD_UPDATE_BUFFER,
  286. SGIMGUI_CMD_UPDATE_IMAGE,
  287. SGIMGUI_CMD_APPEND_BUFFER,
  288. SGIMGUI_CMD_BEGIN_PASS,
  289. SGIMGUI_CMD_APPLY_VIEWPORT,
  290. SGIMGUI_CMD_APPLY_SCISSOR_RECT,
  291. SGIMGUI_CMD_APPLY_PIPELINE,
  292. SGIMGUI_CMD_APPLY_BINDINGS,
  293. SGIMGUI_CMD_APPLY_UNIFORMS,
  294. SGIMGUI_CMD_DRAW,
  295. SGIMGUI_CMD_DISPATCH,
  296. SGIMGUI_CMD_END_PASS,
  297. SGIMGUI_CMD_COMMIT,
  298. SGIMGUI_CMD_ALLOC_BUFFER,
  299. SGIMGUI_CMD_ALLOC_IMAGE,
  300. SGIMGUI_CMD_ALLOC_SAMPLER,
  301. SGIMGUI_CMD_ALLOC_SHADER,
  302. SGIMGUI_CMD_ALLOC_PIPELINE,
  303. SGIMGUI_CMD_ALLOC_ATTACHMENTS,
  304. SGIMGUI_CMD_DEALLOC_BUFFER,
  305. SGIMGUI_CMD_DEALLOC_IMAGE,
  306. SGIMGUI_CMD_DEALLOC_SAMPLER,
  307. SGIMGUI_CMD_DEALLOC_SHADER,
  308. SGIMGUI_CMD_DEALLOC_PIPELINE,
  309. SGIMGUI_CMD_DEALLOC_ATTACHMENTS,
  310. SGIMGUI_CMD_INIT_BUFFER,
  311. SGIMGUI_CMD_INIT_IMAGE,
  312. SGIMGUI_CMD_INIT_SAMPLER,
  313. SGIMGUI_CMD_INIT_SHADER,
  314. SGIMGUI_CMD_INIT_PIPELINE,
  315. SGIMGUI_CMD_INIT_ATTACHMENTS,
  316. SGIMGUI_CMD_UNINIT_BUFFER,
  317. SGIMGUI_CMD_UNINIT_IMAGE,
  318. SGIMGUI_CMD_UNINIT_SAMPLER,
  319. SGIMGUI_CMD_UNINIT_SHADER,
  320. SGIMGUI_CMD_UNINIT_PIPELINE,
  321. SGIMGUI_CMD_UNINIT_ATTACHMENTS,
  322. SGIMGUI_CMD_FAIL_BUFFER,
  323. SGIMGUI_CMD_FAIL_IMAGE,
  324. SGIMGUI_CMD_FAIL_SAMPLER,
  325. SGIMGUI_CMD_FAIL_SHADER,
  326. SGIMGUI_CMD_FAIL_PIPELINE,
  327. SGIMGUI_CMD_FAIL_ATTACHMENTS,
  328. SGIMGUI_CMD_PUSH_DEBUG_GROUP,
  329. SGIMGUI_CMD_POP_DEBUG_GROUP,
  330. } sgimgui_cmd_t;
  331. typedef struct sgimgui_args_make_buffer_t {
  332. sg_buffer result;
  333. } sgimgui_args_make_buffer_t;
  334. typedef struct sgimgui_args_make_image_t {
  335. sg_image result;
  336. } sgimgui_args_make_image_t;
  337. typedef struct sgimgui_args_make_sampler_t {
  338. sg_sampler result;
  339. } sgimgui_args_make_sampler_t;
  340. typedef struct sgimgui_args_make_shader_t {
  341. sg_shader result;
  342. } sgimgui_args_make_shader_t;
  343. typedef struct sgimgui_args_make_pipeline_t {
  344. sg_pipeline result;
  345. } sgimgui_args_make_pipeline_t;
  346. typedef struct sgimgui_args_make_attachments_t {
  347. sg_attachments result;
  348. } sgimgui_args_make_attachments_t;
  349. typedef struct sgimgui_args_destroy_buffer_t {
  350. sg_buffer buffer;
  351. } sgimgui_args_destroy_buffer_t;
  352. typedef struct sgimgui_args_destroy_image_t {
  353. sg_image image;
  354. } sgimgui_args_destroy_image_t;
  355. typedef struct sgimgui_args_destroy_sampler_t {
  356. sg_sampler sampler;
  357. } sgimgui_args_destroy_sampler_t;
  358. typedef struct sgimgui_args_destroy_shader_t {
  359. sg_shader shader;
  360. } sgimgui_args_destroy_shader_t;
  361. typedef struct sgimgui_args_destroy_pipeline_t {
  362. sg_pipeline pipeline;
  363. } sgimgui_args_destroy_pipeline_t;
  364. typedef struct sgimgui_args_destroy_attachments_t {
  365. sg_attachments attachments;
  366. } sgimgui_args_destroy_attachments_t;
  367. typedef struct sgimgui_args_update_buffer_t {
  368. sg_buffer buffer;
  369. size_t data_size;
  370. } sgimgui_args_update_buffer_t;
  371. typedef struct sgimgui_args_update_image_t {
  372. sg_image image;
  373. } sgimgui_args_update_image_t;
  374. typedef struct sgimgui_args_append_buffer_t {
  375. sg_buffer buffer;
  376. size_t data_size;
  377. int result;
  378. } sgimgui_args_append_buffer_t;
  379. typedef struct sgimgui_args_begin_pass_t {
  380. sg_pass pass;
  381. } sgimgui_args_begin_pass_t;
  382. typedef struct sgimgui_args_apply_viewport_t {
  383. int x, y, width, height;
  384. bool origin_top_left;
  385. } sgimgui_args_apply_viewport_t;
  386. typedef struct sgimgui_args_apply_scissor_rect_t {
  387. int x, y, width, height;
  388. bool origin_top_left;
  389. } sgimgui_args_apply_scissor_rect_t;
  390. typedef struct sgimgui_args_apply_pipeline_t {
  391. sg_pipeline pipeline;
  392. } sgimgui_args_apply_pipeline_t;
  393. typedef struct sgimgui_args_apply_bindings_t {
  394. sg_bindings bindings;
  395. } sgimgui_args_apply_bindings_t;
  396. typedef struct sgimgui_args_apply_uniforms_t {
  397. int ub_slot;
  398. size_t data_size;
  399. sg_pipeline pipeline; /* the pipeline which was active at this call */
  400. size_t ubuf_pos; /* start of copied data in capture buffer */
  401. } sgimgui_args_apply_uniforms_t;
  402. typedef struct sgimgui_args_draw_t {
  403. int base_element;
  404. int num_elements;
  405. int num_instances;
  406. } sgimgui_args_draw_t;
  407. typedef struct sgimgui_args_dispatch_t {
  408. int num_groups_x;
  409. int num_groups_y;
  410. int num_groups_z;
  411. } sgimgui_args_dispatch_t;
  412. typedef struct sgimgui_args_alloc_buffer_t {
  413. sg_buffer result;
  414. } sgimgui_args_alloc_buffer_t;
  415. typedef struct sgimgui_args_alloc_image_t {
  416. sg_image result;
  417. } sgimgui_args_alloc_image_t;
  418. typedef struct sgimgui_args_alloc_sampler_t {
  419. sg_sampler result;
  420. } sgimgui_args_alloc_sampler_t;
  421. typedef struct sgimgui_args_alloc_shader_t {
  422. sg_shader result;
  423. } sgimgui_args_alloc_shader_t;
  424. typedef struct sgimgui_args_alloc_pipeline_t {
  425. sg_pipeline result;
  426. } sgimgui_args_alloc_pipeline_t;
  427. typedef struct sgimgui_args_alloc_attachments_t {
  428. sg_attachments result;
  429. } sgimgui_args_alloc_attachments_t;
  430. typedef struct sgimgui_args_dealloc_buffer_t {
  431. sg_buffer buffer;
  432. } sgimgui_args_dealloc_buffer_t;
  433. typedef struct sgimgui_args_dealloc_image_t {
  434. sg_image image;
  435. } sgimgui_args_dealloc_image_t;
  436. typedef struct sgimgui_args_dealloc_sampler_t {
  437. sg_sampler sampler;
  438. } sgimgui_args_dealloc_sampler_t;
  439. typedef struct sgimgui_args_dealloc_shader_t {
  440. sg_shader shader;
  441. } sgimgui_args_dealloc_shader_t;
  442. typedef struct sgimgui_args_dealloc_pipeline_t {
  443. sg_pipeline pipeline;
  444. } sgimgui_args_dealloc_pipeline_t;
  445. typedef struct sgimgui_args_dealloc_attachments_t {
  446. sg_attachments attachments;
  447. } sgimgui_args_dealloc_attachments_t;
  448. typedef struct sgimgui_args_init_buffer_t {
  449. sg_buffer buffer;
  450. } sgimgui_args_init_buffer_t;
  451. typedef struct sgimgui_args_init_image_t {
  452. sg_image image;
  453. } sgimgui_args_init_image_t;
  454. typedef struct sgimgui_args_init_sampler_t {
  455. sg_sampler sampler;
  456. } sgimgui_args_init_sampler_t;
  457. typedef struct sgimgui_args_init_shader_t {
  458. sg_shader shader;
  459. } sgimgui_args_init_shader_t;
  460. typedef struct sgimgui_args_init_pipeline_t {
  461. sg_pipeline pipeline;
  462. } sgimgui_args_init_pipeline_t;
  463. typedef struct sgimgui_args_init_attachments_t {
  464. sg_attachments attachments;
  465. } sgimgui_args_init_attachments_t;
  466. typedef struct sgimgui_args_uninit_buffer_t {
  467. sg_buffer buffer;
  468. } sgimgui_args_uninit_buffer_t;
  469. typedef struct sgimgui_args_uninit_image_t {
  470. sg_image image;
  471. } sgimgui_args_uninit_image_t;
  472. typedef struct sgimgui_args_uninit_sampler_t {
  473. sg_sampler sampler;
  474. } sgimgui_args_uninit_sampler_t;
  475. typedef struct sgimgui_args_uninit_shader_t {
  476. sg_shader shader;
  477. } sgimgui_args_uninit_shader_t;
  478. typedef struct sgimgui_args_uninit_pipeline_t {
  479. sg_pipeline pipeline;
  480. } sgimgui_args_uninit_pipeline_t;
  481. typedef struct sgimgui_args_uninit_attachments_t {
  482. sg_attachments attachments;
  483. } sgimgui_args_uninit_attachments_t;
  484. typedef struct sgimgui_args_fail_buffer_t {
  485. sg_buffer buffer;
  486. } sgimgui_args_fail_buffer_t;
  487. typedef struct sgimgui_args_fail_image_t {
  488. sg_image image;
  489. } sgimgui_args_fail_image_t;
  490. typedef struct sgimgui_args_fail_sampler_t {
  491. sg_sampler sampler;
  492. } sgimgui_args_fail_sampler_t;
  493. typedef struct sgimgui_args_fail_shader_t {
  494. sg_shader shader;
  495. } sgimgui_args_fail_shader_t;
  496. typedef struct sgimgui_args_fail_pipeline_t {
  497. sg_pipeline pipeline;
  498. } sgimgui_args_fail_pipeline_t;
  499. typedef struct sgimgui_args_fail_attachments_t {
  500. sg_attachments attachments;
  501. } sgimgui_args_fail_attachments_t;
  502. typedef struct sgimgui_args_push_debug_group_t {
  503. sgimgui_str_t name;
  504. } sgimgui_args_push_debug_group_t;
  505. typedef union sgimgui_args_t {
  506. sgimgui_args_make_buffer_t make_buffer;
  507. sgimgui_args_make_image_t make_image;
  508. sgimgui_args_make_sampler_t make_sampler;
  509. sgimgui_args_make_shader_t make_shader;
  510. sgimgui_args_make_pipeline_t make_pipeline;
  511. sgimgui_args_make_attachments_t make_attachments;
  512. sgimgui_args_destroy_buffer_t destroy_buffer;
  513. sgimgui_args_destroy_image_t destroy_image;
  514. sgimgui_args_destroy_sampler_t destroy_sampler;
  515. sgimgui_args_destroy_shader_t destroy_shader;
  516. sgimgui_args_destroy_pipeline_t destroy_pipeline;
  517. sgimgui_args_destroy_attachments_t destroy_attachments;
  518. sgimgui_args_update_buffer_t update_buffer;
  519. sgimgui_args_update_image_t update_image;
  520. sgimgui_args_append_buffer_t append_buffer;
  521. sgimgui_args_begin_pass_t begin_pass;
  522. sgimgui_args_apply_viewport_t apply_viewport;
  523. sgimgui_args_apply_scissor_rect_t apply_scissor_rect;
  524. sgimgui_args_apply_pipeline_t apply_pipeline;
  525. sgimgui_args_apply_bindings_t apply_bindings;
  526. sgimgui_args_apply_uniforms_t apply_uniforms;
  527. sgimgui_args_draw_t draw;
  528. sgimgui_args_dispatch_t dispatch;
  529. sgimgui_args_alloc_buffer_t alloc_buffer;
  530. sgimgui_args_alloc_image_t alloc_image;
  531. sgimgui_args_alloc_sampler_t alloc_sampler;
  532. sgimgui_args_alloc_shader_t alloc_shader;
  533. sgimgui_args_alloc_pipeline_t alloc_pipeline;
  534. sgimgui_args_alloc_attachments_t alloc_attachments;
  535. sgimgui_args_dealloc_buffer_t dealloc_buffer;
  536. sgimgui_args_dealloc_image_t dealloc_image;
  537. sgimgui_args_dealloc_sampler_t dealloc_sampler;
  538. sgimgui_args_dealloc_shader_t dealloc_shader;
  539. sgimgui_args_dealloc_pipeline_t dealloc_pipeline;
  540. sgimgui_args_dealloc_attachments_t dealloc_attachments;
  541. sgimgui_args_init_buffer_t init_buffer;
  542. sgimgui_args_init_image_t init_image;
  543. sgimgui_args_init_sampler_t init_sampler;
  544. sgimgui_args_init_shader_t init_shader;
  545. sgimgui_args_init_pipeline_t init_pipeline;
  546. sgimgui_args_init_attachments_t init_attachments;
  547. sgimgui_args_uninit_buffer_t uninit_buffer;
  548. sgimgui_args_uninit_image_t uninit_image;
  549. sgimgui_args_uninit_sampler_t uninit_sampler;
  550. sgimgui_args_uninit_shader_t uninit_shader;
  551. sgimgui_args_uninit_pipeline_t uninit_pipeline;
  552. sgimgui_args_uninit_attachments_t uninit_attachments;
  553. sgimgui_args_fail_buffer_t fail_buffer;
  554. sgimgui_args_fail_image_t fail_image;
  555. sgimgui_args_fail_sampler_t fail_sampler;
  556. sgimgui_args_fail_shader_t fail_shader;
  557. sgimgui_args_fail_pipeline_t fail_pipeline;
  558. sgimgui_args_fail_attachments_t fail_attachments;
  559. sgimgui_args_push_debug_group_t push_debug_group;
  560. } sgimgui_args_t;
  561. typedef struct sgimgui_capture_item_t {
  562. sgimgui_cmd_t cmd;
  563. uint32_t color;
  564. sgimgui_args_t args;
  565. } sgimgui_capture_item_t;
  566. typedef struct sgimgui_capture_bucket_t {
  567. size_t ubuf_size; /* size of uniform capture buffer in bytes */
  568. size_t ubuf_pos; /* current uniform buffer pos */
  569. uint8_t* ubuf; /* buffer for capturing uniform updates */
  570. int num_items;
  571. sgimgui_capture_item_t items[sgimgui_MAX_FRAMECAPTURE_ITEMS];
  572. } sgimgui_capture_bucket_t;
  573. /* double-buffered call-capture buckets, one bucket is currently recorded,
  574. the previous bucket is displayed
  575. */
  576. typedef struct sgimgui_capture_window_t {
  577. bool open;
  578. int bucket_index; /* which bucket to record to, 0 or 1 */
  579. int sel_item; /* currently selected capture item by index */
  580. sgimgui_capture_bucket_t bucket[2];
  581. } sgimgui_capture_window_t;
  582. typedef struct sgimgui_caps_window_t {
  583. bool open;
  584. } sgimgui_caps_window_t;
  585. typedef struct sgimgui_frame_stats_window_t {
  586. bool open;
  587. bool disable_sokol_imgui_stats;
  588. bool in_sokol_imgui;
  589. sg_frame_stats stats;
  590. // FIXME: add a ringbuffer for a stats history here
  591. } sgimgui_frame_stats_window_t;
  592. /*
  593. sgimgui_allocator_t
  594. Used in sgimgui_desc_t to provide custom memory-alloc and -free functions
  595. to sokol_gfx_imgui.h. If memory management should be overridden, both the
  596. alloc and free function must be provided (e.g. it's not valid to
  597. override one function but not the other).
  598. */
  599. typedef struct sgimgui_allocator_t {
  600. void* (*alloc_fn)(size_t size, void* user_data);
  601. void (*free_fn)(void* ptr, void* user_data);
  602. void* user_data;
  603. } sgimgui_allocator_t;
  604. /*
  605. sgimgui_desc_t
  606. Initialization options for sgimgui_init().
  607. */
  608. typedef struct sgimgui_desc_t {
  609. sgimgui_allocator_t allocator; // optional memory allocation overrides (default: malloc/free)
  610. } sgimgui_desc_t;
  611. typedef struct sgimgui_t {
  612. uint32_t init_tag;
  613. sgimgui_desc_t desc;
  614. sgimgui_buffer_window_t buffer_window;
  615. sgimgui_image_window_t image_window;
  616. sgimgui_sampler_window_t sampler_window;
  617. sgimgui_shader_window_t shader_window;
  618. sgimgui_pipeline_window_t pipeline_window;
  619. sgimgui_attachments_window_t attachments_window;
  620. sgimgui_capture_window_t capture_window;
  621. sgimgui_caps_window_t caps_window;
  622. sgimgui_frame_stats_window_t frame_stats_window;
  623. sg_pipeline cur_pipeline;
  624. sg_trace_hooks hooks;
  625. } sgimgui_t;
  626. SOKOL_GFX_IMGUI_API_DECL void sgimgui_init(sgimgui_t* ctx, const sgimgui_desc_t* desc);
  627. SOKOL_GFX_IMGUI_API_DECL void sgimgui_discard(sgimgui_t* ctx);
  628. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw(sgimgui_t* ctx);
  629. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_menu(sgimgui_t* ctx, const char* title);
  630. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_buffer_window_content(sgimgui_t* ctx);
  631. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_image_window_content(sgimgui_t* ctx);
  632. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_sampler_window_content(sgimgui_t* ctx);
  633. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_shader_window_content(sgimgui_t* ctx);
  634. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_pipeline_window_content(sgimgui_t* ctx);
  635. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_attachments_window_content(sgimgui_t* ctx);
  636. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_capture_window_content(sgimgui_t* ctx);
  637. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_capabilities_window_content(sgimgui_t* ctx);
  638. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_frame_stats_window_content(sgimgui_t* ctx);
  639. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_buffer_window(sgimgui_t* ctx);
  640. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_image_window(sgimgui_t* ctx);
  641. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_sampler_window(sgimgui_t* ctx);
  642. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_shader_window(sgimgui_t* ctx);
  643. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_pipeline_window(sgimgui_t* ctx);
  644. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_attachments_window(sgimgui_t* ctx);
  645. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_capture_window(sgimgui_t* ctx);
  646. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_capabilities_window(sgimgui_t* ctx);
  647. SOKOL_GFX_IMGUI_API_DECL void sgimgui_draw_frame_stats_window(sgimgui_t* ctx);
  648. #if defined(__cplusplus)
  649. } /* extern "C" */
  650. #endif
  651. #endif /* SOKOL_GFX_IMGUI_INCLUDED */
  652. /*=== IMPLEMENTATION =========================================================*/
  653. #ifdef SOKOL_GFX_IMGUI_IMPL
  654. #define SOKOL_GFX_IMGUI_IMPL_INCLUDED (1)
  655. #if defined(SOKOL_MALLOC) || defined(SOKOL_CALLOC) || defined(SOKOL_FREE)
  656. #error "SOKOL_MALLOC/CALLOC/FREE macros are no longer supported, please use sgimgui_desc_t.allocator to override memory allocation functions"
  657. #endif
  658. #if defined(__cplusplus)
  659. #if !defined(IMGUI_VERSION)
  660. #error "Please include imgui.h before the sokol_imgui.h implementation"
  661. #endif
  662. #else
  663. #if !defined(CIMGUI_API)
  664. #error "Please include cimgui.h before the sokol_imgui.h implementation"
  665. #endif
  666. #endif
  667. #ifndef SOKOL_ASSERT
  668. #include <assert.h>
  669. #define SOKOL_ASSERT(c) assert(c)
  670. #endif
  671. #ifndef SOKOL_UNREACHABLE
  672. #define SOKOL_UNREACHABLE SOKOL_ASSERT(false)
  673. #endif
  674. #ifndef _SOKOL_PRIVATE
  675. #if defined(__GNUC__) || defined(__clang__)
  676. #define _SOKOL_PRIVATE __attribute__((unused)) static
  677. #else
  678. #define _SOKOL_PRIVATE static
  679. #endif
  680. #endif
  681. #ifndef _SOKOL_UNUSED
  682. #define _SOKOL_UNUSED(x) (void)(x)
  683. #endif
  684. #ifndef SOKOL_API_IMPL
  685. #define SOKOL_API_IMPL
  686. #endif
  687. #include <string.h>
  688. #include <stdio.h> // snprintf
  689. #include <stdlib.h> // malloc, free
  690. #define _SGIMGUI_SLOT_MASK (0xFFFF)
  691. #define _SGIMGUI_LIST_WIDTH (192)
  692. #define _SGIMGUI_COLOR_OTHER 0xFFCCCCCC
  693. #define _SGIMGUI_COLOR_RSRC 0xFF00FFFF
  694. #define _SGIMGUI_COLOR_PASS 0xFFFFFF00
  695. #define _SGIMGUI_COLOR_APPLY 0xFFCCCC00
  696. #define _SGIMGUI_COLOR_DRAW 0xFF00FF00
  697. #define _SGIMGUI_COLOR_ERR 0xFF8888FF
  698. /*--- C => C++ layer ---------------------------------------------------------*/
  699. #if defined(__cplusplus)
  700. #define IMVEC2(x,y) ImVec2(x,y)
  701. #define IMVEC4(x,y,z,w) ImVec4(x,y,z,w)
  702. _SOKOL_PRIVATE void igText(const char* fmt,...) {
  703. va_list args;
  704. va_start(args, fmt);
  705. ImGui::TextV(fmt, args);
  706. va_end(args);
  707. }
  708. _SOKOL_PRIVATE void igSeparator(void) {
  709. return ImGui::Separator();
  710. }
  711. _SOKOL_PRIVATE void igSameLine(void) {
  712. return ImGui::SameLine();
  713. }
  714. _SOKOL_PRIVATE void igPushIDInt(int int_id) {
  715. return ImGui::PushID(int_id);
  716. }
  717. _SOKOL_PRIVATE void igPushID(const char* str_id) {
  718. return ImGui::PushID(str_id);
  719. }
  720. _SOKOL_PRIVATE void igPopID() {
  721. return ImGui::PopID();
  722. }
  723. _SOKOL_PRIVATE bool igSelectableEx(const char* label,bool selected,ImGuiSelectableFlags flags,const ImVec2 size) {
  724. return ImGui::Selectable(label,selected,flags,size);
  725. }
  726. _SOKOL_PRIVATE bool igSmallButton(const char* label) {
  727. return ImGui::SmallButton(label);
  728. }
  729. _SOKOL_PRIVATE bool igBeginChild(const char* str_id,const ImVec2 size,bool border,ImGuiWindowFlags flags) {
  730. return ImGui::BeginChild(str_id,size,border,flags);
  731. }
  732. _SOKOL_PRIVATE void igEndChild() {
  733. return ImGui::EndChild();
  734. }
  735. _SOKOL_PRIVATE void igPushStyleColor(ImGuiCol idx, ImU32 col) {
  736. return ImGui::PushStyleColor(idx,col);
  737. }
  738. _SOKOL_PRIVATE void igPopStyleColor() {
  739. return ImGui::PopStyleColor();
  740. }
  741. _SOKOL_PRIVATE bool igTreeNodeStr(const char* str_id,const char* fmt,...) {
  742. va_list args;
  743. va_start(args, fmt);
  744. bool ret = ImGui::TreeNodeV(str_id,fmt,args);
  745. va_end(args);
  746. return ret;
  747. }
  748. _SOKOL_PRIVATE bool igTreeNode(const char* label) {
  749. return ImGui::TreeNode(label);
  750. }
  751. _SOKOL_PRIVATE void igTreePop() {
  752. return ImGui::TreePop();
  753. }
  754. _SOKOL_PRIVATE bool igIsItemHovered(ImGuiHoveredFlags flags) {
  755. return ImGui::IsItemHovered(flags);
  756. }
  757. _SOKOL_PRIVATE void igSetTooltip(const char* fmt,...) {
  758. va_list args;
  759. va_start(args, fmt);
  760. ImGui::SetTooltipV(fmt,args);
  761. va_end(args);
  762. }
  763. _SOKOL_PRIVATE bool igSliderFloatEx(const char* label,float* v,float v_min,float v_max,const char* format,ImGuiSliderFlags flags) {
  764. return ImGui::SliderFloat(label,v,v_min,v_max,format,flags);
  765. }
  766. _SOKOL_PRIVATE void igSetNextWindowSize(const ImVec2 size,ImGuiCond cond) {
  767. return ImGui::SetNextWindowSize(size,cond);
  768. }
  769. _SOKOL_PRIVATE bool igBegin(const char* name,bool* p_open,ImGuiWindowFlags flags) {
  770. return ImGui::Begin(name,p_open,flags);
  771. }
  772. _SOKOL_PRIVATE void igEnd() {
  773. return ImGui::End();
  774. }
  775. _SOKOL_PRIVATE bool igBeginMenu(const char* label) {
  776. return ImGui::BeginMenu(label);
  777. }
  778. _SOKOL_PRIVATE void igEndMenu(void) {
  779. ImGui::EndMenu();
  780. }
  781. _SOKOL_PRIVATE bool igMenuItemBoolPtr(const char* label, const char* shortcut, bool* p_selected, bool enabled) {
  782. return ImGui::MenuItem(label, shortcut, p_selected, enabled);
  783. }
  784. _SOKOL_PRIVATE bool igBeginTable(const char* str_id, int column, ImGuiTableFlags flags) {
  785. return ImGui::BeginTable(str_id, column, flags);
  786. }
  787. _SOKOL_PRIVATE void igEndTable(void) {
  788. ImGui::EndTable();
  789. }
  790. _SOKOL_PRIVATE void igTableSetupScrollFreeze(int cols, int rows) {
  791. ImGui::TableSetupScrollFreeze(cols, rows);
  792. }
  793. _SOKOL_PRIVATE void igTableSetupColumn(const char* label, ImGuiTableColumnFlags flags) {
  794. ImGui::TableSetupColumn(label, flags);
  795. }
  796. _SOKOL_PRIVATE void igTableHeadersRow(void) {
  797. ImGui::TableHeadersRow();
  798. }
  799. _SOKOL_PRIVATE void igTableNextRow(void) {
  800. ImGui::TableNextRow();
  801. }
  802. _SOKOL_PRIVATE bool igTableSetColumnIndex(int column_n) {
  803. return ImGui::TableSetColumnIndex(column_n);
  804. }
  805. _SOKOL_PRIVATE bool igCheckbox(const char* label, bool* v) {
  806. return ImGui::Checkbox(label, v);
  807. }
  808. #else
  809. #define IMVEC2(x,y) (ImVec2){x,y}
  810. #define IMVEC4(x,y,z,w) (ImVec4){x,y,z,w}
  811. #endif
  812. void _sgimgui_igimage(ImTextureID user_texture_id, const ImVec2 size) {
  813. #if defined(__cplusplus)
  814. ImGui::Image(ImTextureRef(user_texture_id), size);
  815. #else
  816. // FIXME: Dear Bindings is currently missing a constructor wrapper for ImTextureRef
  817. ImTextureRef tex_ref = {0};
  818. tex_ref._TexID = user_texture_id;
  819. igImage(tex_ref, size);
  820. #endif
  821. }
  822. /*--- UTILS ------------------------------------------------------------------*/
  823. _SOKOL_PRIVATE void _sgimgui_clear(void* ptr, size_t size) {
  824. SOKOL_ASSERT(ptr && (size > 0));
  825. memset(ptr, 0, size);
  826. }
  827. _SOKOL_PRIVATE void* _sgimgui_malloc(const sgimgui_allocator_t* allocator, size_t size) {
  828. SOKOL_ASSERT(allocator && (size > 0));
  829. void* ptr;
  830. if (allocator->alloc_fn) {
  831. ptr = allocator->alloc_fn(size, allocator->user_data);
  832. } else {
  833. ptr = malloc(size);
  834. }
  835. SOKOL_ASSERT(ptr);
  836. return ptr;
  837. }
  838. _SOKOL_PRIVATE void* _sgimgui_malloc_clear(const sgimgui_allocator_t* allocator, size_t size) {
  839. void* ptr = _sgimgui_malloc(allocator, size);
  840. _sgimgui_clear(ptr, size);
  841. return ptr;
  842. }
  843. _SOKOL_PRIVATE void _sgimgui_free(const sgimgui_allocator_t* allocator, void* ptr) {
  844. SOKOL_ASSERT(allocator);
  845. if (allocator->free_fn) {
  846. allocator->free_fn(ptr, allocator->user_data);
  847. } else {
  848. free(ptr);
  849. }
  850. }
  851. _SOKOL_PRIVATE void* _sgimgui_realloc(const sgimgui_allocator_t* allocator, void* old_ptr, size_t old_size, size_t new_size) {
  852. SOKOL_ASSERT(allocator && (new_size > 0) && (new_size > old_size));
  853. void* new_ptr = _sgimgui_malloc(allocator, new_size);
  854. if (old_ptr) {
  855. if (old_size > 0) {
  856. memcpy(new_ptr, old_ptr, old_size);
  857. }
  858. _sgimgui_free(allocator, old_ptr);
  859. }
  860. return new_ptr;
  861. }
  862. _SOKOL_PRIVATE int _sgimgui_slot_index(uint32_t id) {
  863. int slot_index = (int) (id & _SGIMGUI_SLOT_MASK);
  864. SOKOL_ASSERT(0 != slot_index);
  865. return slot_index;
  866. }
  867. _SOKOL_PRIVATE uint32_t _sgimgui_align_u32(uint32_t val, uint32_t align) {
  868. SOKOL_ASSERT((align > 0) && ((align & (align - 1)) == 0));
  869. return (val + (align - 1)) & ~(align - 1);
  870. }
  871. _SOKOL_PRIVATE uint32_t _sgimgui_std140_uniform_alignment(sg_uniform_type type, int array_count) {
  872. SOKOL_ASSERT(array_count > 0);
  873. if (array_count == 1) {
  874. switch (type) {
  875. case SG_UNIFORMTYPE_FLOAT:
  876. case SG_UNIFORMTYPE_INT:
  877. return 4;
  878. case SG_UNIFORMTYPE_FLOAT2:
  879. case SG_UNIFORMTYPE_INT2:
  880. return 8;
  881. case SG_UNIFORMTYPE_FLOAT3:
  882. case SG_UNIFORMTYPE_FLOAT4:
  883. case SG_UNIFORMTYPE_INT3:
  884. case SG_UNIFORMTYPE_INT4:
  885. return 16;
  886. case SG_UNIFORMTYPE_MAT4:
  887. return 16;
  888. default:
  889. SOKOL_UNREACHABLE;
  890. return 1;
  891. }
  892. } else {
  893. return 16;
  894. }
  895. }
  896. _SOKOL_PRIVATE uint32_t _sgimgui_std140_uniform_size(sg_uniform_type type, int array_count) {
  897. SOKOL_ASSERT(array_count > 0);
  898. if (array_count == 1) {
  899. switch (type) {
  900. case SG_UNIFORMTYPE_FLOAT:
  901. case SG_UNIFORMTYPE_INT:
  902. return 4;
  903. case SG_UNIFORMTYPE_FLOAT2:
  904. case SG_UNIFORMTYPE_INT2:
  905. return 8;
  906. case SG_UNIFORMTYPE_FLOAT3:
  907. case SG_UNIFORMTYPE_INT3:
  908. return 12;
  909. case SG_UNIFORMTYPE_FLOAT4:
  910. case SG_UNIFORMTYPE_INT4:
  911. return 16;
  912. case SG_UNIFORMTYPE_MAT4:
  913. return 64;
  914. default:
  915. SOKOL_UNREACHABLE;
  916. return 0;
  917. }
  918. } else {
  919. switch (type) {
  920. case SG_UNIFORMTYPE_FLOAT:
  921. case SG_UNIFORMTYPE_FLOAT2:
  922. case SG_UNIFORMTYPE_FLOAT3:
  923. case SG_UNIFORMTYPE_FLOAT4:
  924. case SG_UNIFORMTYPE_INT:
  925. case SG_UNIFORMTYPE_INT2:
  926. case SG_UNIFORMTYPE_INT3:
  927. case SG_UNIFORMTYPE_INT4:
  928. return 16 * (uint32_t)array_count;
  929. case SG_UNIFORMTYPE_MAT4:
  930. return 64 * (uint32_t)array_count;
  931. default:
  932. SOKOL_UNREACHABLE;
  933. return 0;
  934. }
  935. }
  936. }
  937. _SOKOL_PRIVATE void _sgimgui_strcpy(sgimgui_str_t* dst, const char* src) {
  938. SOKOL_ASSERT(dst);
  939. if (src) {
  940. #if defined(_MSC_VER)
  941. strncpy_s(dst->buf, sgimgui_STRBUF_LEN, src, (sgimgui_STRBUF_LEN-1));
  942. #else
  943. strncpy(dst->buf, src, sgimgui_STRBUF_LEN);
  944. #endif
  945. dst->buf[sgimgui_STRBUF_LEN-1] = 0;
  946. } else {
  947. _sgimgui_clear(dst->buf, sgimgui_STRBUF_LEN);
  948. }
  949. }
  950. _SOKOL_PRIVATE sgimgui_str_t _sgimgui_make_str(const char* str) {
  951. sgimgui_str_t res;
  952. _sgimgui_strcpy(&res, str);
  953. return res;
  954. }
  955. _SOKOL_PRIVATE const char* _sgimgui_str_dup(const sgimgui_allocator_t* allocator, const char* src) {
  956. SOKOL_ASSERT(allocator && src);
  957. size_t len = strlen(src) + 1;
  958. char* dst = (char*) _sgimgui_malloc(allocator, len);
  959. memcpy(dst, src, len);
  960. return (const char*) dst;
  961. }
  962. _SOKOL_PRIVATE const void* _sgimgui_bin_dup(const sgimgui_allocator_t* allocator, const void* src, size_t num_bytes) {
  963. SOKOL_ASSERT(allocator && src && (num_bytes > 0));
  964. void* dst = _sgimgui_malloc(allocator, num_bytes);
  965. memcpy(dst, src, num_bytes);
  966. return (const void*) dst;
  967. }
  968. _SOKOL_PRIVATE void _sgimgui_snprintf(sgimgui_str_t* dst, const char* fmt, ...) {
  969. SOKOL_ASSERT(dst);
  970. va_list args;
  971. va_start(args, fmt);
  972. vsnprintf(dst->buf, sizeof(dst->buf), fmt, args);
  973. dst->buf[sizeof(dst->buf)-1] = 0;
  974. va_end(args);
  975. }
  976. /*--- STRING CONVERSION ------------------------------------------------------*/
  977. _SOKOL_PRIVATE const char* _sgimgui_resourcestate_string(sg_resource_state s) {
  978. switch (s) {
  979. case SG_RESOURCESTATE_INITIAL: return "SG_RESOURCESTATE_INITIAL";
  980. case SG_RESOURCESTATE_ALLOC: return "SG_RESOURCESTATE_ALLOC";
  981. case SG_RESOURCESTATE_VALID: return "SG_RESOURCESTATE_VALID";
  982. case SG_RESOURCESTATE_FAILED: return "SG_RESOURCESTATE_FAILED";
  983. default: return "SG_RESOURCESTATE_INVALID";
  984. }
  985. }
  986. _SOKOL_PRIVATE void _sgimgui_draw_resource_slot(const sg_slot_info* slot) {
  987. igText("ResId: %08X", slot->res_id);
  988. igText("State: %s", _sgimgui_resourcestate_string(slot->state));
  989. igText("Uninit Count: %d", slot->uninit_count);
  990. }
  991. _SOKOL_PRIVATE const char* _sgimgui_backend_string(sg_backend b) {
  992. switch (b) {
  993. case SG_BACKEND_GLCORE: return "SG_BACKEND_GLCORE";
  994. case SG_BACKEND_GLES3: return "SG_BACKEND_GLES3";
  995. case SG_BACKEND_D3D11: return "SG_BACKEND_D3D11";
  996. case SG_BACKEND_METAL_IOS: return "SG_BACKEND_METAL_IOS";
  997. case SG_BACKEND_METAL_MACOS: return "SG_BACKEND_METAL_MACOS";
  998. case SG_BACKEND_METAL_SIMULATOR: return "SG_BACKEND_METAL_SIMULATOR";
  999. case SG_BACKEND_WGPU: return "SG_BACKEND_WGPU";
  1000. case SG_BACKEND_DUMMY: return "SG_BACKEND_DUMMY";
  1001. default: return "???";
  1002. }
  1003. }
  1004. _SOKOL_PRIVATE const char* _sgimgui_imagetype_string(sg_image_type t) {
  1005. switch (t) {
  1006. case SG_IMAGETYPE_2D: return "SG_IMAGETYPE_2D";
  1007. case SG_IMAGETYPE_CUBE: return "SG_IMAGETYPE_CUBE";
  1008. case SG_IMAGETYPE_3D: return "SG_IMAGETYPE_3D";
  1009. case SG_IMAGETYPE_ARRAY: return "SG_IMAGETYPE_ARRAY";
  1010. default: return "???";
  1011. }
  1012. }
  1013. _SOKOL_PRIVATE const char* _sgimgui_imagesampletype_string(sg_image_sample_type t) {
  1014. switch (t) {
  1015. case SG_IMAGESAMPLETYPE_FLOAT: return "SG_IMAGESAMPLETYPE_FLOAT";
  1016. case SG_IMAGESAMPLETYPE_DEPTH: return "SG_IMAGESAMPLETYPE_DEPTH";
  1017. case SG_IMAGESAMPLETYPE_SINT: return "SG_IMAGESAMPLETYPE_SINT";
  1018. case SG_IMAGESAMPLETYPE_UINT: return "SG_IMAGESAMPLETYPE_UINT";
  1019. case SG_IMAGESAMPLETYPE_UNFILTERABLE_FLOAT: return "SG_IMAGESAMPLETYPE_UNFILTERABLE_FLOAT";
  1020. default: return "???";
  1021. }
  1022. }
  1023. _SOKOL_PRIVATE const char* _sgimgui_samplertype_string(sg_sampler_type t) {
  1024. switch (t) {
  1025. case SG_SAMPLERTYPE_FILTERING: return "SG_SAMPLERTYPE_FILTERING";
  1026. case SG_SAMPLERTYPE_COMPARISON: return "SG_SAMPLERTYPE_COMPARISON";
  1027. case SG_SAMPLERTYPE_NONFILTERING: return "SG_SAMPLERTYPE_NONFILTERING";
  1028. default: return "???";
  1029. }
  1030. }
  1031. _SOKOL_PRIVATE const char* _sgimgui_uniformlayout_string(sg_uniform_layout l) {
  1032. switch (l) {
  1033. case SG_UNIFORMLAYOUT_NATIVE: return "SG_UNIFORMLAYOUT_NATIVE";
  1034. case SG_UNIFORMLAYOUT_STD140: return "SG_UNIFORMLAYOUT_STD140";
  1035. default: return "???";
  1036. }
  1037. }
  1038. _SOKOL_PRIVATE const char* _sgimgui_pixelformat_string(sg_pixel_format fmt) {
  1039. switch (fmt) {
  1040. case SG_PIXELFORMAT_NONE: return "SG_PIXELFORMAT_NONE";
  1041. case SG_PIXELFORMAT_R8: return "SG_PIXELFORMAT_R8";
  1042. case SG_PIXELFORMAT_R8SN: return "SG_PIXELFORMAT_R8SN";
  1043. case SG_PIXELFORMAT_R8UI: return "SG_PIXELFORMAT_R8UI";
  1044. case SG_PIXELFORMAT_R8SI: return "SG_PIXELFORMAT_R8SI";
  1045. case SG_PIXELFORMAT_R16: return "SG_PIXELFORMAT_R16";
  1046. case SG_PIXELFORMAT_R16SN: return "SG_PIXELFORMAT_R16SN";
  1047. case SG_PIXELFORMAT_R16UI: return "SG_PIXELFORMAT_R16UI";
  1048. case SG_PIXELFORMAT_R16SI: return "SG_PIXELFORMAT_R16SI";
  1049. case SG_PIXELFORMAT_R16F: return "SG_PIXELFORMAT_R16F";
  1050. case SG_PIXELFORMAT_RG8: return "SG_PIXELFORMAT_RG8";
  1051. case SG_PIXELFORMAT_RG8SN: return "SG_PIXELFORMAT_RG8SN";
  1052. case SG_PIXELFORMAT_RG8UI: return "SG_PIXELFORMAT_RG8UI";
  1053. case SG_PIXELFORMAT_RG8SI: return "SG_PIXELFORMAT_RG8SI";
  1054. case SG_PIXELFORMAT_R32UI: return "SG_PIXELFORMAT_R32UI";
  1055. case SG_PIXELFORMAT_R32SI: return "SG_PIXELFORMAT_R32SI";
  1056. case SG_PIXELFORMAT_R32F: return "SG_PIXELFORMAT_R32F";
  1057. case SG_PIXELFORMAT_RG16: return "SG_PIXELFORMAT_RG16";
  1058. case SG_PIXELFORMAT_RG16SN: return "SG_PIXELFORMAT_RG16SN";
  1059. case SG_PIXELFORMAT_RG16UI: return "SG_PIXELFORMAT_RG16UI";
  1060. case SG_PIXELFORMAT_RG16SI: return "SG_PIXELFORMAT_RG16SI";
  1061. case SG_PIXELFORMAT_RG16F: return "SG_PIXELFORMAT_RG16F";
  1062. case SG_PIXELFORMAT_RGBA8: return "SG_PIXELFORMAT_RGBA8";
  1063. case SG_PIXELFORMAT_SRGB8A8: return "SG_PIXELFORMAT_SRGB8A8";
  1064. case SG_PIXELFORMAT_RGBA8SN: return "SG_PIXELFORMAT_RGBA8SN";
  1065. case SG_PIXELFORMAT_RGBA8UI: return "SG_PIXELFORMAT_RGBA8UI";
  1066. case SG_PIXELFORMAT_RGBA8SI: return "SG_PIXELFORMAT_RGBA8SI";
  1067. case SG_PIXELFORMAT_BGRA8: return "SG_PIXELFORMAT_BGRA8";
  1068. case SG_PIXELFORMAT_RGB10A2: return "SG_PIXELFORMAT_RGB10A2";
  1069. case SG_PIXELFORMAT_RG11B10F: return "SG_PIXELFORMAT_RG11B10F";
  1070. case SG_PIXELFORMAT_RG32UI: return "SG_PIXELFORMAT_RG32UI";
  1071. case SG_PIXELFORMAT_RG32SI: return "SG_PIXELFORMAT_RG32SI";
  1072. case SG_PIXELFORMAT_RG32F: return "SG_PIXELFORMAT_RG32F";
  1073. case SG_PIXELFORMAT_RGBA16: return "SG_PIXELFORMAT_RGBA16";
  1074. case SG_PIXELFORMAT_RGBA16SN: return "SG_PIXELFORMAT_RGBA16SN";
  1075. case SG_PIXELFORMAT_RGBA16UI: return "SG_PIXELFORMAT_RGBA16UI";
  1076. case SG_PIXELFORMAT_RGBA16SI: return "SG_PIXELFORMAT_RGBA16SI";
  1077. case SG_PIXELFORMAT_RGBA16F: return "SG_PIXELFORMAT_RGBA16F";
  1078. case SG_PIXELFORMAT_RGBA32UI: return "SG_PIXELFORMAT_RGBA32UI";
  1079. case SG_PIXELFORMAT_RGBA32SI: return "SG_PIXELFORMAT_RGBA32SI";
  1080. case SG_PIXELFORMAT_RGBA32F: return "SG_PIXELFORMAT_RGBA32F";
  1081. case SG_PIXELFORMAT_DEPTH: return "SG_PIXELFORMAT_DEPTH";
  1082. case SG_PIXELFORMAT_DEPTH_STENCIL: return "SG_PIXELFORMAT_DEPTH_STENCIL";
  1083. case SG_PIXELFORMAT_BC1_RGBA: return "SG_PIXELFORMAT_BC1_RGBA";
  1084. case SG_PIXELFORMAT_BC2_RGBA: return "SG_PIXELFORMAT_BC2_RGBA";
  1085. case SG_PIXELFORMAT_BC3_RGBA: return "SG_PIXELFORMAT_BC3_RGBA";
  1086. case SG_PIXELFORMAT_BC4_R: return "SG_PIXELFORMAT_BC4_R";
  1087. case SG_PIXELFORMAT_BC4_RSN: return "SG_PIXELFORMAT_BC4_RSN";
  1088. case SG_PIXELFORMAT_BC5_RG: return "SG_PIXELFORMAT_BC5_RG";
  1089. case SG_PIXELFORMAT_BC5_RGSN: return "SG_PIXELFORMAT_BC5_RGSN";
  1090. case SG_PIXELFORMAT_BC6H_RGBF: return "SG_PIXELFORMAT_BC6H_RGBF";
  1091. case SG_PIXELFORMAT_BC6H_RGBUF: return "SG_PIXELFORMAT_BC6H_RGBUF";
  1092. case SG_PIXELFORMAT_BC7_RGBA: return "SG_PIXELFORMAT_BC7_RGBA";
  1093. case SG_PIXELFORMAT_ETC2_RGB8: return "SG_PIXELFORMAT_ETC2_RGB8";
  1094. case SG_PIXELFORMAT_ETC2_RGB8A1: return "SG_PIXELFORMAT_ETC2_RGB8A1";
  1095. case SG_PIXELFORMAT_ETC2_RGBA8: return "SG_PIXELFORMAT_ETC2_RGBA8";
  1096. case SG_PIXELFORMAT_EAC_R11: return "SG_PIXELFORMAT_EAC_R11";
  1097. case SG_PIXELFORMAT_EAC_R11SN: return "SG_PIXELFORMAT_EAC_R11SN";
  1098. case SG_PIXELFORMAT_EAC_RG11: return "SG_PIXELFORMAT_EAC_RG11";
  1099. case SG_PIXELFORMAT_EAC_RG11SN: return "SG_PIXELFORMAT_EAC_RG11SN";
  1100. case SG_PIXELFORMAT_RGB9E5: return "SG_PIXELFORMAT_RGB9E5";
  1101. case SG_PIXELFORMAT_BC3_SRGBA: return "SG_PIXELFORMAT_BC3_SRGBA";
  1102. case SG_PIXELFORMAT_BC7_SRGBA: return "SG_PIXELFORMAT_BC7_SRGBA";
  1103. case SG_PIXELFORMAT_ETC2_SRGB8: return "SG_PIXELFORMAT_ETC2_SRGB8";
  1104. case SG_PIXELFORMAT_ETC2_SRGB8A8: return "SG_PIXELFORMAT_ETC2_SRGB8A8";
  1105. case SG_PIXELFORMAT_ASTC_4x4_RGBA: return "SG_PIXELFORMAT_ASTC_4x4_RGBA";
  1106. case SG_PIXELFORMAT_ASTC_4x4_SRGBA: return "SG_PIXELFORMAT_ASTC_4x4_SRGBA";
  1107. default: return "???";
  1108. }
  1109. }
  1110. _SOKOL_PRIVATE const char* _sgimgui_filter_string(sg_filter f) {
  1111. switch (f) {
  1112. case SG_FILTER_NEAREST: return "SG_FILTER_NEAREST";
  1113. case SG_FILTER_LINEAR: return "SG_FILTER_LINEAR";
  1114. default: return "???";
  1115. }
  1116. }
  1117. _SOKOL_PRIVATE const char* _sgimgui_wrap_string(sg_wrap w) {
  1118. switch (w) {
  1119. case SG_WRAP_REPEAT: return "SG_WRAP_REPEAT";
  1120. case SG_WRAP_CLAMP_TO_EDGE: return "SG_WRAP_CLAMP_TO_EDGE";
  1121. case SG_WRAP_CLAMP_TO_BORDER: return "SG_WRAP_CLAMP_TO_BORDER";
  1122. case SG_WRAP_MIRRORED_REPEAT: return "SG_WRAP_MIRRORED_REPEAT";
  1123. default: return "???";
  1124. }
  1125. }
  1126. _SOKOL_PRIVATE const char* _sgimgui_bordercolor_string(sg_border_color bc) {
  1127. switch (bc) {
  1128. case SG_BORDERCOLOR_TRANSPARENT_BLACK: return "SG_BORDERCOLOR_TRANSPARENT_BLACK";
  1129. case SG_BORDERCOLOR_OPAQUE_BLACK: return "SG_BORDERCOLOR_OPAQUE_BLACK";
  1130. case SG_BORDERCOLOR_OPAQUE_WHITE: return "SG_BORDERCOLOR_OPAQUE_WHITE";
  1131. default: return "???";
  1132. }
  1133. }
  1134. _SOKOL_PRIVATE const char* _sgimgui_uniformtype_string(sg_uniform_type t) {
  1135. switch (t) {
  1136. case SG_UNIFORMTYPE_FLOAT: return "SG_UNIFORMTYPE_FLOAT";
  1137. case SG_UNIFORMTYPE_FLOAT2: return "SG_UNIFORMTYPE_FLOAT2";
  1138. case SG_UNIFORMTYPE_FLOAT3: return "SG_UNIFORMTYPE_FLOAT3";
  1139. case SG_UNIFORMTYPE_FLOAT4: return "SG_UNIFORMTYPE_FLOAT4";
  1140. case SG_UNIFORMTYPE_INT: return "SG_UNIFORMTYPE_INT";
  1141. case SG_UNIFORMTYPE_INT2: return "SG_UNIFORMTYPE_INT2";
  1142. case SG_UNIFORMTYPE_INT3: return "SG_UNIFORMTYPE_INT3";
  1143. case SG_UNIFORMTYPE_INT4: return "SG_UNIFORMTYPE_INT4";
  1144. case SG_UNIFORMTYPE_MAT4: return "SG_UNIFORMTYPE_MAT4";
  1145. default: return "???";
  1146. }
  1147. }
  1148. _SOKOL_PRIVATE const char* _sgimgui_vertexstep_string(sg_vertex_step s) {
  1149. switch (s) {
  1150. case SG_VERTEXSTEP_PER_VERTEX: return "SG_VERTEXSTEP_PER_VERTEX";
  1151. case SG_VERTEXSTEP_PER_INSTANCE: return "SG_VERTEXSTEP_PER_INSTANCE";
  1152. default: return "???";
  1153. }
  1154. }
  1155. _SOKOL_PRIVATE const char* _sgimgui_vertexformat_string(sg_vertex_format f) {
  1156. switch (f) {
  1157. case SG_VERTEXFORMAT_FLOAT: return "SG_VERTEXFORMAT_FLOAT";
  1158. case SG_VERTEXFORMAT_FLOAT2: return "SG_VERTEXFORMAT_FLOAT2";
  1159. case SG_VERTEXFORMAT_FLOAT3: return "SG_VERTEXFORMAT_FLOAT3";
  1160. case SG_VERTEXFORMAT_FLOAT4: return "SG_VERTEXFORMAT_FLOAT4";
  1161. case SG_VERTEXFORMAT_INT: return "SG_VERTEXFORMAT_INT";
  1162. case SG_VERTEXFORMAT_INT2: return "SG_VERTEXFORMAT_INT2";
  1163. case SG_VERTEXFORMAT_INT3: return "SG_VERTEXFORMAT_INT3";
  1164. case SG_VERTEXFORMAT_INT4: return "SG_VERTEXFORMAT_INT4";
  1165. case SG_VERTEXFORMAT_UINT: return "SG_VERTEXFORMAT_UINT";
  1166. case SG_VERTEXFORMAT_UINT2: return "SG_VERTEXFORMAT_UINT2";
  1167. case SG_VERTEXFORMAT_UINT3: return "SG_VERTEXFORMAT_UINT3";
  1168. case SG_VERTEXFORMAT_UINT4: return "SG_VERTEXFORMAT_UINT4";
  1169. case SG_VERTEXFORMAT_BYTE4: return "SG_VERTEXFORMAT_BYTE4";
  1170. case SG_VERTEXFORMAT_BYTE4N: return "SG_VERTEXFORMAT_BYTE4N";
  1171. case SG_VERTEXFORMAT_UBYTE4: return "SG_VERTEXFORMAT_UBYTE4";
  1172. case SG_VERTEXFORMAT_UBYTE4N: return "SG_VERTEXFORMAT_UBYTE4N";
  1173. case SG_VERTEXFORMAT_SHORT2: return "SG_VERTEXFORMAT_SHORT2";
  1174. case SG_VERTEXFORMAT_SHORT2N: return "SG_VERTEXFORMAT_SHORT2N";
  1175. case SG_VERTEXFORMAT_USHORT2: return "SG_VERTEXFORMAT_USHORT2";
  1176. case SG_VERTEXFORMAT_USHORT2N: return "SG_VERTEXFORMAT_USHORT2N";
  1177. case SG_VERTEXFORMAT_SHORT4: return "SG_VERTEXFORMAT_SHORT4";
  1178. case SG_VERTEXFORMAT_SHORT4N: return "SG_VERTEXFORMAT_SHORT4N";
  1179. case SG_VERTEXFORMAT_USHORT4: return "SG_VERTEXFORMAT_USHORT4";
  1180. case SG_VERTEXFORMAT_USHORT4N: return "SG_VERTEXFORMAT_USHORT4N";
  1181. case SG_VERTEXFORMAT_UINT10_N2: return "SG_VERTEXFORMAT_UINT10_N2";
  1182. case SG_VERTEXFORMAT_HALF2: return "SG_VERTEXFORMAT_HALF2";
  1183. case SG_VERTEXFORMAT_HALF4: return "SG_VERTEXFORMAT_HALF4";
  1184. default: return "???";
  1185. }
  1186. }
  1187. _SOKOL_PRIVATE const char* _sgimgui_primitivetype_string(sg_primitive_type t) {
  1188. switch (t) {
  1189. case SG_PRIMITIVETYPE_POINTS: return "SG_PRIMITIVETYPE_POINTS";
  1190. case SG_PRIMITIVETYPE_LINES: return "SG_PRIMITIVETYPE_LINES";
  1191. case SG_PRIMITIVETYPE_LINE_STRIP: return "SG_PRIMITIVETYPE_LINE_STRIP";
  1192. case SG_PRIMITIVETYPE_TRIANGLES: return "SG_PRIMITIVETYPE_TRIANGLES";
  1193. case SG_PRIMITIVETYPE_TRIANGLE_STRIP: return "SG_PRIMITIVETYPE_TRIANGLE_STRIP";
  1194. default: return "???";
  1195. }
  1196. }
  1197. _SOKOL_PRIVATE const char* _sgimgui_indextype_string(sg_index_type t) {
  1198. switch (t) {
  1199. case SG_INDEXTYPE_NONE: return "SG_INDEXTYPE_NONE";
  1200. case SG_INDEXTYPE_UINT16: return "SG_INDEXTYPE_UINT16";
  1201. case SG_INDEXTYPE_UINT32: return "SG_INDEXTYPE_UINT32";
  1202. default: return "???";
  1203. }
  1204. }
  1205. _SOKOL_PRIVATE const char* _sgimgui_stencilop_string(sg_stencil_op op) {
  1206. switch (op) {
  1207. case SG_STENCILOP_KEEP: return "SG_STENCILOP_KEEP";
  1208. case SG_STENCILOP_ZERO: return "SG_STENCILOP_ZERO";
  1209. case SG_STENCILOP_REPLACE: return "SG_STENCILOP_REPLACE";
  1210. case SG_STENCILOP_INCR_CLAMP: return "SG_STENCILOP_INCR_CLAMP";
  1211. case SG_STENCILOP_DECR_CLAMP: return "SG_STENCILOP_DECR_CLAMP";
  1212. case SG_STENCILOP_INVERT: return "SG_STENCILOP_INVERT";
  1213. case SG_STENCILOP_INCR_WRAP: return "SG_STENCILOP_INCR_WRAP";
  1214. case SG_STENCILOP_DECR_WRAP: return "SG_STENCILOP_DECR_WRAP";
  1215. default: return "???";
  1216. }
  1217. }
  1218. _SOKOL_PRIVATE const char* _sgimgui_comparefunc_string(sg_compare_func f) {
  1219. switch (f) {
  1220. case SG_COMPAREFUNC_NEVER: return "SG_COMPAREFUNC_NEVER";
  1221. case SG_COMPAREFUNC_LESS: return "SG_COMPAREFUNC_LESS";
  1222. case SG_COMPAREFUNC_EQUAL: return "SG_COMPAREFUNC_EQUAL";
  1223. case SG_COMPAREFUNC_LESS_EQUAL: return "SG_COMPAREFUNC_LESS_EQUAL";
  1224. case SG_COMPAREFUNC_GREATER: return "SG_COMPAREFUNC_GREATER";
  1225. case SG_COMPAREFUNC_NOT_EQUAL: return "SG_COMPAREFUNC_NOT_EQUAL";
  1226. case SG_COMPAREFUNC_GREATER_EQUAL: return "SG_COMPAREFUNC_GREATER_EQUAL";
  1227. case SG_COMPAREFUNC_ALWAYS: return "SG_COMPAREFUNC_ALWAYS";
  1228. default: return "???";
  1229. }
  1230. }
  1231. _SOKOL_PRIVATE const char* _sgimgui_blendfactor_string(sg_blend_factor f) {
  1232. switch (f) {
  1233. case SG_BLENDFACTOR_ZERO: return "SG_BLENDFACTOR_ZERO";
  1234. case SG_BLENDFACTOR_ONE: return "SG_BLENDFACTOR_ONE";
  1235. case SG_BLENDFACTOR_SRC_COLOR: return "SG_BLENDFACTOR_SRC_COLOR";
  1236. case SG_BLENDFACTOR_ONE_MINUS_SRC_COLOR: return "SG_BLENDFACTOR_ONE_MINUS_SRC_COLOR";
  1237. case SG_BLENDFACTOR_SRC_ALPHA: return "SG_BLENDFACTOR_SRC_ALPHA";
  1238. case SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA: return "SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA";
  1239. case SG_BLENDFACTOR_DST_COLOR: return "SG_BLENDFACTOR_DST_COLOR";
  1240. case SG_BLENDFACTOR_ONE_MINUS_DST_COLOR: return "SG_BLENDFACTOR_ONE_MINUS_DST_COLOR";
  1241. case SG_BLENDFACTOR_DST_ALPHA: return "SG_BLENDFACTOR_DST_ALPHA";
  1242. case SG_BLENDFACTOR_ONE_MINUS_DST_ALPHA: return "SG_BLENDFACTOR_ONE_MINUS_DST_ALPHA";
  1243. case SG_BLENDFACTOR_SRC_ALPHA_SATURATED: return "SG_BLENDFACTOR_SRC_ALPHA_SATURATED";
  1244. case SG_BLENDFACTOR_BLEND_COLOR: return "SG_BLENDFACTOR_BLEND_COLOR";
  1245. case SG_BLENDFACTOR_ONE_MINUS_BLEND_COLOR: return "SG_BLENDFACTOR_ONE_MINUS_BLEND_COLOR";
  1246. case SG_BLENDFACTOR_BLEND_ALPHA: return "SG_BLENDFACTOR_BLEND_ALPHA";
  1247. case SG_BLENDFACTOR_ONE_MINUS_BLEND_ALPHA: return "SG_BLENDFACTOR_ONE_MINUS_BLEND_ALPHA";
  1248. default: return "???";
  1249. }
  1250. }
  1251. _SOKOL_PRIVATE const char* _sgimgui_blendop_string(sg_blend_op op) {
  1252. switch (op) {
  1253. case SG_BLENDOP_ADD: return "SG_BLENDOP_ADD";
  1254. case SG_BLENDOP_SUBTRACT: return "SG_BLENDOP_SUBTRACT";
  1255. case SG_BLENDOP_REVERSE_SUBTRACT: return "SG_BLENDOP_REVERSE_SUBTRACT";
  1256. case SG_BLENDOP_MIN: return "SG_BLENDOP_MIN";
  1257. case SG_BLENDOP_MAX: return "SG_BLENDOP_MAX";
  1258. default: return "???";
  1259. }
  1260. }
  1261. _SOKOL_PRIVATE const char* _sgimgui_colormask_string(sg_color_mask m) {
  1262. static const char* str[] = {
  1263. "NONE",
  1264. "R",
  1265. "G",
  1266. "RG",
  1267. "B",
  1268. "RB",
  1269. "GB",
  1270. "RGB",
  1271. "A",
  1272. "RA",
  1273. "GA",
  1274. "RGA",
  1275. "BA",
  1276. "RBA",
  1277. "GBA",
  1278. "RGBA",
  1279. };
  1280. return str[m & 0xF];
  1281. }
  1282. _SOKOL_PRIVATE const char* _sgimgui_cullmode_string(sg_cull_mode cm) {
  1283. switch (cm) {
  1284. case SG_CULLMODE_NONE: return "SG_CULLMODE_NONE";
  1285. case SG_CULLMODE_FRONT: return "SG_CULLMODE_FRONT";
  1286. case SG_CULLMODE_BACK: return "SG_CULLMODE_BACK";
  1287. default: return "???";
  1288. }
  1289. }
  1290. _SOKOL_PRIVATE const char* _sgimgui_facewinding_string(sg_face_winding fw) {
  1291. switch (fw) {
  1292. case SG_FACEWINDING_CCW: return "SG_FACEWINDING_CCW";
  1293. case SG_FACEWINDING_CW: return "SG_FACEWINDING_CW";
  1294. default: return "???";
  1295. }
  1296. }
  1297. _SOKOL_PRIVATE const char* _sgimgui_shaderstage_string(sg_shader_stage stage) {
  1298. switch (stage) {
  1299. case SG_SHADERSTAGE_VERTEX: return "SG_SHADERSTAGE_VERTEX";
  1300. case SG_SHADERSTAGE_FRAGMENT: return "SG_SHADERSTAGE_FRAGMENT";
  1301. case SG_SHADERSTAGE_COMPUTE: return "SG_SHADERSTAGE_COMPUTE";
  1302. default: return "???";
  1303. }
  1304. }
  1305. _SOKOL_PRIVATE const char* _sgimgui_shaderattrbasetype_string(sg_shader_attr_base_type b) {
  1306. switch (b) {
  1307. case SG_SHADERATTRBASETYPE_UNDEFINED: return "SG_SHADERATTRBASETYPE_UNDEFINED";
  1308. case SG_SHADERATTRBASETYPE_FLOAT: return "SG_SHADERATTRBASETYPE_FLOAT";
  1309. case SG_SHADERATTRBASETYPE_SINT: return "SG_SHADERATTRBASETYPE_SINT";
  1310. case SG_SHADERATTRBASETYPE_UINT: return "SG_SHADERATTRBASETYPE_UINT";
  1311. default: return "???";
  1312. }
  1313. }
  1314. _SOKOL_PRIVATE const char* _sgimgui_bool_string(bool b) {
  1315. return b ? "true" : "false";
  1316. }
  1317. _SOKOL_PRIVATE const char* _sgimgui_color_string(sgimgui_str_t* dst_str, sg_color color) {
  1318. _sgimgui_snprintf(dst_str, "%.3f %.3f %.3f %.3f", color.r, color.g, color.b, color.a);
  1319. return dst_str->buf;
  1320. }
  1321. _SOKOL_PRIVATE sgimgui_str_t _sgimgui_res_id_string(uint32_t res_id, const char* label) {
  1322. SOKOL_ASSERT(label);
  1323. sgimgui_str_t res;
  1324. if (label[0]) {
  1325. _sgimgui_snprintf(&res, "'%s'", label);
  1326. } else {
  1327. _sgimgui_snprintf(&res, "0x%08X", res_id);
  1328. }
  1329. return res;
  1330. }
  1331. _SOKOL_PRIVATE sgimgui_str_t _sgimgui_buffer_id_string(sgimgui_t* ctx, sg_buffer buf_id) {
  1332. if (buf_id.id != SG_INVALID_ID) {
  1333. const sgimgui_buffer_t* buf_ui = &ctx->buffer_window.slots[_sgimgui_slot_index(buf_id.id)];
  1334. return _sgimgui_res_id_string(buf_id.id, buf_ui->label.buf);
  1335. } else {
  1336. return _sgimgui_make_str("<invalid>");
  1337. }
  1338. }
  1339. _SOKOL_PRIVATE sgimgui_str_t _sgimgui_image_id_string(sgimgui_t* ctx, sg_image img_id) {
  1340. if (img_id.id != SG_INVALID_ID) {
  1341. const sgimgui_image_t* img_ui = &ctx->image_window.slots[_sgimgui_slot_index(img_id.id)];
  1342. return _sgimgui_res_id_string(img_id.id, img_ui->label.buf);
  1343. } else {
  1344. return _sgimgui_make_str("<invalid>");
  1345. }
  1346. }
  1347. _SOKOL_PRIVATE sgimgui_str_t _sgimgui_sampler_id_string(sgimgui_t* ctx, sg_sampler smp_id) {
  1348. if (smp_id.id != SG_INVALID_ID) {
  1349. const sgimgui_sampler_t* smp_ui = &ctx->sampler_window.slots[_sgimgui_slot_index(smp_id.id)];
  1350. return _sgimgui_res_id_string(smp_id.id, smp_ui->label.buf);
  1351. } else {
  1352. return _sgimgui_make_str("<invalid>");
  1353. }
  1354. }
  1355. _SOKOL_PRIVATE sgimgui_str_t _sgimgui_shader_id_string(sgimgui_t* ctx, sg_shader shd_id) {
  1356. if (shd_id.id != SG_INVALID_ID) {
  1357. const sgimgui_shader_t* shd_ui = &ctx->shader_window.slots[_sgimgui_slot_index(shd_id.id)];
  1358. return _sgimgui_res_id_string(shd_id.id, shd_ui->label.buf);
  1359. } else {
  1360. return _sgimgui_make_str("<invalid>");
  1361. }
  1362. }
  1363. _SOKOL_PRIVATE sgimgui_str_t _sgimgui_pipeline_id_string(sgimgui_t* ctx, sg_pipeline pip_id) {
  1364. if (pip_id.id != SG_INVALID_ID) {
  1365. const sgimgui_pipeline_t* pip_ui = &ctx->pipeline_window.slots[_sgimgui_slot_index(pip_id.id)];
  1366. return _sgimgui_res_id_string(pip_id.id, pip_ui->label.buf);
  1367. } else {
  1368. return _sgimgui_make_str("<invalid>");
  1369. }
  1370. }
  1371. _SOKOL_PRIVATE sgimgui_str_t _sgimgui_attachments_id_string(sgimgui_t* ctx, sg_attachments atts_id) {
  1372. if (atts_id.id != SG_INVALID_ID) {
  1373. const sgimgui_attachments_t* atts_ui = &ctx->attachments_window.slots[_sgimgui_slot_index(atts_id.id)];
  1374. return _sgimgui_res_id_string(atts_id.id, atts_ui->label.buf);
  1375. } else {
  1376. return _sgimgui_make_str("<invalid>");
  1377. }
  1378. }
  1379. /*--- RESOURCE HELPERS -------------------------------------------------------*/
  1380. _SOKOL_PRIVATE void _sgimgui_buffer_created(sgimgui_t* ctx, sg_buffer res_id, int slot_index, const sg_buffer_desc* desc) {
  1381. SOKOL_ASSERT((slot_index > 0) && (slot_index < ctx->buffer_window.num_slots));
  1382. sgimgui_buffer_t* buf = &ctx->buffer_window.slots[slot_index];
  1383. buf->res_id = res_id;
  1384. buf->desc = *desc;
  1385. buf->label = _sgimgui_make_str(desc->label);
  1386. }
  1387. _SOKOL_PRIVATE void _sgimgui_buffer_destroyed(sgimgui_t* ctx, int slot_index) {
  1388. SOKOL_ASSERT((slot_index > 0) && (slot_index < ctx->buffer_window.num_slots));
  1389. sgimgui_buffer_t* buf = &ctx->buffer_window.slots[slot_index];
  1390. buf->res_id.id = SG_INVALID_ID;
  1391. }
  1392. _SOKOL_PRIVATE void _sgimgui_image_created(sgimgui_t* ctx, sg_image res_id, int slot_index, const sg_image_desc* desc) {
  1393. SOKOL_ASSERT((slot_index > 0) && (slot_index < ctx->image_window.num_slots));
  1394. sgimgui_image_t* img = &ctx->image_window.slots[slot_index];
  1395. img->res_id = res_id;
  1396. img->desc = *desc;
  1397. img->ui_scale = 1.0f;
  1398. img->label = _sgimgui_make_str(desc->label);
  1399. }
  1400. _SOKOL_PRIVATE void _sgimgui_image_destroyed(sgimgui_t* ctx, int slot_index) {
  1401. SOKOL_ASSERT((slot_index > 0) && (slot_index < ctx->image_window.num_slots));
  1402. sgimgui_image_t* img = &ctx->image_window.slots[slot_index];
  1403. img->res_id.id = SG_INVALID_ID;
  1404. }
  1405. _SOKOL_PRIVATE void _sgimgui_sampler_created(sgimgui_t* ctx, sg_sampler res_id, int slot_index, const sg_sampler_desc* desc) {
  1406. SOKOL_ASSERT((slot_index > 0) && (slot_index < ctx->sampler_window.num_slots));
  1407. sgimgui_sampler_t* smp = &ctx->sampler_window.slots[slot_index];
  1408. smp->res_id = res_id;
  1409. smp->desc = *desc;
  1410. smp->label = _sgimgui_make_str(desc->label);
  1411. }
  1412. _SOKOL_PRIVATE void _sgimgui_sampler_destroyed(sgimgui_t* ctx, int slot_index) {
  1413. SOKOL_ASSERT((slot_index > 0) && (slot_index < ctx->sampler_window.num_slots));
  1414. sgimgui_sampler_t* smp = &ctx->sampler_window.slots[slot_index];
  1415. smp->res_id.id = SG_INVALID_ID;
  1416. }
  1417. _SOKOL_PRIVATE void _sgimgui_shader_created(sgimgui_t* ctx, sg_shader res_id, int slot_index, const sg_shader_desc* desc) {
  1418. SOKOL_ASSERT((slot_index > 0) && (slot_index < ctx->shader_window.num_slots));
  1419. sgimgui_shader_t* shd = &ctx->shader_window.slots[slot_index];
  1420. shd->res_id = res_id;
  1421. shd->desc = *desc;
  1422. shd->label = _sgimgui_make_str(desc->label);
  1423. if (shd->desc.vertex_func.entry) {
  1424. shd->vs_entry = _sgimgui_make_str(shd->desc.vertex_func.entry);
  1425. shd->desc.vertex_func.entry = shd->vs_entry.buf;
  1426. }
  1427. if (shd->desc.fragment_func.entry) {
  1428. shd->fs_entry = _sgimgui_make_str(shd->desc.fragment_func.entry);
  1429. shd->desc.fragment_func.entry = shd->fs_entry.buf;
  1430. }
  1431. if (shd->desc.vertex_func.d3d11_target) {
  1432. shd->vs_d3d11_target = _sgimgui_make_str(shd->desc.vertex_func.d3d11_target);
  1433. shd->desc.vertex_func.d3d11_target = shd->vs_d3d11_target.buf;
  1434. }
  1435. if (shd->desc.fragment_func.d3d11_target) {
  1436. shd->fs_d3d11_target = _sgimgui_make_str(shd->desc.fragment_func.d3d11_target);
  1437. shd->desc.fragment_func.d3d11_target = shd->fs_d3d11_target.buf;
  1438. }
  1439. for (int i = 0; i < SG_MAX_UNIFORMBLOCK_BINDSLOTS; i++) {
  1440. for (int j = 0; j < SG_MAX_UNIFORMBLOCK_MEMBERS; j++) {
  1441. sg_glsl_shader_uniform* su = &shd->desc.uniform_blocks[i].glsl_uniforms[j];
  1442. if (su->glsl_name) {
  1443. shd->glsl_uniform_name[i][j] = _sgimgui_make_str(su->glsl_name);
  1444. su->glsl_name = shd->glsl_uniform_name[i][j].buf;
  1445. }
  1446. }
  1447. }
  1448. for (int i = 0; i < SG_MAX_IMAGE_SAMPLER_PAIRS; i++) {
  1449. if (shd->desc.image_sampler_pairs[i].glsl_name) {
  1450. shd->glsl_image_sampler_name[i] = _sgimgui_make_str(shd->desc.image_sampler_pairs[i].glsl_name);
  1451. shd->desc.image_sampler_pairs[i].glsl_name = shd->glsl_image_sampler_name[i].buf;
  1452. }
  1453. }
  1454. if (shd->desc.vertex_func.source) {
  1455. shd->desc.vertex_func.source = _sgimgui_str_dup(&ctx->desc.allocator, shd->desc.vertex_func.source);
  1456. }
  1457. if (shd->desc.vertex_func.bytecode.ptr) {
  1458. shd->desc.vertex_func.bytecode.ptr = _sgimgui_bin_dup(&ctx->desc.allocator, shd->desc.vertex_func.bytecode.ptr, shd->desc.vertex_func.bytecode.size);
  1459. }
  1460. if (shd->desc.fragment_func.source) {
  1461. shd->desc.fragment_func.source = _sgimgui_str_dup(&ctx->desc.allocator, shd->desc.fragment_func.source);
  1462. }
  1463. if (shd->desc.fragment_func.bytecode.ptr) {
  1464. shd->desc.fragment_func.bytecode.ptr = _sgimgui_bin_dup(&ctx->desc.allocator, shd->desc.fragment_func.bytecode.ptr, shd->desc.fragment_func.bytecode.size);
  1465. }
  1466. for (int i = 0; i < SG_MAX_VERTEX_ATTRIBUTES; i++) {
  1467. sg_shader_vertex_attr* va = &shd->desc.attrs[i];
  1468. if (va->glsl_name) {
  1469. shd->attr_glsl_name[i] = _sgimgui_make_str(va->glsl_name);
  1470. va->glsl_name = shd->attr_glsl_name[i].buf;
  1471. }
  1472. if (va->hlsl_sem_name) {
  1473. shd->attr_hlsl_sem_name[i] = _sgimgui_make_str(va->hlsl_sem_name);
  1474. va->hlsl_sem_name = shd->attr_hlsl_sem_name[i].buf;
  1475. }
  1476. }
  1477. }
  1478. _SOKOL_PRIVATE void _sgimgui_shader_destroyed(sgimgui_t* ctx, int slot_index) {
  1479. SOKOL_ASSERT((slot_index > 0) && (slot_index < ctx->shader_window.num_slots));
  1480. sgimgui_shader_t* shd = &ctx->shader_window.slots[slot_index];
  1481. shd->res_id.id = SG_INVALID_ID;
  1482. if (shd->desc.vertex_func.source) {
  1483. _sgimgui_free(&ctx->desc.allocator, (void*)shd->desc.vertex_func.source);
  1484. shd->desc.vertex_func.source = 0;
  1485. }
  1486. if (shd->desc.vertex_func.bytecode.ptr) {
  1487. _sgimgui_free(&ctx->desc.allocator, (void*)shd->desc.vertex_func.bytecode.ptr);
  1488. shd->desc.vertex_func.bytecode.ptr = 0;
  1489. }
  1490. if (shd->desc.fragment_func.source) {
  1491. _sgimgui_free(&ctx->desc.allocator, (void*)shd->desc.fragment_func.source);
  1492. shd->desc.fragment_func.source = 0;
  1493. }
  1494. if (shd->desc.fragment_func.bytecode.ptr) {
  1495. _sgimgui_free(&ctx->desc.allocator, (void*)shd->desc.fragment_func.bytecode.ptr);
  1496. shd->desc.fragment_func.bytecode.ptr = 0;
  1497. }
  1498. }
  1499. _SOKOL_PRIVATE void _sgimgui_pipeline_created(sgimgui_t* ctx, sg_pipeline res_id, int slot_index, const sg_pipeline_desc* desc) {
  1500. SOKOL_ASSERT((slot_index > 0) && (slot_index < ctx->pipeline_window.num_slots));
  1501. sgimgui_pipeline_t* pip = &ctx->pipeline_window.slots[slot_index];
  1502. pip->res_id = res_id;
  1503. pip->label = _sgimgui_make_str(desc->label);
  1504. pip->desc = *desc;
  1505. }
  1506. _SOKOL_PRIVATE void _sgimgui_pipeline_destroyed(sgimgui_t* ctx, int slot_index) {
  1507. SOKOL_ASSERT((slot_index > 0) && (slot_index < ctx->pipeline_window.num_slots));
  1508. sgimgui_pipeline_t* pip = &ctx->pipeline_window.slots[slot_index];
  1509. pip->res_id.id = SG_INVALID_ID;
  1510. }
  1511. _SOKOL_PRIVATE void _sgimgui_attachments_created(sgimgui_t* ctx, sg_attachments res_id, int slot_index, const sg_attachments_desc* desc) {
  1512. SOKOL_ASSERT((slot_index > 0) && (slot_index < ctx->attachments_window.num_slots));
  1513. sgimgui_attachments_t* atts = &ctx->attachments_window.slots[slot_index];
  1514. atts->res_id = res_id;
  1515. for (int i = 0; i < SG_MAX_COLOR_ATTACHMENTS; i++) {
  1516. atts->color_image_scale[i] = 0.25f;
  1517. atts->resolve_image_scale[i] = 0.25f;
  1518. }
  1519. atts->ds_image_scale = 0.25f;
  1520. for (int i = 0; i < SG_MAX_STORAGE_ATTACHMENTS; i++) {
  1521. atts->storage_image_scale[i] = 0.25f;
  1522. }
  1523. atts->label = _sgimgui_make_str(desc->label);
  1524. atts->desc = *desc;
  1525. }
  1526. _SOKOL_PRIVATE void _sgimgui_attachments_destroyed(sgimgui_t* ctx, int slot_index) {
  1527. SOKOL_ASSERT((slot_index > 0) && (slot_index < ctx->attachments_window.num_slots));
  1528. sgimgui_attachments_t* atts = &ctx->attachments_window.slots[slot_index];
  1529. atts->res_id.id = SG_INVALID_ID;
  1530. }
  1531. /*--- COMMAND CAPTURING ------------------------------------------------------*/
  1532. _SOKOL_PRIVATE void _sgimgui_capture_init(sgimgui_t* ctx) {
  1533. const size_t ubuf_initial_size = 256 * 1024;
  1534. for (int i = 0; i < 2; i++) {
  1535. sgimgui_capture_bucket_t* bucket = &ctx->capture_window.bucket[i];
  1536. bucket->ubuf_size = ubuf_initial_size;
  1537. bucket->ubuf = (uint8_t*) _sgimgui_malloc(&ctx->desc.allocator, bucket->ubuf_size);
  1538. }
  1539. }
  1540. _SOKOL_PRIVATE void _sgimgui_capture_discard(sgimgui_t* ctx) {
  1541. for (int i = 0; i < 2; i++) {
  1542. sgimgui_capture_bucket_t* bucket = &ctx->capture_window.bucket[i];
  1543. SOKOL_ASSERT(bucket->ubuf);
  1544. _sgimgui_free(&ctx->desc.allocator, bucket->ubuf);
  1545. bucket->ubuf = 0;
  1546. }
  1547. }
  1548. _SOKOL_PRIVATE sgimgui_capture_bucket_t* _sgimgui_capture_get_write_bucket(sgimgui_t* ctx) {
  1549. return &ctx->capture_window.bucket[ctx->capture_window.bucket_index & 1];
  1550. }
  1551. _SOKOL_PRIVATE sgimgui_capture_bucket_t* _sgimgui_capture_get_read_bucket(sgimgui_t* ctx) {
  1552. return &ctx->capture_window.bucket[(ctx->capture_window.bucket_index + 1) & 1];
  1553. }
  1554. _SOKOL_PRIVATE void _sgimgui_capture_next_frame(sgimgui_t* ctx) {
  1555. ctx->capture_window.bucket_index = (ctx->capture_window.bucket_index + 1) & 1;
  1556. sgimgui_capture_bucket_t* bucket = &ctx->capture_window.bucket[ctx->capture_window.bucket_index];
  1557. bucket->num_items = 0;
  1558. bucket->ubuf_pos = 0;
  1559. }
  1560. _SOKOL_PRIVATE void _sgimgui_capture_grow_ubuf(sgimgui_t* ctx, size_t required_size) {
  1561. sgimgui_capture_bucket_t* bucket = _sgimgui_capture_get_write_bucket(ctx);
  1562. SOKOL_ASSERT(required_size > bucket->ubuf_size);
  1563. size_t old_size = bucket->ubuf_size;
  1564. size_t new_size = required_size + (required_size>>1); /* allocate a bit ahead */
  1565. bucket->ubuf_size = new_size;
  1566. bucket->ubuf = (uint8_t*) _sgimgui_realloc(&ctx->desc.allocator, bucket->ubuf, old_size, new_size);
  1567. }
  1568. _SOKOL_PRIVATE sgimgui_capture_item_t* _sgimgui_capture_next_write_item(sgimgui_t* ctx) {
  1569. sgimgui_capture_bucket_t* bucket = _sgimgui_capture_get_write_bucket(ctx);
  1570. if (bucket->num_items < sgimgui_MAX_FRAMECAPTURE_ITEMS) {
  1571. sgimgui_capture_item_t* item = &bucket->items[bucket->num_items++];
  1572. return item;
  1573. } else {
  1574. return 0;
  1575. }
  1576. }
  1577. _SOKOL_PRIVATE int _sgimgui_capture_num_read_items(sgimgui_t* ctx) {
  1578. sgimgui_capture_bucket_t* bucket = _sgimgui_capture_get_read_bucket(ctx);
  1579. return bucket->num_items;
  1580. }
  1581. _SOKOL_PRIVATE sgimgui_capture_item_t* _sgimgui_capture_read_item_at(sgimgui_t* ctx, int index) {
  1582. sgimgui_capture_bucket_t* bucket = _sgimgui_capture_get_read_bucket(ctx);
  1583. SOKOL_ASSERT(index < bucket->num_items);
  1584. return &bucket->items[index];
  1585. }
  1586. _SOKOL_PRIVATE size_t _sgimgui_capture_uniforms(sgimgui_t* ctx, const sg_range* data) {
  1587. sgimgui_capture_bucket_t* bucket = _sgimgui_capture_get_write_bucket(ctx);
  1588. const size_t required_size = bucket->ubuf_pos + data->size;
  1589. if (required_size > bucket->ubuf_size) {
  1590. _sgimgui_capture_grow_ubuf(ctx, required_size);
  1591. }
  1592. SOKOL_ASSERT(required_size <= bucket->ubuf_size);
  1593. memcpy(bucket->ubuf + bucket->ubuf_pos, data->ptr, data->size);
  1594. const size_t pos = bucket->ubuf_pos;
  1595. bucket->ubuf_pos += data->size;
  1596. SOKOL_ASSERT(bucket->ubuf_pos <= bucket->ubuf_size);
  1597. return pos;
  1598. }
  1599. _SOKOL_PRIVATE sgimgui_str_t _sgimgui_capture_item_string(sgimgui_t* ctx, int index, const sgimgui_capture_item_t* item) {
  1600. sgimgui_str_t str = _sgimgui_make_str(0);
  1601. switch (item->cmd) {
  1602. case SGIMGUI_CMD_RESET_STATE_CACHE:
  1603. _sgimgui_snprintf(&str, "%d: sg_reset_state_cache()", index);
  1604. break;
  1605. case SGIMGUI_CMD_MAKE_BUFFER:
  1606. {
  1607. sgimgui_str_t res_id = _sgimgui_buffer_id_string(ctx, item->args.make_buffer.result);
  1608. _sgimgui_snprintf(&str, "%d: sg_make_buffer(desc=..) => %s", index, res_id.buf);
  1609. }
  1610. break;
  1611. case SGIMGUI_CMD_MAKE_IMAGE:
  1612. {
  1613. sgimgui_str_t res_id = _sgimgui_image_id_string(ctx, item->args.make_image.result);
  1614. _sgimgui_snprintf(&str, "%d: sg_make_image(desc=..) => %s", index, res_id.buf);
  1615. }
  1616. break;
  1617. case SGIMGUI_CMD_MAKE_SAMPLER:
  1618. {
  1619. sgimgui_str_t res_id = _sgimgui_sampler_id_string(ctx, item->args.make_sampler.result);
  1620. _sgimgui_snprintf(&str, "%d: sg_make_sampler(desc=..) => %s", index, res_id.buf);
  1621. }
  1622. break;
  1623. case SGIMGUI_CMD_MAKE_SHADER:
  1624. {
  1625. sgimgui_str_t res_id = _sgimgui_shader_id_string(ctx, item->args.make_shader.result);
  1626. _sgimgui_snprintf(&str, "%d: sg_make_shader(desc=..) => %s", index, res_id.buf);
  1627. }
  1628. break;
  1629. case SGIMGUI_CMD_MAKE_PIPELINE:
  1630. {
  1631. sgimgui_str_t res_id = _sgimgui_pipeline_id_string(ctx, item->args.make_pipeline.result);
  1632. _sgimgui_snprintf(&str, "%d: sg_make_pipeline(desc=..) => %s", index, res_id.buf);
  1633. }
  1634. break;
  1635. case SGIMGUI_CMD_MAKE_ATTACHMENTS:
  1636. {
  1637. sgimgui_str_t res_id = _sgimgui_attachments_id_string(ctx, item->args.make_attachments.result);
  1638. _sgimgui_snprintf(&str, "%d: sg_make_attachments(desc=..) => %s", index, res_id.buf);
  1639. }
  1640. break;
  1641. case SGIMGUI_CMD_DESTROY_BUFFER:
  1642. {
  1643. sgimgui_str_t res_id = _sgimgui_buffer_id_string(ctx, item->args.destroy_buffer.buffer);
  1644. _sgimgui_snprintf(&str, "%d: sg_destroy_buffer(buf=%s)", index, res_id.buf);
  1645. }
  1646. break;
  1647. case SGIMGUI_CMD_DESTROY_IMAGE:
  1648. {
  1649. sgimgui_str_t res_id = _sgimgui_image_id_string(ctx, item->args.destroy_image.image);
  1650. _sgimgui_snprintf(&str, "%d: sg_destroy_image(img=%s)", index, res_id.buf);
  1651. }
  1652. break;
  1653. case SGIMGUI_CMD_DESTROY_SAMPLER:
  1654. {
  1655. sgimgui_str_t res_id = _sgimgui_sampler_id_string(ctx, item->args.destroy_sampler.sampler);
  1656. _sgimgui_snprintf(&str, "%d: sg_destroy_sampler(smp=%s)", index, res_id.buf);
  1657. }
  1658. break;
  1659. case SGIMGUI_CMD_DESTROY_SHADER:
  1660. {
  1661. sgimgui_str_t res_id = _sgimgui_shader_id_string(ctx, item->args.destroy_shader.shader);
  1662. _sgimgui_snprintf(&str, "%d: sg_destroy_shader(shd=%s)", index, res_id.buf);
  1663. }
  1664. break;
  1665. case SGIMGUI_CMD_DESTROY_PIPELINE:
  1666. {
  1667. sgimgui_str_t res_id = _sgimgui_pipeline_id_string(ctx, item->args.destroy_pipeline.pipeline);
  1668. _sgimgui_snprintf(&str, "%d: sg_destroy_pipeline(pip=%s)", index, res_id.buf);
  1669. }
  1670. break;
  1671. case SGIMGUI_CMD_DESTROY_ATTACHMENTS:
  1672. {
  1673. sgimgui_str_t res_id = _sgimgui_attachments_id_string(ctx, item->args.destroy_attachments.attachments);
  1674. _sgimgui_snprintf(&str, "%d: sg_destroy_attachments(atts=%s)", index, res_id.buf);
  1675. }
  1676. break;
  1677. case SGIMGUI_CMD_UPDATE_BUFFER:
  1678. {
  1679. sgimgui_str_t res_id = _sgimgui_buffer_id_string(ctx, item->args.update_buffer.buffer);
  1680. _sgimgui_snprintf(&str, "%d: sg_update_buffer(buf=%s, data.size=%d)",
  1681. index, res_id.buf,
  1682. item->args.update_buffer.data_size);
  1683. }
  1684. break;
  1685. case SGIMGUI_CMD_UPDATE_IMAGE:
  1686. {
  1687. sgimgui_str_t res_id = _sgimgui_image_id_string(ctx, item->args.update_image.image);
  1688. _sgimgui_snprintf(&str, "%d: sg_update_image(img=%s, data=..)", index, res_id.buf);
  1689. }
  1690. break;
  1691. case SGIMGUI_CMD_APPEND_BUFFER:
  1692. {
  1693. sgimgui_str_t res_id = _sgimgui_buffer_id_string(ctx, item->args.append_buffer.buffer);
  1694. _sgimgui_snprintf(&str, "%d: sg_append_buffer(buf=%s, data.size=%d) => %d",
  1695. index, res_id.buf,
  1696. item->args.append_buffer.data_size,
  1697. item->args.append_buffer.result);
  1698. }
  1699. break;
  1700. case SGIMGUI_CMD_BEGIN_PASS:
  1701. {
  1702. _sgimgui_snprintf(&str, "%d: sg_begin_pass(pass=...)", index);
  1703. }
  1704. break;
  1705. case SGIMGUI_CMD_APPLY_VIEWPORT:
  1706. _sgimgui_snprintf(&str, "%d: sg_apply_viewport(x=%d, y=%d, width=%d, height=%d, origin_top_left=%s)",
  1707. index,
  1708. item->args.apply_viewport.x,
  1709. item->args.apply_viewport.y,
  1710. item->args.apply_viewport.width,
  1711. item->args.apply_viewport.height,
  1712. _sgimgui_bool_string(item->args.apply_viewport.origin_top_left));
  1713. break;
  1714. case SGIMGUI_CMD_APPLY_SCISSOR_RECT:
  1715. _sgimgui_snprintf(&str, "%d: sg_apply_scissor_rect(x=%d, y=%d, width=%d, height=%d, origin_top_left=%s)",
  1716. index,
  1717. item->args.apply_scissor_rect.x,
  1718. item->args.apply_scissor_rect.y,
  1719. item->args.apply_scissor_rect.width,
  1720. item->args.apply_scissor_rect.height,
  1721. _sgimgui_bool_string(item->args.apply_scissor_rect.origin_top_left));
  1722. break;
  1723. case SGIMGUI_CMD_APPLY_PIPELINE:
  1724. {
  1725. sgimgui_str_t res_id = _sgimgui_pipeline_id_string(ctx, item->args.apply_pipeline.pipeline);
  1726. _sgimgui_snprintf(&str, "%d: sg_apply_pipeline(pip=%s)", index, res_id.buf);
  1727. }
  1728. break;
  1729. case SGIMGUI_CMD_APPLY_BINDINGS:
  1730. _sgimgui_snprintf(&str, "%d: sg_apply_bindings(bindings=..)", index);
  1731. break;
  1732. case SGIMGUI_CMD_APPLY_UNIFORMS:
  1733. _sgimgui_snprintf(&str, "%d: sg_apply_uniforms(ub_slot=%d, data.size=%d)",
  1734. index,
  1735. item->args.apply_uniforms.ub_slot,
  1736. item->args.apply_uniforms.data_size);
  1737. break;
  1738. case SGIMGUI_CMD_DRAW:
  1739. _sgimgui_snprintf(&str, "%d: sg_draw(base_element=%d, num_elements=%d, num_instances=%d)",
  1740. index,
  1741. item->args.draw.base_element,
  1742. item->args.draw.num_elements,
  1743. item->args.draw.num_instances);
  1744. break;
  1745. case SGIMGUI_CMD_DISPATCH:
  1746. _sgimgui_snprintf(&str, "%d: sg_dispatch(num_groups_x=%d, num_groups_y=%d, num_groups_z=%d)",
  1747. index,
  1748. item->args.dispatch.num_groups_x,
  1749. item->args.dispatch.num_groups_y,
  1750. item->args.dispatch.num_groups_z);
  1751. break;
  1752. case SGIMGUI_CMD_END_PASS:
  1753. _sgimgui_snprintf(&str, "%d: sg_end_pass()", index);
  1754. break;
  1755. case SGIMGUI_CMD_COMMIT:
  1756. _sgimgui_snprintf(&str, "%d: sg_commit()", index);
  1757. break;
  1758. case SGIMGUI_CMD_ALLOC_BUFFER:
  1759. {
  1760. sgimgui_str_t res_id = _sgimgui_buffer_id_string(ctx, item->args.alloc_buffer.result);
  1761. _sgimgui_snprintf(&str, "%d: sg_alloc_buffer() => %s", index, res_id.buf);
  1762. }
  1763. break;
  1764. case SGIMGUI_CMD_ALLOC_IMAGE:
  1765. {
  1766. sgimgui_str_t res_id = _sgimgui_image_id_string(ctx, item->args.alloc_image.result);
  1767. _sgimgui_snprintf(&str, "%d: sg_alloc_image() => %s", index, res_id.buf);
  1768. }
  1769. break;
  1770. case SGIMGUI_CMD_ALLOC_SAMPLER:
  1771. {
  1772. sgimgui_str_t res_id = _sgimgui_sampler_id_string(ctx, item->args.alloc_sampler.result);
  1773. _sgimgui_snprintf(&str, "%d: sg_alloc_sampler() => %s", index, res_id.buf);
  1774. }
  1775. break;
  1776. case SGIMGUI_CMD_ALLOC_SHADER:
  1777. {
  1778. sgimgui_str_t res_id = _sgimgui_shader_id_string(ctx, item->args.alloc_shader.result);
  1779. _sgimgui_snprintf(&str, "%d: sg_alloc_shader() => %s", index, res_id.buf);
  1780. }
  1781. break;
  1782. case SGIMGUI_CMD_ALLOC_PIPELINE:
  1783. {
  1784. sgimgui_str_t res_id = _sgimgui_pipeline_id_string(ctx, item->args.alloc_pipeline.result);
  1785. _sgimgui_snprintf(&str, "%d: sg_alloc_pipeline() => %s", index, res_id.buf);
  1786. }
  1787. break;
  1788. case SGIMGUI_CMD_ALLOC_ATTACHMENTS:
  1789. {
  1790. sgimgui_str_t res_id = _sgimgui_attachments_id_string(ctx, item->args.alloc_attachments.result);
  1791. _sgimgui_snprintf(&str, "%d: sg_alloc_attachments() => %s", index, res_id.buf);
  1792. }
  1793. break;
  1794. case SGIMGUI_CMD_DEALLOC_BUFFER:
  1795. {
  1796. sgimgui_str_t res_id = _sgimgui_buffer_id_string(ctx, item->args.dealloc_buffer.buffer);
  1797. _sgimgui_snprintf(&str, "%d: sg_dealloc_buffer(buf=%s)", index, res_id.buf);
  1798. }
  1799. break;
  1800. case SGIMGUI_CMD_DEALLOC_IMAGE:
  1801. {
  1802. sgimgui_str_t res_id = _sgimgui_image_id_string(ctx, item->args.dealloc_image.image);
  1803. _sgimgui_snprintf(&str, "%d: sg_dealloc_image(img=%d)", index, res_id.buf);
  1804. }
  1805. break;
  1806. case SGIMGUI_CMD_DEALLOC_SAMPLER:
  1807. {
  1808. sgimgui_str_t res_id = _sgimgui_sampler_id_string(ctx, item->args.dealloc_sampler.sampler);
  1809. _sgimgui_snprintf(&str, "%d: sg_dealloc_sampler(smp=%s)", index, res_id.buf);
  1810. }
  1811. break;
  1812. case SGIMGUI_CMD_DEALLOC_SHADER:
  1813. {
  1814. sgimgui_str_t res_id = _sgimgui_shader_id_string(ctx, item->args.dealloc_shader.shader);
  1815. _sgimgui_snprintf(&str, "%d: sg_dealloc_shader(shd=%s)", index, res_id.buf);
  1816. }
  1817. break;
  1818. case SGIMGUI_CMD_DEALLOC_PIPELINE:
  1819. {
  1820. sgimgui_str_t res_id = _sgimgui_pipeline_id_string(ctx, item->args.dealloc_pipeline.pipeline);
  1821. _sgimgui_snprintf(&str, "%d: sg_dealloc_pipeline(pip=%s)", index, res_id.buf);
  1822. }
  1823. break;
  1824. case SGIMGUI_CMD_DEALLOC_ATTACHMENTS:
  1825. {
  1826. sgimgui_str_t res_id = _sgimgui_attachments_id_string(ctx, item->args.dealloc_attachments.attachments);
  1827. _sgimgui_snprintf(&str, "%d: sg_dealloc_attachments(atts=%s)", index, res_id.buf);
  1828. }
  1829. break;
  1830. case SGIMGUI_CMD_INIT_BUFFER:
  1831. {
  1832. sgimgui_str_t res_id = _sgimgui_buffer_id_string(ctx, item->args.init_buffer.buffer);
  1833. _sgimgui_snprintf(&str, "%d: sg_init_buffer(buf=%s, desc=..)", index, res_id.buf);
  1834. }
  1835. break;
  1836. case SGIMGUI_CMD_INIT_IMAGE:
  1837. {
  1838. sgimgui_str_t res_id = _sgimgui_image_id_string(ctx, item->args.init_image.image);
  1839. _sgimgui_snprintf(&str, "%d: sg_init_image(img=%s, desc=..)", index, res_id.buf);
  1840. }
  1841. break;
  1842. case SGIMGUI_CMD_INIT_SAMPLER:
  1843. {
  1844. sgimgui_str_t res_id = _sgimgui_sampler_id_string(ctx, item->args.init_sampler.sampler);
  1845. _sgimgui_snprintf(&str, "%d: sg_init_sampler(smp=%s, desc=..)", index, res_id.buf);
  1846. }
  1847. break;
  1848. case SGIMGUI_CMD_INIT_SHADER:
  1849. {
  1850. sgimgui_str_t res_id = _sgimgui_shader_id_string(ctx, item->args.init_shader.shader);
  1851. _sgimgui_snprintf(&str, "%d: sg_init_shader(shd=%s, desc=..)", index, res_id.buf);
  1852. }
  1853. break;
  1854. case SGIMGUI_CMD_INIT_PIPELINE:
  1855. {
  1856. sgimgui_str_t res_id = _sgimgui_pipeline_id_string(ctx, item->args.init_pipeline.pipeline);
  1857. _sgimgui_snprintf(&str, "%d: sg_init_pipeline(pip=%s, desc=..)", index, res_id.buf);
  1858. }
  1859. break;
  1860. case SGIMGUI_CMD_INIT_ATTACHMENTS:
  1861. {
  1862. sgimgui_str_t res_id = _sgimgui_attachments_id_string(ctx, item->args.init_attachments.attachments);
  1863. _sgimgui_snprintf(&str, "%d: sg_init_attachments(atts=%s, desc=..)", index, res_id.buf);
  1864. }
  1865. break;
  1866. case SGIMGUI_CMD_UNINIT_BUFFER:
  1867. {
  1868. sgimgui_str_t res_id = _sgimgui_buffer_id_string(ctx, item->args.uninit_buffer.buffer);
  1869. _sgimgui_snprintf(&str, "%d: sg_uninit_buffer(buf=%s)", index, res_id.buf);
  1870. }
  1871. break;
  1872. case SGIMGUI_CMD_UNINIT_IMAGE:
  1873. {
  1874. sgimgui_str_t res_id = _sgimgui_image_id_string(ctx, item->args.uninit_image.image);
  1875. _sgimgui_snprintf(&str, "%d: sg_uninit_image(img=%s)", index, res_id.buf);
  1876. }
  1877. break;
  1878. case SGIMGUI_CMD_UNINIT_SAMPLER:
  1879. {
  1880. sgimgui_str_t res_id = _sgimgui_sampler_id_string(ctx, item->args.uninit_sampler.sampler);
  1881. _sgimgui_snprintf(&str, "%d: sg_uninit_sampler(smp=%s)", index, res_id.buf);
  1882. }
  1883. break;
  1884. case SGIMGUI_CMD_UNINIT_SHADER:
  1885. {
  1886. sgimgui_str_t res_id = _sgimgui_shader_id_string(ctx, item->args.uninit_shader.shader);
  1887. _sgimgui_snprintf(&str, "%d: sg_uninit_shader(shd=%s)", index, res_id.buf);
  1888. }
  1889. break;
  1890. case SGIMGUI_CMD_UNINIT_PIPELINE:
  1891. {
  1892. sgimgui_str_t res_id = _sgimgui_pipeline_id_string(ctx, item->args.uninit_pipeline.pipeline);
  1893. _sgimgui_snprintf(&str, "%d: sg_uninit_pipeline(pip=%s)", index, res_id.buf);
  1894. }
  1895. break;
  1896. case SGIMGUI_CMD_UNINIT_ATTACHMENTS:
  1897. {
  1898. sgimgui_str_t res_id = _sgimgui_attachments_id_string(ctx, item->args.uninit_attachments.attachments);
  1899. _sgimgui_snprintf(&str, "%d: sg_uninit_attachments(atts=%s)", index, res_id.buf);
  1900. }
  1901. break;
  1902. case SGIMGUI_CMD_FAIL_BUFFER:
  1903. {
  1904. sgimgui_str_t res_id = _sgimgui_buffer_id_string(ctx, item->args.fail_buffer.buffer);
  1905. _sgimgui_snprintf(&str, "%d: sg_fail_buffer(buf=%s)", index, res_id.buf);
  1906. }
  1907. break;
  1908. case SGIMGUI_CMD_FAIL_IMAGE:
  1909. {
  1910. sgimgui_str_t res_id = _sgimgui_image_id_string(ctx, item->args.fail_image.image);
  1911. _sgimgui_snprintf(&str, "%d: sg_fail_image(img=%s)", index, res_id.buf);
  1912. }
  1913. break;
  1914. case SGIMGUI_CMD_FAIL_SAMPLER:
  1915. {
  1916. sgimgui_str_t res_id = _sgimgui_sampler_id_string(ctx, item->args.fail_sampler.sampler);
  1917. _sgimgui_snprintf(&str, "%d: sg_fail_sampler(smp=%s)", index, res_id.buf);
  1918. }
  1919. break;
  1920. case SGIMGUI_CMD_FAIL_SHADER:
  1921. {
  1922. sgimgui_str_t res_id = _sgimgui_shader_id_string(ctx, item->args.fail_shader.shader);
  1923. _sgimgui_snprintf(&str, "%d: sg_fail_shader(shd=%s)", index, res_id.buf);
  1924. }
  1925. break;
  1926. case SGIMGUI_CMD_FAIL_PIPELINE:
  1927. {
  1928. sgimgui_str_t res_id = _sgimgui_pipeline_id_string(ctx, item->args.fail_pipeline.pipeline);
  1929. _sgimgui_snprintf(&str, "%d: sg_fail_pipeline(shd=%s)", index, res_id.buf);
  1930. }
  1931. break;
  1932. case SGIMGUI_CMD_FAIL_ATTACHMENTS:
  1933. {
  1934. sgimgui_str_t res_id = _sgimgui_attachments_id_string(ctx, item->args.fail_attachments.attachments);
  1935. _sgimgui_snprintf(&str, "%d: sg_fail_attachments(atts=%s)", index, res_id.buf);
  1936. }
  1937. break;
  1938. case SGIMGUI_CMD_PUSH_DEBUG_GROUP:
  1939. _sgimgui_snprintf(&str, "%d: sg_push_debug_group(name=%s)", index,
  1940. item->args.push_debug_group.name.buf);
  1941. break;
  1942. case SGIMGUI_CMD_POP_DEBUG_GROUP:
  1943. _sgimgui_snprintf(&str, "%d: sg_pop_debug_group()", index);
  1944. break;
  1945. default:
  1946. _sgimgui_snprintf(&str, "%d: ???", index);
  1947. break;
  1948. }
  1949. return str;
  1950. }
  1951. /*--- CAPTURE CALLBACKS ------------------------------------------------------*/
  1952. _SOKOL_PRIVATE void _sgimgui_reset_state_cache(void* user_data) {
  1953. sgimgui_t* ctx = (sgimgui_t*) user_data;
  1954. SOKOL_ASSERT(ctx);
  1955. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  1956. if (item) {
  1957. item->cmd = SGIMGUI_CMD_RESET_STATE_CACHE;
  1958. item->color = _SGIMGUI_COLOR_OTHER;
  1959. }
  1960. if (ctx->hooks.reset_state_cache) {
  1961. ctx->hooks.reset_state_cache(ctx->hooks.user_data);
  1962. }
  1963. }
  1964. _SOKOL_PRIVATE void _sgimgui_make_buffer(const sg_buffer_desc* desc, sg_buffer buf_id, void* user_data) {
  1965. sgimgui_t* ctx = (sgimgui_t*) user_data;
  1966. SOKOL_ASSERT(ctx);
  1967. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  1968. if (item) {
  1969. item->cmd = SGIMGUI_CMD_MAKE_BUFFER;
  1970. item->color = _SGIMGUI_COLOR_RSRC;
  1971. item->args.make_buffer.result = buf_id;
  1972. }
  1973. if (ctx->hooks.make_buffer) {
  1974. ctx->hooks.make_buffer(desc, buf_id, ctx->hooks.user_data);
  1975. }
  1976. if (buf_id.id != SG_INVALID_ID) {
  1977. _sgimgui_buffer_created(ctx, buf_id, _sgimgui_slot_index(buf_id.id), desc);
  1978. }
  1979. }
  1980. _SOKOL_PRIVATE void _sgimgui_make_image(const sg_image_desc* desc, sg_image img_id, void* user_data) {
  1981. sgimgui_t* ctx = (sgimgui_t*) user_data;
  1982. SOKOL_ASSERT(ctx);
  1983. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  1984. if (item) {
  1985. item->cmd = SGIMGUI_CMD_MAKE_IMAGE;
  1986. item->color = _SGIMGUI_COLOR_RSRC;
  1987. item->args.make_image.result = img_id;
  1988. }
  1989. if (ctx->hooks.make_image) {
  1990. ctx->hooks.make_image(desc, img_id, ctx->hooks.user_data);
  1991. }
  1992. if (img_id.id != SG_INVALID_ID) {
  1993. _sgimgui_image_created(ctx, img_id, _sgimgui_slot_index(img_id.id), desc);
  1994. }
  1995. }
  1996. _SOKOL_PRIVATE void _sgimgui_make_sampler(const sg_sampler_desc* desc, sg_sampler smp_id, void* user_data) {
  1997. sgimgui_t* ctx = (sgimgui_t*) user_data;
  1998. SOKOL_ASSERT(ctx);
  1999. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2000. if (item) {
  2001. item->cmd = SGIMGUI_CMD_MAKE_SAMPLER;
  2002. item->color = _SGIMGUI_COLOR_RSRC;
  2003. item->args.make_sampler.result = smp_id;
  2004. }
  2005. if (ctx->hooks.make_sampler) {
  2006. ctx->hooks.make_sampler(desc, smp_id, ctx->hooks.user_data);
  2007. }
  2008. if (smp_id.id != SG_INVALID_ID) {
  2009. _sgimgui_sampler_created(ctx, smp_id, _sgimgui_slot_index(smp_id.id), desc);
  2010. }
  2011. }
  2012. _SOKOL_PRIVATE void _sgimgui_make_shader(const sg_shader_desc* desc, sg_shader shd_id, void* user_data) {
  2013. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2014. SOKOL_ASSERT(ctx);
  2015. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2016. if (item) {
  2017. item->cmd = SGIMGUI_CMD_MAKE_SHADER;
  2018. item->color = _SGIMGUI_COLOR_RSRC;
  2019. item->args.make_shader.result = shd_id;
  2020. }
  2021. if (ctx->hooks.make_shader) {
  2022. ctx->hooks.make_shader(desc, shd_id, ctx->hooks.user_data);
  2023. }
  2024. if (shd_id.id != SG_INVALID_ID) {
  2025. _sgimgui_shader_created(ctx, shd_id, _sgimgui_slot_index(shd_id.id), desc);
  2026. }
  2027. }
  2028. _SOKOL_PRIVATE void _sgimgui_make_pipeline(const sg_pipeline_desc* desc, sg_pipeline pip_id, void* user_data) {
  2029. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2030. SOKOL_ASSERT(ctx);
  2031. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2032. if (item) {
  2033. item->cmd = SGIMGUI_CMD_MAKE_PIPELINE;
  2034. item->color = _SGIMGUI_COLOR_RSRC;
  2035. item->args.make_pipeline.result = pip_id;
  2036. }
  2037. if (ctx->hooks.make_pipeline) {
  2038. ctx->hooks.make_pipeline(desc, pip_id, ctx->hooks.user_data);
  2039. }
  2040. if (pip_id.id != SG_INVALID_ID) {
  2041. _sgimgui_pipeline_created(ctx, pip_id, _sgimgui_slot_index(pip_id.id), desc);
  2042. }
  2043. }
  2044. _SOKOL_PRIVATE void _sgimgui_make_attachments(const sg_attachments_desc* desc, sg_attachments atts_id, void* user_data) {
  2045. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2046. SOKOL_ASSERT(ctx);
  2047. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2048. if (item) {
  2049. item->cmd = SGIMGUI_CMD_MAKE_ATTACHMENTS;
  2050. item->color = _SGIMGUI_COLOR_RSRC;
  2051. item->args.make_attachments.result = atts_id;
  2052. }
  2053. if (ctx->hooks.make_attachments) {
  2054. ctx->hooks.make_attachments(desc, atts_id, ctx->hooks.user_data);
  2055. }
  2056. if (atts_id.id != SG_INVALID_ID) {
  2057. _sgimgui_attachments_created(ctx, atts_id, _sgimgui_slot_index(atts_id.id), desc);
  2058. }
  2059. }
  2060. _SOKOL_PRIVATE void _sgimgui_destroy_buffer(sg_buffer buf, void* user_data) {
  2061. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2062. SOKOL_ASSERT(ctx);
  2063. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2064. if (item) {
  2065. item->cmd = SGIMGUI_CMD_DESTROY_BUFFER;
  2066. item->color = _SGIMGUI_COLOR_RSRC;
  2067. item->args.destroy_buffer.buffer = buf;
  2068. }
  2069. if (ctx->hooks.destroy_buffer) {
  2070. ctx->hooks.destroy_buffer(buf, ctx->hooks.user_data);
  2071. }
  2072. if (buf.id != SG_INVALID_ID) {
  2073. _sgimgui_buffer_destroyed(ctx, _sgimgui_slot_index(buf.id));
  2074. }
  2075. }
  2076. _SOKOL_PRIVATE void _sgimgui_destroy_image(sg_image img, void* user_data) {
  2077. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2078. SOKOL_ASSERT(ctx);
  2079. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2080. if (item) {
  2081. item->cmd = SGIMGUI_CMD_DESTROY_IMAGE;
  2082. item->color = _SGIMGUI_COLOR_RSRC;
  2083. item->args.destroy_image.image = img;
  2084. }
  2085. if (ctx->hooks.destroy_image) {
  2086. ctx->hooks.destroy_image(img, ctx->hooks.user_data);
  2087. }
  2088. if (img.id != SG_INVALID_ID) {
  2089. _sgimgui_image_destroyed(ctx, _sgimgui_slot_index(img.id));
  2090. }
  2091. }
  2092. _SOKOL_PRIVATE void _sgimgui_destroy_sampler(sg_sampler smp, void* user_data) {
  2093. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2094. SOKOL_ASSERT(ctx);
  2095. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2096. if (item) {
  2097. item->cmd = SGIMGUI_CMD_DESTROY_SAMPLER;
  2098. item->color = _SGIMGUI_COLOR_RSRC;
  2099. item->args.destroy_sampler.sampler = smp;
  2100. }
  2101. if (ctx->hooks.destroy_sampler) {
  2102. ctx->hooks.destroy_sampler(smp, ctx->hooks.user_data);
  2103. }
  2104. if (smp.id != SG_INVALID_ID) {
  2105. _sgimgui_sampler_destroyed(ctx, _sgimgui_slot_index(smp.id));
  2106. }
  2107. }
  2108. _SOKOL_PRIVATE void _sgimgui_destroy_shader(sg_shader shd, void* user_data) {
  2109. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2110. SOKOL_ASSERT(ctx);
  2111. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2112. if (item) {
  2113. item->cmd = SGIMGUI_CMD_DESTROY_SHADER;
  2114. item->color = _SGIMGUI_COLOR_RSRC;
  2115. item->args.destroy_shader.shader = shd;
  2116. }
  2117. if (ctx->hooks.destroy_shader) {
  2118. ctx->hooks.destroy_shader(shd, ctx->hooks.user_data);
  2119. }
  2120. if (shd.id != SG_INVALID_ID) {
  2121. _sgimgui_shader_destroyed(ctx, _sgimgui_slot_index(shd.id));
  2122. }
  2123. }
  2124. _SOKOL_PRIVATE void _sgimgui_destroy_pipeline(sg_pipeline pip, void* user_data) {
  2125. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2126. SOKOL_ASSERT(ctx);
  2127. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2128. if (item) {
  2129. item->cmd = SGIMGUI_CMD_DESTROY_PIPELINE;
  2130. item->color = _SGIMGUI_COLOR_RSRC;
  2131. item->args.destroy_pipeline.pipeline = pip;
  2132. }
  2133. if (ctx->hooks.destroy_pipeline) {
  2134. ctx->hooks.destroy_pipeline(pip, ctx->hooks.user_data);
  2135. }
  2136. if (pip.id != SG_INVALID_ID) {
  2137. _sgimgui_pipeline_destroyed(ctx, _sgimgui_slot_index(pip.id));
  2138. }
  2139. }
  2140. _SOKOL_PRIVATE void _sgimgui_destroy_attachments(sg_attachments atts, void* user_data) {
  2141. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2142. SOKOL_ASSERT(ctx);
  2143. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2144. if (item) {
  2145. item->cmd = SGIMGUI_CMD_DESTROY_ATTACHMENTS;
  2146. item->color = _SGIMGUI_COLOR_RSRC;
  2147. item->args.destroy_attachments.attachments = atts;
  2148. }
  2149. if (ctx->hooks.destroy_attachments) {
  2150. ctx->hooks.destroy_attachments(atts, ctx->hooks.user_data);
  2151. }
  2152. if (atts.id != SG_INVALID_ID) {
  2153. _sgimgui_attachments_destroyed(ctx, _sgimgui_slot_index(atts.id));
  2154. }
  2155. }
  2156. _SOKOL_PRIVATE void _sgimgui_update_buffer(sg_buffer buf, const sg_range* data, void* user_data) {
  2157. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2158. SOKOL_ASSERT(ctx);
  2159. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2160. if (item) {
  2161. item->cmd = SGIMGUI_CMD_UPDATE_BUFFER;
  2162. item->color = _SGIMGUI_COLOR_RSRC;
  2163. item->args.update_buffer.buffer = buf;
  2164. item->args.update_buffer.data_size = data->size;
  2165. }
  2166. if (ctx->hooks.update_buffer) {
  2167. ctx->hooks.update_buffer(buf, data, ctx->hooks.user_data);
  2168. }
  2169. }
  2170. _SOKOL_PRIVATE void _sgimgui_update_image(sg_image img, const sg_image_data* data, void* user_data) {
  2171. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2172. SOKOL_ASSERT(ctx);
  2173. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2174. if (item) {
  2175. item->cmd = SGIMGUI_CMD_UPDATE_IMAGE;
  2176. item->color = _SGIMGUI_COLOR_RSRC;
  2177. item->args.update_image.image = img;
  2178. }
  2179. if (ctx->hooks.update_image) {
  2180. ctx->hooks.update_image(img, data, ctx->hooks.user_data);
  2181. }
  2182. }
  2183. _SOKOL_PRIVATE void _sgimgui_append_buffer(sg_buffer buf, const sg_range* data, int result, void* user_data) {
  2184. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2185. SOKOL_ASSERT(ctx);
  2186. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2187. if (item) {
  2188. item->cmd = SGIMGUI_CMD_APPEND_BUFFER;
  2189. item->color = _SGIMGUI_COLOR_RSRC;
  2190. item->args.append_buffer.buffer = buf;
  2191. item->args.append_buffer.data_size = data->size;
  2192. item->args.append_buffer.result = result;
  2193. }
  2194. if (ctx->hooks.append_buffer) {
  2195. ctx->hooks.append_buffer(buf, data, result, ctx->hooks.user_data);
  2196. }
  2197. }
  2198. _SOKOL_PRIVATE void _sgimgui_begin_pass(const sg_pass* pass, void* user_data) {
  2199. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2200. SOKOL_ASSERT(ctx);
  2201. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2202. if (item) {
  2203. SOKOL_ASSERT(pass);
  2204. item->cmd = SGIMGUI_CMD_BEGIN_PASS;
  2205. item->color = _SGIMGUI_COLOR_PASS;
  2206. item->args.begin_pass.pass = *pass;
  2207. }
  2208. if (ctx->hooks.begin_pass) {
  2209. ctx->hooks.begin_pass(pass, ctx->hooks.user_data);
  2210. }
  2211. }
  2212. _SOKOL_PRIVATE void _sgimgui_apply_viewport(int x, int y, int width, int height, bool origin_top_left, void* user_data) {
  2213. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2214. SOKOL_ASSERT(ctx);
  2215. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2216. if (item) {
  2217. item->cmd = SGIMGUI_CMD_APPLY_VIEWPORT;
  2218. item->color = _SGIMGUI_COLOR_APPLY;
  2219. item->args.apply_viewport.x = x;
  2220. item->args.apply_viewport.y = y;
  2221. item->args.apply_viewport.width = width;
  2222. item->args.apply_viewport.height = height;
  2223. item->args.apply_viewport.origin_top_left = origin_top_left;
  2224. }
  2225. if (ctx->hooks.apply_viewport) {
  2226. ctx->hooks.apply_viewport(x, y, width, height, origin_top_left, ctx->hooks.user_data);
  2227. }
  2228. }
  2229. _SOKOL_PRIVATE void _sgimgui_apply_scissor_rect(int x, int y, int width, int height, bool origin_top_left, void* user_data) {
  2230. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2231. SOKOL_ASSERT(ctx);
  2232. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2233. if (item) {
  2234. item->cmd = SGIMGUI_CMD_APPLY_SCISSOR_RECT;
  2235. item->color = _SGIMGUI_COLOR_APPLY;
  2236. item->args.apply_scissor_rect.x = x;
  2237. item->args.apply_scissor_rect.y = y;
  2238. item->args.apply_scissor_rect.width = width;
  2239. item->args.apply_scissor_rect.height = height;
  2240. item->args.apply_scissor_rect.origin_top_left = origin_top_left;
  2241. }
  2242. if (ctx->hooks.apply_scissor_rect) {
  2243. ctx->hooks.apply_scissor_rect(x, y, width, height, origin_top_left, ctx->hooks.user_data);
  2244. }
  2245. }
  2246. _SOKOL_PRIVATE void _sgimgui_apply_pipeline(sg_pipeline pip, void* user_data) {
  2247. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2248. SOKOL_ASSERT(ctx);
  2249. ctx->cur_pipeline = pip; /* stored for _sgimgui_apply_uniforms */
  2250. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2251. if (item) {
  2252. item->cmd = SGIMGUI_CMD_APPLY_PIPELINE;
  2253. item->color = _SGIMGUI_COLOR_APPLY;
  2254. item->args.apply_pipeline.pipeline = pip;
  2255. }
  2256. if (ctx->hooks.apply_pipeline) {
  2257. ctx->hooks.apply_pipeline(pip, ctx->hooks.user_data);
  2258. }
  2259. }
  2260. _SOKOL_PRIVATE void _sgimgui_apply_bindings(const sg_bindings* bindings, void* user_data) {
  2261. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2262. SOKOL_ASSERT(ctx);
  2263. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2264. if (item) {
  2265. SOKOL_ASSERT(bindings);
  2266. item->cmd = SGIMGUI_CMD_APPLY_BINDINGS;
  2267. item->color = _SGIMGUI_COLOR_APPLY;
  2268. item->args.apply_bindings.bindings = *bindings;
  2269. }
  2270. if (ctx->hooks.apply_bindings) {
  2271. ctx->hooks.apply_bindings(bindings, ctx->hooks.user_data);
  2272. }
  2273. }
  2274. _SOKOL_PRIVATE void _sgimgui_apply_uniforms(int ub_slot, const sg_range* data, void* user_data) {
  2275. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2276. SOKOL_ASSERT(ctx);
  2277. SOKOL_ASSERT(data);
  2278. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2279. if (item) {
  2280. item->cmd = SGIMGUI_CMD_APPLY_UNIFORMS;
  2281. item->color = _SGIMGUI_COLOR_APPLY;
  2282. sgimgui_args_apply_uniforms_t* args = &item->args.apply_uniforms;
  2283. args->ub_slot = ub_slot;
  2284. args->data_size = data->size;
  2285. args->pipeline = ctx->cur_pipeline;
  2286. args->ubuf_pos = _sgimgui_capture_uniforms(ctx, data);
  2287. }
  2288. if (ctx->hooks.apply_uniforms) {
  2289. ctx->hooks.apply_uniforms(ub_slot, data, ctx->hooks.user_data);
  2290. }
  2291. }
  2292. _SOKOL_PRIVATE void _sgimgui_draw(int base_element, int num_elements, int num_instances, void* user_data) {
  2293. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2294. SOKOL_ASSERT(ctx);
  2295. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2296. if (item) {
  2297. item->cmd = SGIMGUI_CMD_DRAW;
  2298. item->color = _SGIMGUI_COLOR_DRAW;
  2299. item->args.draw.base_element = base_element;
  2300. item->args.draw.num_elements = num_elements;
  2301. item->args.draw.num_instances = num_instances;
  2302. }
  2303. if (ctx->hooks.draw) {
  2304. ctx->hooks.draw(base_element, num_elements, num_instances, ctx->hooks.user_data);
  2305. }
  2306. }
  2307. _SOKOL_PRIVATE void _sgimgui_dispatch(int num_groups_x, int num_groups_y, int num_groups_z, void* user_data) {
  2308. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2309. SOKOL_ASSERT(ctx);
  2310. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2311. if (item) {
  2312. item->cmd = SGIMGUI_CMD_DISPATCH;
  2313. item->color = _SGIMGUI_COLOR_DRAW;
  2314. item->args.dispatch.num_groups_x = num_groups_x;
  2315. item->args.dispatch.num_groups_y = num_groups_y;
  2316. item->args.dispatch.num_groups_z = num_groups_z;
  2317. }
  2318. if (ctx->hooks.dispatch) {
  2319. ctx->hooks.dispatch(num_groups_x, num_groups_y, num_groups_z, ctx->hooks.user_data);
  2320. }
  2321. }
  2322. _SOKOL_PRIVATE void _sgimgui_end_pass(void* user_data) {
  2323. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2324. SOKOL_ASSERT(ctx);
  2325. ctx->cur_pipeline.id = SG_INVALID_ID;
  2326. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2327. if (item) {
  2328. item->cmd = SGIMGUI_CMD_END_PASS;
  2329. item->color = _SGIMGUI_COLOR_PASS;
  2330. }
  2331. if (ctx->hooks.end_pass) {
  2332. ctx->hooks.end_pass(ctx->hooks.user_data);
  2333. }
  2334. }
  2335. _SOKOL_PRIVATE void _sgimgui_commit(void* user_data) {
  2336. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2337. SOKOL_ASSERT(ctx);
  2338. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2339. if (item) {
  2340. item->cmd = SGIMGUI_CMD_COMMIT;
  2341. item->color = _SGIMGUI_COLOR_OTHER;
  2342. }
  2343. _sgimgui_capture_next_frame(ctx);
  2344. if (ctx->hooks.commit) {
  2345. ctx->hooks.commit(ctx->hooks.user_data);
  2346. }
  2347. }
  2348. _SOKOL_PRIVATE void _sgimgui_alloc_buffer(sg_buffer result, void* user_data) {
  2349. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2350. SOKOL_ASSERT(ctx);
  2351. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2352. if (item) {
  2353. item->cmd = SGIMGUI_CMD_ALLOC_BUFFER;
  2354. item->color = _SGIMGUI_COLOR_RSRC;
  2355. item->args.alloc_buffer.result = result;
  2356. }
  2357. if (ctx->hooks.alloc_buffer) {
  2358. ctx->hooks.alloc_buffer(result, ctx->hooks.user_data);
  2359. }
  2360. }
  2361. _SOKOL_PRIVATE void _sgimgui_alloc_image(sg_image result, void* user_data) {
  2362. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2363. SOKOL_ASSERT(ctx);
  2364. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2365. if (item) {
  2366. item->cmd = SGIMGUI_CMD_ALLOC_IMAGE;
  2367. item->color = _SGIMGUI_COLOR_RSRC;
  2368. item->args.alloc_image.result = result;
  2369. }
  2370. if (ctx->hooks.alloc_image) {
  2371. ctx->hooks.alloc_image(result, ctx->hooks.user_data);
  2372. }
  2373. }
  2374. _SOKOL_PRIVATE void _sgimgui_alloc_sampler(sg_sampler result, void* user_data) {
  2375. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2376. SOKOL_ASSERT(ctx);
  2377. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2378. if (item) {
  2379. item->cmd = SGIMGUI_CMD_ALLOC_SAMPLER;
  2380. item->color = _SGIMGUI_COLOR_RSRC;
  2381. item->args.alloc_sampler.result = result;
  2382. }
  2383. if (ctx->hooks.alloc_sampler) {
  2384. ctx->hooks.alloc_sampler(result, ctx->hooks.user_data);
  2385. }
  2386. }
  2387. _SOKOL_PRIVATE void _sgimgui_alloc_shader(sg_shader result, void* user_data) {
  2388. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2389. SOKOL_ASSERT(ctx);
  2390. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2391. if (item) {
  2392. item->cmd = SGIMGUI_CMD_ALLOC_SHADER;
  2393. item->color = _SGIMGUI_COLOR_RSRC;
  2394. item->args.alloc_shader.result = result;
  2395. }
  2396. if (ctx->hooks.alloc_shader) {
  2397. ctx->hooks.alloc_shader(result, ctx->hooks.user_data);
  2398. }
  2399. }
  2400. _SOKOL_PRIVATE void _sgimgui_alloc_pipeline(sg_pipeline result, void* user_data) {
  2401. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2402. SOKOL_ASSERT(ctx);
  2403. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2404. if (item) {
  2405. item->cmd = SGIMGUI_CMD_ALLOC_PIPELINE;
  2406. item->color = _SGIMGUI_COLOR_RSRC;
  2407. item->args.alloc_pipeline.result = result;
  2408. }
  2409. if (ctx->hooks.alloc_pipeline) {
  2410. ctx->hooks.alloc_pipeline(result, ctx->hooks.user_data);
  2411. }
  2412. }
  2413. _SOKOL_PRIVATE void _sgimgui_alloc_attachments(sg_attachments result, void* user_data) {
  2414. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2415. SOKOL_ASSERT(ctx);
  2416. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2417. if (item) {
  2418. item->cmd = SGIMGUI_CMD_ALLOC_ATTACHMENTS;
  2419. item->color = _SGIMGUI_COLOR_RSRC;
  2420. item->args.alloc_attachments.result = result;
  2421. }
  2422. if (ctx->hooks.alloc_attachments) {
  2423. ctx->hooks.alloc_attachments(result, ctx->hooks.user_data);
  2424. }
  2425. }
  2426. _SOKOL_PRIVATE void _sgimgui_dealloc_buffer(sg_buffer buf_id, void* user_data) {
  2427. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2428. SOKOL_ASSERT(ctx);
  2429. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2430. if (item) {
  2431. item->cmd = SGIMGUI_CMD_DEALLOC_BUFFER;
  2432. item->color = _SGIMGUI_COLOR_RSRC;
  2433. item->args.dealloc_buffer.buffer = buf_id;
  2434. }
  2435. if (ctx->hooks.dealloc_buffer) {
  2436. ctx->hooks.dealloc_buffer(buf_id, ctx->hooks.user_data);
  2437. }
  2438. }
  2439. _SOKOL_PRIVATE void _sgimgui_dealloc_image(sg_image img_id, void* user_data) {
  2440. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2441. SOKOL_ASSERT(ctx);
  2442. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2443. if (item) {
  2444. item->cmd = SGIMGUI_CMD_DEALLOC_IMAGE;
  2445. item->color = _SGIMGUI_COLOR_RSRC;
  2446. item->args.dealloc_image.image = img_id;
  2447. }
  2448. if (ctx->hooks.dealloc_image) {
  2449. ctx->hooks.dealloc_image(img_id, ctx->hooks.user_data);
  2450. }
  2451. }
  2452. _SOKOL_PRIVATE void _sgimgui_dealloc_sampler(sg_sampler smp_id, void* user_data) {
  2453. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2454. SOKOL_ASSERT(ctx);
  2455. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2456. if (item) {
  2457. item->cmd = SGIMGUI_CMD_DEALLOC_SAMPLER;
  2458. item->color = _SGIMGUI_COLOR_RSRC;
  2459. item->args.dealloc_sampler.sampler = smp_id;
  2460. }
  2461. if (ctx->hooks.dealloc_sampler) {
  2462. ctx->hooks.dealloc_sampler(smp_id, ctx->hooks.user_data);
  2463. }
  2464. }
  2465. _SOKOL_PRIVATE void _sgimgui_dealloc_shader(sg_shader shd_id, void* user_data) {
  2466. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2467. SOKOL_ASSERT(ctx);
  2468. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2469. if (item) {
  2470. item->cmd = SGIMGUI_CMD_DEALLOC_SHADER;
  2471. item->color = _SGIMGUI_COLOR_RSRC;
  2472. item->args.dealloc_shader.shader = shd_id;
  2473. }
  2474. if (ctx->hooks.dealloc_shader) {
  2475. ctx->hooks.dealloc_shader(shd_id, ctx->hooks.user_data);
  2476. }
  2477. }
  2478. _SOKOL_PRIVATE void _sgimgui_dealloc_pipeline(sg_pipeline pip_id, void* user_data) {
  2479. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2480. SOKOL_ASSERT(ctx);
  2481. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2482. if (item) {
  2483. item->cmd = SGIMGUI_CMD_DEALLOC_PIPELINE;
  2484. item->color = _SGIMGUI_COLOR_RSRC;
  2485. item->args.dealloc_pipeline.pipeline = pip_id;
  2486. }
  2487. if (ctx->hooks.dealloc_pipeline) {
  2488. ctx->hooks.dealloc_pipeline(pip_id, ctx->hooks.user_data);
  2489. }
  2490. }
  2491. _SOKOL_PRIVATE void _sgimgui_dealloc_attachments(sg_attachments atts_id, void* user_data) {
  2492. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2493. SOKOL_ASSERT(ctx);
  2494. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2495. if (item) {
  2496. item->cmd = SGIMGUI_CMD_DEALLOC_ATTACHMENTS;
  2497. item->color = _SGIMGUI_COLOR_RSRC;
  2498. item->args.dealloc_attachments.attachments = atts_id;
  2499. }
  2500. if (ctx->hooks.dealloc_attachments) {
  2501. ctx->hooks.dealloc_attachments(atts_id, ctx->hooks.user_data);
  2502. }
  2503. }
  2504. _SOKOL_PRIVATE void _sgimgui_init_buffer(sg_buffer buf_id, const sg_buffer_desc* desc, void* user_data) {
  2505. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2506. SOKOL_ASSERT(ctx);
  2507. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2508. if (item) {
  2509. item->cmd = SGIMGUI_CMD_INIT_BUFFER;
  2510. item->color = _SGIMGUI_COLOR_RSRC;
  2511. item->args.init_buffer.buffer = buf_id;
  2512. }
  2513. if (ctx->hooks.init_buffer) {
  2514. ctx->hooks.init_buffer(buf_id, desc, ctx->hooks.user_data);
  2515. }
  2516. if (buf_id.id != SG_INVALID_ID) {
  2517. _sgimgui_buffer_created(ctx, buf_id, _sgimgui_slot_index(buf_id.id), desc);
  2518. }
  2519. }
  2520. _SOKOL_PRIVATE void _sgimgui_init_image(sg_image img_id, const sg_image_desc* desc, void* user_data) {
  2521. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2522. SOKOL_ASSERT(ctx);
  2523. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2524. if (item) {
  2525. item->cmd = SGIMGUI_CMD_INIT_IMAGE;
  2526. item->color = _SGIMGUI_COLOR_RSRC;
  2527. item->args.init_image.image = img_id;
  2528. }
  2529. if (ctx->hooks.init_image) {
  2530. ctx->hooks.init_image(img_id, desc, ctx->hooks.user_data);
  2531. }
  2532. if (img_id.id != SG_INVALID_ID) {
  2533. _sgimgui_image_created(ctx, img_id, _sgimgui_slot_index(img_id.id), desc);
  2534. }
  2535. }
  2536. _SOKOL_PRIVATE void _sgimgui_init_sampler(sg_sampler smp_id, const sg_sampler_desc* desc, void* user_data) {
  2537. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2538. SOKOL_ASSERT(ctx);
  2539. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2540. if (item) {
  2541. item->cmd = SGIMGUI_CMD_INIT_SAMPLER;
  2542. item->color = _SGIMGUI_COLOR_RSRC;
  2543. item->args.init_sampler.sampler = smp_id;
  2544. }
  2545. if (ctx->hooks.init_sampler) {
  2546. ctx->hooks.init_sampler(smp_id, desc, ctx->hooks.user_data);
  2547. }
  2548. if (smp_id.id != SG_INVALID_ID) {
  2549. _sgimgui_sampler_created(ctx, smp_id, _sgimgui_slot_index(smp_id.id), desc);
  2550. }
  2551. }
  2552. _SOKOL_PRIVATE void _sgimgui_init_shader(sg_shader shd_id, const sg_shader_desc* desc, void* user_data) {
  2553. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2554. SOKOL_ASSERT(ctx);
  2555. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2556. if (item) {
  2557. item->cmd = SGIMGUI_CMD_INIT_SHADER;
  2558. item->color = _SGIMGUI_COLOR_RSRC;
  2559. item->args.init_shader.shader = shd_id;
  2560. }
  2561. if (ctx->hooks.init_shader) {
  2562. ctx->hooks.init_shader(shd_id, desc, ctx->hooks.user_data);
  2563. }
  2564. if (shd_id.id != SG_INVALID_ID) {
  2565. _sgimgui_shader_created(ctx, shd_id, _sgimgui_slot_index(shd_id.id), desc);
  2566. }
  2567. }
  2568. _SOKOL_PRIVATE void _sgimgui_init_pipeline(sg_pipeline pip_id, const sg_pipeline_desc* desc, void* user_data) {
  2569. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2570. SOKOL_ASSERT(ctx);
  2571. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2572. if (item) {
  2573. item->cmd = SGIMGUI_CMD_INIT_PIPELINE;
  2574. item->color = _SGIMGUI_COLOR_RSRC;
  2575. item->args.init_pipeline.pipeline = pip_id;
  2576. }
  2577. if (ctx->hooks.init_pipeline) {
  2578. ctx->hooks.init_pipeline(pip_id, desc, ctx->hooks.user_data);
  2579. }
  2580. if (pip_id.id != SG_INVALID_ID) {
  2581. _sgimgui_pipeline_created(ctx, pip_id, _sgimgui_slot_index(pip_id.id), desc);
  2582. }
  2583. }
  2584. _SOKOL_PRIVATE void _sgimgui_init_attachments(sg_attachments atts_id, const sg_attachments_desc* desc, void* user_data) {
  2585. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2586. SOKOL_ASSERT(ctx);
  2587. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2588. if (item) {
  2589. item->cmd = SGIMGUI_CMD_INIT_ATTACHMENTS;
  2590. item->color = _SGIMGUI_COLOR_RSRC;
  2591. item->args.init_attachments.attachments = atts_id;
  2592. }
  2593. if (ctx->hooks.init_attachments) {
  2594. ctx->hooks.init_attachments(atts_id, desc, ctx->hooks.user_data);
  2595. }
  2596. if (atts_id.id != SG_INVALID_ID) {
  2597. _sgimgui_attachments_created(ctx, atts_id, _sgimgui_slot_index(atts_id.id), desc);
  2598. }
  2599. }
  2600. _SOKOL_PRIVATE void _sgimgui_uninit_buffer(sg_buffer buf, void* user_data) {
  2601. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2602. SOKOL_ASSERT(ctx);
  2603. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2604. if (item) {
  2605. item->cmd = SGIMGUI_CMD_UNINIT_BUFFER;
  2606. item->color = _SGIMGUI_COLOR_RSRC;
  2607. item->args.uninit_buffer.buffer = buf;
  2608. }
  2609. if (ctx->hooks.uninit_buffer) {
  2610. ctx->hooks.uninit_buffer(buf, ctx->hooks.user_data);
  2611. }
  2612. if (buf.id != SG_INVALID_ID) {
  2613. _sgimgui_buffer_destroyed(ctx, _sgimgui_slot_index(buf.id));
  2614. }
  2615. }
  2616. _SOKOL_PRIVATE void _sgimgui_uninit_image(sg_image img, void* user_data) {
  2617. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2618. SOKOL_ASSERT(ctx);
  2619. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2620. if (item) {
  2621. item->cmd = SGIMGUI_CMD_UNINIT_IMAGE;
  2622. item->color = _SGIMGUI_COLOR_RSRC;
  2623. item->args.uninit_image.image = img;
  2624. }
  2625. if (ctx->hooks.uninit_image) {
  2626. ctx->hooks.uninit_image(img, ctx->hooks.user_data);
  2627. }
  2628. if (img.id != SG_INVALID_ID) {
  2629. _sgimgui_image_destroyed(ctx, _sgimgui_slot_index(img.id));
  2630. }
  2631. }
  2632. _SOKOL_PRIVATE void _sgimgui_uninit_sampler(sg_sampler smp, void* user_data) {
  2633. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2634. SOKOL_ASSERT(ctx);
  2635. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2636. if (item) {
  2637. item->cmd = SGIMGUI_CMD_UNINIT_SAMPLER;
  2638. item->color = _SGIMGUI_COLOR_RSRC;
  2639. item->args.uninit_sampler.sampler = smp;
  2640. }
  2641. if (ctx->hooks.uninit_sampler) {
  2642. ctx->hooks.uninit_sampler(smp, ctx->hooks.user_data);
  2643. }
  2644. if (smp.id != SG_INVALID_ID) {
  2645. _sgimgui_sampler_destroyed(ctx, _sgimgui_slot_index(smp.id));
  2646. }
  2647. }
  2648. _SOKOL_PRIVATE void _sgimgui_uninit_shader(sg_shader shd, void* user_data) {
  2649. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2650. SOKOL_ASSERT(ctx);
  2651. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2652. if (item) {
  2653. item->cmd = SGIMGUI_CMD_UNINIT_SHADER;
  2654. item->color = _SGIMGUI_COLOR_RSRC;
  2655. item->args.uninit_shader.shader = shd;
  2656. }
  2657. if (ctx->hooks.uninit_shader) {
  2658. ctx->hooks.uninit_shader(shd, ctx->hooks.user_data);
  2659. }
  2660. if (shd.id != SG_INVALID_ID) {
  2661. _sgimgui_shader_destroyed(ctx, _sgimgui_slot_index(shd.id));
  2662. }
  2663. }
  2664. _SOKOL_PRIVATE void _sgimgui_uninit_pipeline(sg_pipeline pip, void* user_data) {
  2665. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2666. SOKOL_ASSERT(ctx);
  2667. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2668. if (item) {
  2669. item->cmd = SGIMGUI_CMD_UNINIT_PIPELINE;
  2670. item->color = _SGIMGUI_COLOR_RSRC;
  2671. item->args.uninit_pipeline.pipeline = pip;
  2672. }
  2673. if (ctx->hooks.uninit_pipeline) {
  2674. ctx->hooks.uninit_pipeline(pip, ctx->hooks.user_data);
  2675. }
  2676. if (pip.id != SG_INVALID_ID) {
  2677. _sgimgui_pipeline_destroyed(ctx, _sgimgui_slot_index(pip.id));
  2678. }
  2679. }
  2680. _SOKOL_PRIVATE void _sgimgui_uninit_attachments(sg_attachments atts, void* user_data) {
  2681. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2682. SOKOL_ASSERT(ctx);
  2683. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2684. if (item) {
  2685. item->cmd = SGIMGUI_CMD_UNINIT_PIPELINE;
  2686. item->color = _SGIMGUI_COLOR_RSRC;
  2687. item->args.uninit_attachments.attachments = atts;
  2688. }
  2689. if (ctx->hooks.uninit_attachments) {
  2690. ctx->hooks.uninit_attachments(atts, ctx->hooks.user_data);
  2691. }
  2692. if (atts.id != SG_INVALID_ID) {
  2693. _sgimgui_attachments_destroyed(ctx, _sgimgui_slot_index(atts.id));
  2694. }
  2695. }
  2696. _SOKOL_PRIVATE void _sgimgui_fail_buffer(sg_buffer buf_id, void* user_data) {
  2697. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2698. SOKOL_ASSERT(ctx);
  2699. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2700. if (item) {
  2701. item->cmd = SGIMGUI_CMD_FAIL_BUFFER;
  2702. item->color = _SGIMGUI_COLOR_RSRC;
  2703. item->args.fail_buffer.buffer = buf_id;
  2704. }
  2705. if (ctx->hooks.fail_buffer) {
  2706. ctx->hooks.fail_buffer(buf_id, ctx->hooks.user_data);
  2707. }
  2708. }
  2709. _SOKOL_PRIVATE void _sgimgui_fail_image(sg_image img_id, void* user_data) {
  2710. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2711. SOKOL_ASSERT(ctx);
  2712. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2713. if (item) {
  2714. item->cmd = SGIMGUI_CMD_FAIL_IMAGE;
  2715. item->color = _SGIMGUI_COLOR_RSRC;
  2716. item->args.fail_image.image = img_id;
  2717. }
  2718. if (ctx->hooks.fail_image) {
  2719. ctx->hooks.fail_image(img_id, ctx->hooks.user_data);
  2720. }
  2721. }
  2722. _SOKOL_PRIVATE void _sgimgui_fail_sampler(sg_sampler smp_id, void* user_data) {
  2723. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2724. SOKOL_ASSERT(ctx);
  2725. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2726. if (item) {
  2727. item->cmd = SGIMGUI_CMD_FAIL_SAMPLER;
  2728. item->color = _SGIMGUI_COLOR_RSRC;
  2729. item->args.fail_sampler.sampler = smp_id;
  2730. }
  2731. if (ctx->hooks.fail_sampler) {
  2732. ctx->hooks.fail_sampler(smp_id, ctx->hooks.user_data);
  2733. }
  2734. }
  2735. _SOKOL_PRIVATE void _sgimgui_fail_shader(sg_shader shd_id, void* user_data) {
  2736. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2737. SOKOL_ASSERT(ctx);
  2738. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2739. if (item) {
  2740. item->cmd = SGIMGUI_CMD_FAIL_SHADER;
  2741. item->color = _SGIMGUI_COLOR_RSRC;
  2742. item->args.fail_shader.shader = shd_id;
  2743. }
  2744. if (ctx->hooks.fail_shader) {
  2745. ctx->hooks.fail_shader(shd_id, ctx->hooks.user_data);
  2746. }
  2747. }
  2748. _SOKOL_PRIVATE void _sgimgui_fail_pipeline(sg_pipeline pip_id, void* user_data) {
  2749. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2750. SOKOL_ASSERT(ctx);
  2751. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2752. if (item) {
  2753. item->cmd = SGIMGUI_CMD_FAIL_PIPELINE;
  2754. item->color = _SGIMGUI_COLOR_RSRC;
  2755. item->args.fail_pipeline.pipeline = pip_id;
  2756. }
  2757. if (ctx->hooks.fail_pipeline) {
  2758. ctx->hooks.fail_pipeline(pip_id, ctx->hooks.user_data);
  2759. }
  2760. }
  2761. _SOKOL_PRIVATE void _sgimgui_fail_attachments(sg_attachments atts_id, void* user_data) {
  2762. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2763. SOKOL_ASSERT(ctx);
  2764. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2765. if (item) {
  2766. item->cmd = SGIMGUI_CMD_FAIL_ATTACHMENTS;
  2767. item->color = _SGIMGUI_COLOR_RSRC;
  2768. item->args.fail_attachments.attachments = atts_id;
  2769. }
  2770. if (ctx->hooks.fail_attachments) {
  2771. ctx->hooks.fail_attachments(atts_id, ctx->hooks.user_data);
  2772. }
  2773. }
  2774. _SOKOL_PRIVATE void _sgimgui_push_debug_group(const char* name, void* user_data) {
  2775. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2776. SOKOL_ASSERT(ctx);
  2777. if (0 == strcmp(name, "sokol-imgui")) {
  2778. ctx->frame_stats_window.in_sokol_imgui = true;
  2779. if (ctx->frame_stats_window.disable_sokol_imgui_stats) {
  2780. sg_disable_frame_stats();
  2781. }
  2782. }
  2783. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2784. if (item) {
  2785. item->cmd = SGIMGUI_CMD_PUSH_DEBUG_GROUP;
  2786. item->color = _SGIMGUI_COLOR_OTHER;
  2787. item->args.push_debug_group.name = _sgimgui_make_str(name);
  2788. }
  2789. if (ctx->hooks.push_debug_group) {
  2790. ctx->hooks.push_debug_group(name, ctx->hooks.user_data);
  2791. }
  2792. }
  2793. _SOKOL_PRIVATE void _sgimgui_pop_debug_group(void* user_data) {
  2794. sgimgui_t* ctx = (sgimgui_t*) user_data;
  2795. SOKOL_ASSERT(ctx);
  2796. if (ctx->frame_stats_window.in_sokol_imgui) {
  2797. ctx->frame_stats_window.in_sokol_imgui = false;
  2798. if (ctx->frame_stats_window.disable_sokol_imgui_stats) {
  2799. sg_enable_frame_stats();
  2800. }
  2801. }
  2802. sgimgui_capture_item_t* item = _sgimgui_capture_next_write_item(ctx);
  2803. if (item) {
  2804. item->cmd = SGIMGUI_CMD_POP_DEBUG_GROUP;
  2805. item->color = _SGIMGUI_COLOR_OTHER;
  2806. }
  2807. if (ctx->hooks.pop_debug_group) {
  2808. ctx->hooks.pop_debug_group(ctx->hooks.user_data);
  2809. }
  2810. }
  2811. /*--- IMGUI HELPERS ----------------------------------------------------------*/
  2812. _SOKOL_PRIVATE bool _sgimgui_draw_resid_list_item(uint32_t res_id, const char* label, bool selected) {
  2813. igPushIDInt((int)res_id);
  2814. bool res;
  2815. if (label[0]) {
  2816. res = igSelectableEx(label, selected, 0, IMVEC2(0,0));
  2817. } else {
  2818. sgimgui_str_t str;
  2819. _sgimgui_snprintf(&str, "0x%08X", res_id);
  2820. res = igSelectableEx(str.buf, selected, 0, IMVEC2(0,0));
  2821. }
  2822. igPopID();
  2823. return res;
  2824. }
  2825. _SOKOL_PRIVATE bool _sgimgui_draw_resid_link(uint32_t res_type, uint32_t res_id, const char* label) {
  2826. SOKOL_ASSERT(label);
  2827. sgimgui_str_t str_buf;
  2828. const char* str;
  2829. if (label[0]) {
  2830. str = label;
  2831. } else {
  2832. _sgimgui_snprintf(&str_buf, "0x%08X", res_id);
  2833. str = str_buf.buf;
  2834. }
  2835. igPushIDInt((int)((res_type<<24)|res_id));
  2836. bool res = igSmallButton(str);
  2837. igPopID();
  2838. return res;
  2839. }
  2840. _SOKOL_PRIVATE bool _sgimgui_draw_buffer_link(sgimgui_t* ctx, sg_buffer buf) {
  2841. bool retval = false;
  2842. if (buf.id != SG_INVALID_ID) {
  2843. const sgimgui_buffer_t* buf_ui = &ctx->buffer_window.slots[_sgimgui_slot_index(buf.id)];
  2844. retval = _sgimgui_draw_resid_link(1, buf.id, buf_ui->label.buf);
  2845. }
  2846. return retval;
  2847. }
  2848. _SOKOL_PRIVATE bool _sgimgui_draw_image_link(sgimgui_t* ctx, sg_image img) {
  2849. bool retval = false;
  2850. if (img.id != SG_INVALID_ID) {
  2851. const sgimgui_image_t* img_ui = &ctx->image_window.slots[_sgimgui_slot_index(img.id)];
  2852. retval = _sgimgui_draw_resid_link(2, img.id, img_ui->label.buf);
  2853. }
  2854. return retval;
  2855. }
  2856. _SOKOL_PRIVATE bool _sgimgui_draw_sampler_link(sgimgui_t* ctx, sg_sampler smp) {
  2857. bool retval = false;
  2858. if (smp.id != SG_INVALID_ID) {
  2859. const sgimgui_sampler_t* smp_ui = &ctx->sampler_window.slots[_sgimgui_slot_index(smp.id)];
  2860. retval = _sgimgui_draw_resid_link(2, smp.id, smp_ui->label.buf);
  2861. }
  2862. return retval;
  2863. }
  2864. _SOKOL_PRIVATE bool _sgimgui_draw_shader_link(sgimgui_t* ctx, sg_shader shd) {
  2865. bool retval = false;
  2866. if (shd.id != SG_INVALID_ID) {
  2867. const sgimgui_shader_t* shd_ui = &ctx->shader_window.slots[_sgimgui_slot_index(shd.id)];
  2868. retval = _sgimgui_draw_resid_link(3, shd.id, shd_ui->label.buf);
  2869. }
  2870. return retval;
  2871. }
  2872. _SOKOL_PRIVATE void _sgimgui_show_buffer(sgimgui_t* ctx, sg_buffer buf) {
  2873. ctx->buffer_window.open = true;
  2874. ctx->buffer_window.sel_buf = buf;
  2875. }
  2876. _SOKOL_PRIVATE void _sgimgui_show_image(sgimgui_t* ctx, sg_image img) {
  2877. ctx->image_window.open = true;
  2878. ctx->image_window.sel_img = img;
  2879. }
  2880. _SOKOL_PRIVATE void _sgimgui_show_sampler(sgimgui_t* ctx, sg_sampler smp) {
  2881. ctx->sampler_window.open = true;
  2882. ctx->sampler_window.sel_smp = smp;
  2883. }
  2884. _SOKOL_PRIVATE void _sgimgui_show_shader(sgimgui_t* ctx, sg_shader shd) {
  2885. ctx->shader_window.open = true;
  2886. ctx->shader_window.sel_shd = shd;
  2887. }
  2888. _SOKOL_PRIVATE void _sgimgui_draw_buffer_list(sgimgui_t* ctx) {
  2889. igBeginChild("buffer_list", IMVEC2(_SGIMGUI_LIST_WIDTH,0), true, 0);
  2890. for (int i = 0; i < ctx->buffer_window.num_slots; i++) {
  2891. sg_buffer buf = ctx->buffer_window.slots[i].res_id;
  2892. sg_resource_state state = sg_query_buffer_state(buf);
  2893. if ((state != SG_RESOURCESTATE_INVALID) && (state != SG_RESOURCESTATE_INITIAL)) {
  2894. bool selected = ctx->buffer_window.sel_buf.id == buf.id;
  2895. if (_sgimgui_draw_resid_list_item(buf.id, ctx->buffer_window.slots[i].label.buf, selected)) {
  2896. ctx->buffer_window.sel_buf.id = buf.id;
  2897. }
  2898. }
  2899. }
  2900. igEndChild();
  2901. }
  2902. _SOKOL_PRIVATE void _sgimgui_draw_image_list(sgimgui_t* ctx) {
  2903. igBeginChild("image_list", IMVEC2(_SGIMGUI_LIST_WIDTH,0), true, 0);
  2904. for (int i = 0; i < ctx->image_window.num_slots; i++) {
  2905. sg_image img = ctx->image_window.slots[i].res_id;
  2906. sg_resource_state state = sg_query_image_state(img);
  2907. if ((state != SG_RESOURCESTATE_INVALID) && (state != SG_RESOURCESTATE_INITIAL)) {
  2908. bool selected = ctx->image_window.sel_img.id == img.id;
  2909. if (_sgimgui_draw_resid_list_item(img.id, ctx->image_window.slots[i].label.buf, selected)) {
  2910. ctx->image_window.sel_img.id = img.id;
  2911. }
  2912. }
  2913. }
  2914. igEndChild();
  2915. }
  2916. _SOKOL_PRIVATE void _sgimgui_draw_sampler_list(sgimgui_t* ctx) {
  2917. igBeginChild("sampler_list", IMVEC2(_SGIMGUI_LIST_WIDTH,0), true, 0);
  2918. for (int i = 0; i < ctx->sampler_window.num_slots; i++) {
  2919. sg_sampler smp = ctx->sampler_window.slots[i].res_id;
  2920. sg_resource_state state = sg_query_sampler_state(smp);
  2921. if ((state != SG_RESOURCESTATE_INVALID) && (state != SG_RESOURCESTATE_INITIAL)) {
  2922. bool selected = ctx->sampler_window.sel_smp.id == smp.id;
  2923. if (_sgimgui_draw_resid_list_item(smp.id, ctx->sampler_window.slots[i].label.buf, selected)) {
  2924. ctx->sampler_window.sel_smp.id = smp.id;
  2925. }
  2926. }
  2927. }
  2928. igEndChild();
  2929. }
  2930. _SOKOL_PRIVATE void _sgimgui_draw_shader_list(sgimgui_t* ctx) {
  2931. igBeginChild("shader_list", IMVEC2(_SGIMGUI_LIST_WIDTH,0), true, 0);
  2932. for (int i = 0; i < ctx->shader_window.num_slots; i++) {
  2933. sg_shader shd = ctx->shader_window.slots[i].res_id;
  2934. sg_resource_state state = sg_query_shader_state(shd);
  2935. if ((state != SG_RESOURCESTATE_INVALID) && (state != SG_RESOURCESTATE_INITIAL)) {
  2936. bool selected = ctx->shader_window.sel_shd.id == shd.id;
  2937. if (_sgimgui_draw_resid_list_item(shd.id, ctx->shader_window.slots[i].label.buf, selected)) {
  2938. ctx->shader_window.sel_shd.id = shd.id;
  2939. }
  2940. }
  2941. }
  2942. igEndChild();
  2943. }
  2944. _SOKOL_PRIVATE void _sgimgui_draw_pipeline_list(sgimgui_t* ctx) {
  2945. igBeginChild("pipeline_list", IMVEC2(_SGIMGUI_LIST_WIDTH,0), true, 0);
  2946. for (int i = 1; i < ctx->pipeline_window.num_slots; i++) {
  2947. sg_pipeline pip = ctx->pipeline_window.slots[i].res_id;
  2948. sg_resource_state state = sg_query_pipeline_state(pip);
  2949. if ((state != SG_RESOURCESTATE_INVALID) && (state != SG_RESOURCESTATE_INITIAL)) {
  2950. bool selected = ctx->pipeline_window.sel_pip.id == pip.id;
  2951. if (_sgimgui_draw_resid_list_item(pip.id, ctx->pipeline_window.slots[i].label.buf, selected)) {
  2952. ctx->pipeline_window.sel_pip.id = pip.id;
  2953. }
  2954. }
  2955. }
  2956. igEndChild();
  2957. }
  2958. _SOKOL_PRIVATE void _sgimgui_draw_attachments_list(sgimgui_t* ctx) {
  2959. igBeginChild("pass_list", IMVEC2(_SGIMGUI_LIST_WIDTH,0), true, 0);
  2960. for (int i = 1; i < ctx->attachments_window.num_slots; i++) {
  2961. sg_attachments atts = ctx->attachments_window.slots[i].res_id;
  2962. sg_resource_state state = sg_query_attachments_state(atts);
  2963. if ((state != SG_RESOURCESTATE_INVALID) && (state != SG_RESOURCESTATE_INITIAL)) {
  2964. bool selected = ctx->attachments_window.sel_atts.id == atts.id;
  2965. if (_sgimgui_draw_resid_list_item(atts.id, ctx->attachments_window.slots[i].label.buf, selected)) {
  2966. ctx->attachments_window.sel_atts.id = atts.id;
  2967. }
  2968. }
  2969. }
  2970. igEndChild();
  2971. }
  2972. _SOKOL_PRIVATE void _sgimgui_draw_capture_list(sgimgui_t* ctx) {
  2973. igBeginChild("capture_list", IMVEC2(_SGIMGUI_LIST_WIDTH,0), true, 0);
  2974. const int num_items = _sgimgui_capture_num_read_items(ctx);
  2975. uint64_t group_stack = 1; /* bit set: group unfolded, cleared: folded */
  2976. for (int i = 0; i < num_items; i++) {
  2977. const sgimgui_capture_item_t* item = _sgimgui_capture_read_item_at(ctx, i);
  2978. sgimgui_str_t item_string = _sgimgui_capture_item_string(ctx, i, item);
  2979. igPushStyleColor(ImGuiCol_Text, item->color);
  2980. igPushIDInt(i);
  2981. if (item->cmd == SGIMGUI_CMD_PUSH_DEBUG_GROUP) {
  2982. if (group_stack & 1) {
  2983. group_stack <<= 1;
  2984. const char* group_name = item->args.push_debug_group.name.buf;
  2985. if (igTreeNodeStr(group_name, "Group: %s", group_name)) {
  2986. group_stack |= 1;
  2987. }
  2988. } else {
  2989. group_stack <<= 1;
  2990. }
  2991. } else if (item->cmd == SGIMGUI_CMD_POP_DEBUG_GROUP) {
  2992. if (group_stack & 1) {
  2993. igTreePop();
  2994. }
  2995. group_stack >>= 1;
  2996. } else if (group_stack & 1) {
  2997. if (igSelectableEx(item_string.buf, ctx->capture_window.sel_item == i, 0, IMVEC2(0,0))) {
  2998. ctx->capture_window.sel_item = i;
  2999. }
  3000. if (igIsItemHovered(0)) {
  3001. igSetTooltip("%s", item_string.buf);
  3002. }
  3003. }
  3004. igPopID();
  3005. igPopStyleColor();
  3006. }
  3007. igEndChild();
  3008. }
  3009. _SOKOL_PRIVATE void _sgimgui_draw_buffer_panel(sgimgui_t* ctx, sg_buffer buf) {
  3010. if (buf.id != SG_INVALID_ID) {
  3011. igBeginChild("buffer", IMVEC2(0,0), false, 0);
  3012. sg_buffer_info info = sg_query_buffer_info(buf);
  3013. if (info.slot.state == SG_RESOURCESTATE_VALID) {
  3014. const sgimgui_buffer_t* buf_ui = &ctx->buffer_window.slots[_sgimgui_slot_index(buf.id)];
  3015. igText("Label: %s", buf_ui->label.buf[0] ? buf_ui->label.buf : "---");
  3016. _sgimgui_draw_resource_slot(&info.slot);
  3017. igSeparator();
  3018. igText("Usage:\n");
  3019. igText(" vertex_buffer: %s", _sgimgui_bool_string(buf_ui->desc.usage.vertex_buffer));
  3020. igText(" index_buffer: %s", _sgimgui_bool_string(buf_ui->desc.usage.index_buffer));
  3021. igText(" storage_buffer: %s", _sgimgui_bool_string(buf_ui->desc.usage.storage_buffer));
  3022. igText(" immutable: %s", _sgimgui_bool_string(buf_ui->desc.usage.immutable));
  3023. igText(" dynamic_update: %s", _sgimgui_bool_string(buf_ui->desc.usage.dynamic_update));
  3024. igText(" stream_update: %s", _sgimgui_bool_string(buf_ui->desc.usage.stream_update));
  3025. igText("Size: %d", (int)buf_ui->desc.size);
  3026. if (!buf_ui->desc.usage.immutable) {
  3027. igSeparator();
  3028. igText("Num Slots: %d", info.num_slots);
  3029. igText("Active Slot: %d", info.active_slot);
  3030. igText("Update Frame Index: %d", info.update_frame_index);
  3031. igText("Append Frame Index: %d", info.append_frame_index);
  3032. igText("Append Pos: %d", info.append_pos);
  3033. igText("Append Overflow: %s", _sgimgui_bool_string(info.append_overflow));
  3034. }
  3035. } else {
  3036. igText("Buffer 0x%08X not valid.", buf.id);
  3037. }
  3038. igEndChild();
  3039. }
  3040. }
  3041. _SOKOL_PRIVATE bool _sgimgui_image_renderable(sg_image_type type, sg_pixel_format fmt, int sample_count) {
  3042. return (type == SG_IMAGETYPE_2D)
  3043. && sg_query_pixelformat(fmt).sample
  3044. && sample_count == 1;
  3045. }
  3046. _SOKOL_PRIVATE void _sgimgui_draw_embedded_image(sgimgui_t* ctx, sg_image img, float* scale) {
  3047. if (sg_query_image_state(img) == SG_RESOURCESTATE_VALID) {
  3048. sgimgui_image_t* img_ui = &ctx->image_window.slots[_sgimgui_slot_index(img.id)];
  3049. if (_sgimgui_image_renderable(img_ui->desc.type, img_ui->desc.pixel_format, img_ui->desc.sample_count)) {
  3050. igPushIDInt((int)img.id);
  3051. igSliderFloatEx("Scale", scale, 0.125f, 8.0f, "%.3f", ImGuiSliderFlags_Logarithmic);
  3052. float w = (float)img_ui->desc.width * (*scale);
  3053. float h = (float)img_ui->desc.height * (*scale);
  3054. _sgimgui_igimage(simgui_imtextureid(img_ui->res_id), IMVEC2(w, h));
  3055. igPopID();
  3056. } else {
  3057. igText("Image not renderable.");
  3058. }
  3059. }
  3060. }
  3061. _SOKOL_PRIVATE void _sgimgui_draw_image_panel(sgimgui_t* ctx, sg_image img) {
  3062. if (img.id != SG_INVALID_ID) {
  3063. igBeginChild("image", IMVEC2(0,0), false, 0);
  3064. sg_image_info info = sg_query_image_info(img);
  3065. if (info.slot.state == SG_RESOURCESTATE_VALID) {
  3066. sgimgui_image_t* img_ui = &ctx->image_window.slots[_sgimgui_slot_index(img.id)];
  3067. const sg_image_desc* desc = &img_ui->desc;
  3068. igText("Label: %s", img_ui->label.buf[0] ? img_ui->label.buf : "---");
  3069. _sgimgui_draw_resource_slot(&info.slot);
  3070. igSeparator();
  3071. _sgimgui_draw_embedded_image(ctx, img, &img_ui->ui_scale);
  3072. igSeparator();
  3073. igText("Type: %s", _sgimgui_imagetype_string(desc->type));
  3074. igText("Usage:\n");
  3075. igText(" render_attachment: %s", _sgimgui_bool_string(desc->usage.render_attachment));
  3076. igText(" storage_attachment: %s", _sgimgui_bool_string(desc->usage.storage_attachment));
  3077. igText(" immutable: %s", _sgimgui_bool_string(desc->usage.immutable));
  3078. igText(" dynamic_update: %s", _sgimgui_bool_string(desc->usage.dynamic_update));
  3079. igText(" stream_update: %s", _sgimgui_bool_string(desc->usage.stream_update));
  3080. igText("Width: %d", desc->width);
  3081. igText("Height: %d", desc->height);
  3082. igText("Num Slices: %d", desc->num_slices);
  3083. igText("Num Mipmaps: %d", desc->num_mipmaps);
  3084. igText("Pixel Format: %s", _sgimgui_pixelformat_string(desc->pixel_format));
  3085. igText("Sample Count: %d", desc->sample_count);
  3086. if (!desc->usage.immutable) {
  3087. igSeparator();
  3088. igText("Num Slots: %d", info.num_slots);
  3089. igText("Active Slot: %d", info.active_slot);
  3090. igText("Update Frame Index: %d", info.upd_frame_index);
  3091. }
  3092. } else {
  3093. igText("Image 0x%08X not valid.", img.id);
  3094. }
  3095. igEndChild();
  3096. }
  3097. }
  3098. _SOKOL_PRIVATE void _sgimgui_draw_sampler_panel(sgimgui_t* ctx, sg_sampler smp) {
  3099. if (smp.id != SG_INVALID_ID) {
  3100. igBeginChild("sampler", IMVEC2(0,0), false, 0);
  3101. sg_sampler_info info = sg_query_sampler_info(smp);
  3102. if (info.slot.state == SG_RESOURCESTATE_VALID) {
  3103. sgimgui_sampler_t* smp_ui = &ctx->sampler_window.slots[_sgimgui_slot_index(smp.id)];
  3104. const sg_sampler_desc* desc = &smp_ui->desc;
  3105. igText("Label: %s", smp_ui->label.buf[0] ? smp_ui->label.buf : "---");
  3106. _sgimgui_draw_resource_slot(&info.slot);
  3107. igSeparator();
  3108. igText("Min Filter: %s", _sgimgui_filter_string(desc->min_filter));
  3109. igText("Mag Filter: %s", _sgimgui_filter_string(desc->mag_filter));
  3110. igText("Mipmap Filter: %s", _sgimgui_filter_string(desc->mipmap_filter));
  3111. igText("Wrap U: %s", _sgimgui_wrap_string(desc->wrap_u));
  3112. igText("Wrap V: %s", _sgimgui_wrap_string(desc->wrap_v));
  3113. igText("Wrap W: %s", _sgimgui_wrap_string(desc->wrap_w));
  3114. igText("Min LOD: %.3f", desc->min_lod);
  3115. igText("Max LOD: %.3f", desc->max_lod);
  3116. igText("Border Color: %s", _sgimgui_bordercolor_string(desc->border_color));
  3117. igText("Compare: %s", _sgimgui_comparefunc_string(desc->compare));
  3118. igText("Max Anisotropy: %d", desc->max_anisotropy);
  3119. } else {
  3120. igText("Sampler 0x%08X not valid.", smp.id);
  3121. }
  3122. igEndChild();
  3123. }
  3124. }
  3125. _SOKOL_PRIVATE void _sgimgui_draw_shader_func(const char* title, const sg_shader_function* func) {
  3126. SOKOL_ASSERT(func);
  3127. if ((func->source == 0) && (func->bytecode.ptr == 0)) {
  3128. return;
  3129. }
  3130. igPushID(title);
  3131. igText("%s", title);
  3132. if (func->entry) {
  3133. igText(" entry: %s", func->entry);
  3134. }
  3135. if (func->d3d11_target) {
  3136. igText(" d3d11_target: %s", func->d3d11_target);
  3137. }
  3138. if (func->source) {
  3139. if (igTreeNode("source:")) {
  3140. igText("%s", func->source);
  3141. igTreePop();
  3142. }
  3143. } else if (func->bytecode.ptr) {
  3144. if (igTreeNode("bytecode")) {
  3145. igText("Byte-code display currently not supported.");
  3146. igTreePop();
  3147. }
  3148. }
  3149. igPopID();
  3150. }
  3151. _SOKOL_PRIVATE void _sgimgui_draw_shader_panel(sgimgui_t* ctx, sg_shader shd) {
  3152. if (shd.id != SG_INVALID_ID) {
  3153. igBeginChild("shader", IMVEC2(0,0), false, ImGuiWindowFlags_HorizontalScrollbar);
  3154. sg_shader_info info = sg_query_shader_info(shd);
  3155. if (info.slot.state == SG_RESOURCESTATE_VALID) {
  3156. const sgimgui_shader_t* shd_ui = &ctx->shader_window.slots[_sgimgui_slot_index(shd.id)];
  3157. igText("Label: %s", shd_ui->label.buf[0] ? shd_ui->label.buf : "---");
  3158. _sgimgui_draw_resource_slot(&info.slot);
  3159. igSeparator();
  3160. if (igTreeNode("Attrs")) {
  3161. for (int i = 0; i < SG_MAX_VERTEX_ATTRIBUTES; i++) {
  3162. const sg_shader_vertex_attr* a_desc = &shd_ui->desc.attrs[i];
  3163. if ((a_desc->base_type != SG_SHADERATTRBASETYPE_UNDEFINED) || a_desc->glsl_name || a_desc->hlsl_sem_name) {
  3164. igText("#%d:", i);
  3165. if (a_desc->base_type != SG_SHADERATTRBASETYPE_UNDEFINED) {
  3166. igText(" Base Type: %s", _sgimgui_shaderattrbasetype_string(a_desc->base_type));
  3167. }
  3168. if (a_desc->glsl_name) {
  3169. igText(" GLSL Name: %s", a_desc->glsl_name);
  3170. }
  3171. if (a_desc->hlsl_sem_name) {
  3172. igText(" HLSL Sem Name: %s", a_desc->hlsl_sem_name);
  3173. igText(" HLSL Sem Index: %d", a_desc->hlsl_sem_index);
  3174. }
  3175. }
  3176. }
  3177. igTreePop();
  3178. }
  3179. int num_valid_ubs = 0;
  3180. for (int i = 0; i < SG_MAX_UNIFORMBLOCK_BINDSLOTS; i++) {
  3181. const sg_shader_uniform_block* ub = &shd_ui->desc.uniform_blocks[i];
  3182. if (ub->stage != SG_SHADERSTAGE_NONE) {
  3183. num_valid_ubs++;
  3184. }
  3185. }
  3186. int num_valid_images = 0;
  3187. for (int i = 0; i < SG_MAX_IMAGE_BINDSLOTS; i++) {
  3188. if (shd_ui->desc.images[i].stage != SG_SHADERSTAGE_NONE) {
  3189. num_valid_images++;
  3190. }
  3191. }
  3192. int num_valid_samplers = 0;
  3193. for (int i = 0; i < SG_MAX_SAMPLER_BINDSLOTS; i++) {
  3194. if (shd_ui->desc.samplers[i].stage != SG_SHADERSTAGE_NONE) {
  3195. num_valid_samplers++;
  3196. }
  3197. }
  3198. int num_valid_image_sampler_pairs = 0;
  3199. for (int i = 0; i < SG_MAX_IMAGE_SAMPLER_PAIRS; i++) {
  3200. if (shd_ui->desc.image_sampler_pairs[i].stage != SG_SHADERSTAGE_NONE) {
  3201. num_valid_image_sampler_pairs++;
  3202. }
  3203. }
  3204. int num_valid_storage_buffers = 0;
  3205. for (int i = 0; i < SG_MAX_STORAGEBUFFER_BINDSLOTS; i++) {
  3206. if (shd_ui->desc.storage_buffers[i].stage != SG_SHADERSTAGE_NONE) {
  3207. num_valid_storage_buffers++;
  3208. }
  3209. }
  3210. int num_valid_storage_images = 0;
  3211. for (int i = 0; i < SG_MAX_STORAGE_ATTACHMENTS; i++) {
  3212. if (shd_ui->desc.storage_images[i].stage != SG_SHADERSTAGE_NONE) {
  3213. num_valid_storage_images++;
  3214. }
  3215. }
  3216. if (num_valid_ubs > 0) {
  3217. if (igTreeNode("Uniform Blocks")) {
  3218. for (int i = 0; i < SG_MAX_UNIFORMBLOCK_BINDSLOTS; i++) {
  3219. const sg_shader_uniform_block* ub = &shd_ui->desc.uniform_blocks[i];
  3220. if (ub->stage == SG_SHADERSTAGE_NONE) {
  3221. continue;
  3222. }
  3223. igText("- slot: %d", i);
  3224. igText(" stage: %s", _sgimgui_shaderstage_string(ub->stage));
  3225. igText(" size: %d", ub->size);
  3226. igText(" layout: %s", _sgimgui_uniformlayout_string(ub->layout));
  3227. igText(" hlsl_register_b_n: %d", ub->hlsl_register_b_n);
  3228. igText(" msl_buffer_n: %d", ub->msl_buffer_n);
  3229. igText(" wgsl_group0_binding_n: %d", ub->wgsl_group0_binding_n);
  3230. igText(" glsl_uniforms:");
  3231. for (int j = 0; j < SG_MAX_UNIFORMBLOCK_MEMBERS; j++) {
  3232. const sg_glsl_shader_uniform* u = &ub->glsl_uniforms[j];
  3233. if (SG_UNIFORMTYPE_INVALID != u->type) {
  3234. if (u->array_count <= 1) {
  3235. igText(" %s %s", _sgimgui_uniformtype_string(u->type), u->glsl_name ? u->glsl_name : "");
  3236. } else {
  3237. igText(" %s[%d] %s", _sgimgui_uniformtype_string(u->type), u->array_count, u->glsl_name ? u->glsl_name : "");
  3238. }
  3239. }
  3240. }
  3241. }
  3242. igTreePop();
  3243. }
  3244. }
  3245. if (num_valid_images > 0) {
  3246. if (igTreeNode("Images")) {
  3247. for (int i = 0; i < SG_MAX_IMAGE_BINDSLOTS; i++) {
  3248. const sg_shader_image* sid = &shd_ui->desc.images[i];
  3249. if (sid->stage == SG_SHADERSTAGE_NONE) {
  3250. continue;
  3251. }
  3252. igText("- slot: %d", i);
  3253. igText(" stage: %s", _sgimgui_shaderstage_string(sid->stage));
  3254. igText(" image_type: %s", _sgimgui_imagetype_string(sid->image_type));
  3255. igText(" sample_type: %s", _sgimgui_imagesampletype_string(sid->sample_type));
  3256. igText(" multisampled: %s", _sgimgui_bool_string(sid->multisampled));
  3257. igText(" hlsl_register_t_n: %d", sid->hlsl_register_t_n);
  3258. igText(" msl_texture_n: %d", sid->msl_texture_n);
  3259. igText(" wgsl_group1_binding_n: %d", sid->wgsl_group1_binding_n);
  3260. }
  3261. igTreePop();
  3262. }
  3263. }
  3264. if (num_valid_samplers > 0) {
  3265. if (igTreeNode("Samplers")) {
  3266. for (int i = 0; i < SG_MAX_SAMPLER_BINDSLOTS; i++) {
  3267. const sg_shader_sampler* ssd = &shd_ui->desc.samplers[i];
  3268. if (ssd->stage == SG_SHADERSTAGE_NONE) {
  3269. continue;
  3270. }
  3271. igText("- slot: %d", i);
  3272. igText(" stage: %s", _sgimgui_shaderstage_string(ssd->stage));
  3273. igText(" sampler_type: %s", _sgimgui_samplertype_string(ssd->sampler_type));
  3274. igText(" hlsl_register_s_n: %d", ssd->hlsl_register_s_n);
  3275. igText(" msl_sampler_n: %d", ssd->msl_sampler_n);
  3276. igText(" wgsl_group1_binding_n: %d", ssd->wgsl_group1_binding_n);
  3277. }
  3278. igTreePop();
  3279. }
  3280. }
  3281. if (num_valid_image_sampler_pairs > 0) {
  3282. if (igTreeNode("Image Sampler Pairs")) {
  3283. for (int i = 0; i < SG_MAX_IMAGE_SAMPLER_PAIRS; i++) {
  3284. const sg_shader_image_sampler_pair* sispd = &shd_ui->desc.image_sampler_pairs[i];
  3285. if (sispd->stage == SG_SHADERSTAGE_NONE) {
  3286. continue;
  3287. }
  3288. igText("- slot: %d", i);
  3289. igText(" stage: %s", _sgimgui_shaderstage_string(sispd->stage));
  3290. igText(" image_slot: %d", sispd->image_slot);
  3291. igText(" sampler_slot: %d", sispd->sampler_slot);
  3292. igText(" glsl_name: %s", sispd->glsl_name ? sispd->glsl_name : "---");
  3293. }
  3294. igTreePop();
  3295. }
  3296. }
  3297. if (num_valid_storage_buffers > 0) {
  3298. if (igTreeNode("Storage Buffers")) {
  3299. for (int i = 0; i < SG_MAX_STORAGEBUFFER_BINDSLOTS; i++) {
  3300. const sg_shader_storage_buffer* sbuf = &shd_ui->desc.storage_buffers[i];
  3301. if (sbuf->stage == SG_SHADERSTAGE_NONE) {
  3302. continue;
  3303. }
  3304. igText("- slot: %d", i);
  3305. igText(" stage: %s", _sgimgui_shaderstage_string(sbuf->stage));
  3306. igText(" readonly: %s", _sgimgui_bool_string(sbuf->readonly));
  3307. if (sbuf->readonly) {
  3308. igText(" hlsl_register_t_n: %d", sbuf->hlsl_register_t_n);
  3309. } else {
  3310. igText(" hlsl_register_u_n: %d", sbuf->hlsl_register_u_n);
  3311. }
  3312. igText(" msl_buffer_n: %d", sbuf->msl_buffer_n);
  3313. igText(" wgsl_group1_binding_n: %d", sbuf->wgsl_group1_binding_n);
  3314. igText(" glsl_binding_n: %d", sbuf->glsl_binding_n);
  3315. }
  3316. igTreePop();
  3317. }
  3318. }
  3319. if (num_valid_storage_images > 0) {
  3320. if (igTreeNode("Storage Images")) {
  3321. for (int i = 0; i < SG_MAX_STORAGE_ATTACHMENTS; i++) {
  3322. const sg_shader_storage_image* simg = &shd_ui->desc.storage_images[i];
  3323. if (simg->stage == SG_SHADERSTAGE_NONE) {
  3324. continue;
  3325. }
  3326. igText("- slot: %d", i);
  3327. igText(" stage: %s", _sgimgui_shaderstage_string(simg->stage));
  3328. igText(" image_type: %s", _sgimgui_imagetype_string(simg->image_type));
  3329. igText(" access_format: %s", _sgimgui_pixelformat_string(simg->access_format));
  3330. igText(" writeonly: %s", _sgimgui_bool_string(simg->writeonly));
  3331. igText(" hlsl_register_u_n: %d", simg->hlsl_register_u_n);
  3332. igText(" msl_texture_n: %d", simg->msl_texture_n);
  3333. igText(" wgsl_group2_binding_n: %d", simg->wgsl_group2_binding_n);
  3334. igText(" glsl_binding_n: %d", simg->glsl_binding_n);
  3335. }
  3336. igTreePop();
  3337. }
  3338. }
  3339. _sgimgui_draw_shader_func("Vertex Function", &shd_ui->desc.vertex_func);
  3340. _sgimgui_draw_shader_func("Fragment Function", &shd_ui->desc.fragment_func);
  3341. _sgimgui_draw_shader_func("Compute Function", &shd_ui->desc.compute_func);
  3342. } else {
  3343. igText("Shader 0x%08X not valid!", shd.id);
  3344. }
  3345. igEndChild();
  3346. }
  3347. }
  3348. _SOKOL_PRIVATE void _sgimgui_draw_vertex_layout_state(const sg_vertex_layout_state* layout) {
  3349. if (igTreeNode("Buffers")) {
  3350. for (int i = 0; i < SG_MAX_VERTEXBUFFER_BINDSLOTS; i++) {
  3351. const sg_vertex_buffer_layout_state* l_state = &layout->buffers[i];
  3352. if (l_state->stride > 0) {
  3353. igText("#%d:", i);
  3354. igText(" Stride: %d", l_state->stride);
  3355. igText(" Step Func: %s", _sgimgui_vertexstep_string(l_state->step_func));
  3356. igText(" Step Rate: %d", l_state->step_rate);
  3357. }
  3358. }
  3359. igTreePop();
  3360. }
  3361. if (igTreeNode("Attrs")) {
  3362. for (int i = 0; i < SG_MAX_VERTEX_ATTRIBUTES; i++) {
  3363. const sg_vertex_attr_state* a_state = &layout->attrs[i];
  3364. if (a_state->format != SG_VERTEXFORMAT_INVALID) {
  3365. igText("#%d:", i);
  3366. igText(" Format: %s", _sgimgui_vertexformat_string(a_state->format));
  3367. igText(" Offset: %d", a_state->offset);
  3368. igText(" Buffer Index: %d", a_state->buffer_index);
  3369. }
  3370. }
  3371. igTreePop();
  3372. }
  3373. }
  3374. _SOKOL_PRIVATE void _sgimgui_draw_stencil_face_state(const sg_stencil_face_state* sfs) {
  3375. igText("Fail Op: %s", _sgimgui_stencilop_string(sfs->fail_op));
  3376. igText("Depth Fail Op: %s", _sgimgui_stencilop_string(sfs->depth_fail_op));
  3377. igText("Pass Op: %s", _sgimgui_stencilop_string(sfs->pass_op));
  3378. igText("Compare: %s", _sgimgui_comparefunc_string(sfs->compare));
  3379. }
  3380. _SOKOL_PRIVATE void _sgimgui_draw_stencil_state(const sg_stencil_state* ss) {
  3381. igText("Enabled: %s", _sgimgui_bool_string(ss->enabled));
  3382. igText("Read Mask: 0x%02X", ss->read_mask);
  3383. igText("Write Mask: 0x%02X", ss->write_mask);
  3384. igText("Ref: 0x%02X", ss->ref);
  3385. if (igTreeNode("Front")) {
  3386. _sgimgui_draw_stencil_face_state(&ss->front);
  3387. igTreePop();
  3388. }
  3389. if (igTreeNode("Back")) {
  3390. _sgimgui_draw_stencil_face_state(&ss->back);
  3391. igTreePop();
  3392. }
  3393. }
  3394. _SOKOL_PRIVATE void _sgimgui_draw_depth_state(const sg_depth_state* ds) {
  3395. igText("Pixel Format: %s", _sgimgui_pixelformat_string(ds->pixel_format));
  3396. igText("Compare: %s", _sgimgui_comparefunc_string(ds->compare));
  3397. igText("Write Enabled: %s", _sgimgui_bool_string(ds->write_enabled));
  3398. igText("Bias: %f", ds->bias);
  3399. igText("Bias Slope: %f", ds->bias_slope_scale);
  3400. igText("Bias Clamp: %f", ds->bias_clamp);
  3401. }
  3402. _SOKOL_PRIVATE void _sgimgui_draw_blend_state(const sg_blend_state* bs) {
  3403. igText("Blend Enabled: %s", _sgimgui_bool_string(bs->enabled));
  3404. igText("Src Factor RGB: %s", _sgimgui_blendfactor_string(bs->src_factor_rgb));
  3405. igText("Dst Factor RGB: %s", _sgimgui_blendfactor_string(bs->dst_factor_rgb));
  3406. igText("Op RGB: %s", _sgimgui_blendop_string(bs->op_rgb));
  3407. igText("Src Factor Alpha: %s", _sgimgui_blendfactor_string(bs->src_factor_alpha));
  3408. igText("Dst Factor Alpha: %s", _sgimgui_blendfactor_string(bs->dst_factor_alpha));
  3409. igText("Op Alpha: %s", _sgimgui_blendop_string(bs->op_alpha));
  3410. }
  3411. _SOKOL_PRIVATE void _sgimgui_draw_color_target_state(const sg_color_target_state* cs) {
  3412. igText("Pixel Format: %s", _sgimgui_pixelformat_string(cs->pixel_format));
  3413. igText("Write Mask: %s", _sgimgui_colormask_string(cs->write_mask));
  3414. if (igTreeNode("Blend State:")) {
  3415. _sgimgui_draw_blend_state(&cs->blend);
  3416. igTreePop();
  3417. }
  3418. }
  3419. _SOKOL_PRIVATE void _sgimgui_draw_pipeline_panel(sgimgui_t* ctx, sg_pipeline pip) {
  3420. if (pip.id != SG_INVALID_ID) {
  3421. igBeginChild("pipeline", IMVEC2(0,0), false, 0);
  3422. sg_pipeline_info info = sg_query_pipeline_info(pip);
  3423. if (info.slot.state == SG_RESOURCESTATE_VALID) {
  3424. const sgimgui_pipeline_t* pip_ui = &ctx->pipeline_window.slots[_sgimgui_slot_index(pip.id)];
  3425. igText("Label: %s", pip_ui->label.buf[0] ? pip_ui->label.buf : "---");
  3426. _sgimgui_draw_resource_slot(&info.slot);
  3427. igSeparator();
  3428. igText("Compute: %s", _sgimgui_bool_string(pip_ui->desc.compute));
  3429. igText("Shader: "); igSameLine();
  3430. if (_sgimgui_draw_shader_link(ctx, pip_ui->desc.shader)) {
  3431. _sgimgui_show_shader(ctx, pip_ui->desc.shader);
  3432. }
  3433. if (!pip_ui->desc.compute) {
  3434. if (igTreeNode("Vertex Layout State")) {
  3435. _sgimgui_draw_vertex_layout_state(&pip_ui->desc.layout);
  3436. igTreePop();
  3437. }
  3438. if (igTreeNode("Depth State")) {
  3439. _sgimgui_draw_depth_state(&pip_ui->desc.depth);
  3440. igTreePop();
  3441. }
  3442. if (igTreeNode("Stencil State")) {
  3443. _sgimgui_draw_stencil_state(&pip_ui->desc.stencil);
  3444. igTreePop();
  3445. }
  3446. igText("Color Count: %d", pip_ui->desc.color_count);
  3447. for (int i = 0; i < pip_ui->desc.color_count; i++) {
  3448. sgimgui_str_t str;
  3449. _sgimgui_snprintf(&str, "Color Target %d", i);
  3450. if (igTreeNode(str.buf)) {
  3451. _sgimgui_draw_color_target_state(&pip_ui->desc.colors[i]);
  3452. igTreePop();
  3453. }
  3454. }
  3455. igText("Prim Type: %s", _sgimgui_primitivetype_string(pip_ui->desc.primitive_type));
  3456. igText("Index Type: %s", _sgimgui_indextype_string(pip_ui->desc.index_type));
  3457. igText("Cull Mode: %s", _sgimgui_cullmode_string(pip_ui->desc.cull_mode));
  3458. igText("Face Winding: %s", _sgimgui_facewinding_string(pip_ui->desc.face_winding));
  3459. igText("Sample Count: %d", pip_ui->desc.sample_count);
  3460. sgimgui_str_t blend_color_str;
  3461. igText("Blend Color: %s", _sgimgui_color_string(&blend_color_str, pip_ui->desc.blend_color));
  3462. igText("Alpha To Coverage: %s", _sgimgui_bool_string(pip_ui->desc.alpha_to_coverage_enabled));
  3463. }
  3464. } else {
  3465. igText("Pipeline 0x%08X not valid.", pip.id);
  3466. }
  3467. igEndChild();
  3468. }
  3469. }
  3470. _SOKOL_PRIVATE void _sgimgui_draw_attachment(sgimgui_t* ctx, const sg_attachment_desc* att, float* img_scale) {
  3471. igText(" Image: "); igSameLine();
  3472. if (_sgimgui_draw_image_link(ctx, att->image)) {
  3473. _sgimgui_show_image(ctx, att->image);
  3474. }
  3475. igText(" Mip Level: %d", att->mip_level);
  3476. igText(" Slice: %d", att->slice);
  3477. _sgimgui_draw_embedded_image(ctx, att->image, img_scale);
  3478. }
  3479. _SOKOL_PRIVATE void _sgimgui_draw_attachments_panel(sgimgui_t* ctx, sg_attachments atts) {
  3480. if (atts.id != SG_INVALID_ID) {
  3481. igBeginChild("attachments", IMVEC2(0,0), false, 0);
  3482. sg_attachments_info info = sg_query_attachments_info(atts);
  3483. if (info.slot.state == SG_RESOURCESTATE_VALID) {
  3484. sgimgui_attachments_t* atts_ui = &ctx->attachments_window.slots[_sgimgui_slot_index(atts.id)];
  3485. igText("Label: %s", atts_ui->label.buf[0] ? atts_ui->label.buf : "---");
  3486. _sgimgui_draw_resource_slot(&info.slot);
  3487. for (int i = 0; i < SG_MAX_COLOR_ATTACHMENTS; i++) {
  3488. if (atts_ui->desc.colors[i].image.id == SG_INVALID_ID) {
  3489. break;
  3490. }
  3491. igSeparator();
  3492. igText("Color Image #%d:", i);
  3493. _sgimgui_draw_attachment(ctx, &atts_ui->desc.colors[i], &atts_ui->color_image_scale[i]);
  3494. }
  3495. for (int i = 0; i < SG_MAX_COLOR_ATTACHMENTS; i++) {
  3496. if (atts_ui->desc.resolves[i].image.id == SG_INVALID_ID) {
  3497. break;
  3498. }
  3499. igSeparator();
  3500. igText("Resolve Image #%d:", i);
  3501. _sgimgui_draw_attachment(ctx, &atts_ui->desc.resolves[i], &atts_ui->resolve_image_scale[i]);
  3502. }
  3503. if (atts_ui->desc.depth_stencil.image.id != SG_INVALID_ID) {
  3504. igSeparator();
  3505. igText("Depth-Stencil Image:");
  3506. _sgimgui_draw_attachment(ctx, &atts_ui->desc.depth_stencil, &atts_ui->ds_image_scale);
  3507. }
  3508. for (int i = 0; i < SG_MAX_STORAGE_ATTACHMENTS; i++) {
  3509. if (atts_ui->desc.storages[i].image.id == SG_INVALID_ID) {
  3510. break;
  3511. }
  3512. igSeparator();
  3513. igText("Storage Image #%d:", i);
  3514. _sgimgui_draw_attachment(ctx, &atts_ui->desc.storages[i], &atts_ui->storage_image_scale[i]);
  3515. }
  3516. } else {
  3517. igText("Attachments 0x%08X not valid.", atts.id);
  3518. }
  3519. igEndChild();
  3520. }
  3521. }
  3522. _SOKOL_PRIVATE void _sgimgui_draw_bindings_panel(sgimgui_t* ctx, const sg_bindings* bnd) {
  3523. igPushID("bnd_vbufs");
  3524. for (int i = 0; i < SG_MAX_VERTEXBUFFER_BINDSLOTS; i++) {
  3525. sg_buffer buf = bnd->vertex_buffers[i];
  3526. if (buf.id != SG_INVALID_ID) {
  3527. igSeparator();
  3528. igText("Vertex Buffer Slot #%d:", i);
  3529. igText(" Buffer: "); igSameLine();
  3530. if (_sgimgui_draw_buffer_link(ctx, buf)) {
  3531. _sgimgui_show_buffer(ctx, buf);
  3532. }
  3533. igText(" Offset: %d", bnd->vertex_buffer_offsets[i]);
  3534. }
  3535. }
  3536. igPopID();
  3537. igPushID("bnd_ibuf");
  3538. if (bnd->index_buffer.id != SG_INVALID_ID) {
  3539. sg_buffer buf = bnd->index_buffer;
  3540. if (buf.id != SG_INVALID_ID) {
  3541. igSeparator();
  3542. igText("Index Buffer Slot:");
  3543. igText(" Buffer: "); igSameLine();
  3544. if (_sgimgui_draw_buffer_link(ctx, buf)) {
  3545. _sgimgui_show_buffer(ctx, buf);
  3546. }
  3547. igText(" Offset: %d", bnd->index_buffer_offset);
  3548. }
  3549. }
  3550. igPopID();
  3551. igPushID("bnd_sbufs");
  3552. for (int i = 0; i < SG_MAX_STORAGEBUFFER_BINDSLOTS; i++) {
  3553. sg_buffer buf = bnd->storage_buffers[i];
  3554. if (buf.id != SG_INVALID_ID) {
  3555. igSeparator();
  3556. igText("Storage Buffer Slot #%d:", i);
  3557. igText(" Buffer: "); igSameLine();
  3558. if (_sgimgui_draw_buffer_link(ctx, buf)) {
  3559. _sgimgui_show_buffer(ctx, buf);
  3560. }
  3561. }
  3562. }
  3563. igPopID();
  3564. igPushID("bnd_imgs");
  3565. for (int i = 0; i < SG_MAX_IMAGE_BINDSLOTS; i++) {
  3566. sg_image img = bnd->images[i];
  3567. if (img.id != SG_INVALID_ID) {
  3568. igSeparator();
  3569. igText("Image Slot #%d:", i);
  3570. igText(" Image: "); igSameLine();
  3571. if (_sgimgui_draw_image_link(ctx, img)) {
  3572. _sgimgui_show_image(ctx, img);
  3573. }
  3574. }
  3575. }
  3576. igPopID();
  3577. igPushID("bnd_smps");
  3578. for (int i = 0; i < SG_MAX_SAMPLER_BINDSLOTS; i++) {
  3579. sg_sampler smp = bnd->samplers[i];
  3580. if (smp.id != SG_INVALID_ID) {
  3581. igSeparator();
  3582. igText("Sampler Slot #%d:", i);
  3583. igText(" Sampler: "); igSameLine();
  3584. if (_sgimgui_draw_sampler_link(ctx, smp)) {
  3585. _sgimgui_show_sampler(ctx, smp);
  3586. }
  3587. }
  3588. }
  3589. igPopID();
  3590. }
  3591. _SOKOL_PRIVATE void _sgimgui_draw_uniforms_panel(sgimgui_t* ctx, const sgimgui_args_apply_uniforms_t* args) {
  3592. SOKOL_ASSERT(args->ub_slot < SG_MAX_UNIFORMBLOCK_BINDSLOTS);
  3593. /* check if all the required information for drawing the structured uniform block content
  3594. is available, otherwise just render a generic hexdump
  3595. */
  3596. if (sg_query_pipeline_state(args->pipeline) != SG_RESOURCESTATE_VALID) {
  3597. igText("Pipeline object not valid!");
  3598. return;
  3599. }
  3600. sgimgui_pipeline_t* pip_ui = &ctx->pipeline_window.slots[_sgimgui_slot_index(args->pipeline.id)];
  3601. if (sg_query_shader_state(pip_ui->desc.shader) != SG_RESOURCESTATE_VALID) {
  3602. igText("Shader object not valid!");
  3603. return;
  3604. }
  3605. sgimgui_shader_t* shd_ui = &ctx->shader_window.slots[_sgimgui_slot_index(pip_ui->desc.shader.id)];
  3606. SOKOL_ASSERT(shd_ui->res_id.id == pip_ui->desc.shader.id);
  3607. const sg_shader_uniform_block* ub_desc = &shd_ui->desc.uniform_blocks[args->ub_slot];
  3608. SOKOL_ASSERT(args->data_size <= ub_desc->size);
  3609. bool draw_dump = false;
  3610. if (ub_desc->glsl_uniforms[0].type == SG_UNIFORMTYPE_INVALID) {
  3611. draw_dump = true;
  3612. }
  3613. sgimgui_capture_bucket_t* bucket = _sgimgui_capture_get_read_bucket(ctx);
  3614. SOKOL_ASSERT((args->ubuf_pos + args->data_size) <= bucket->ubuf_size);
  3615. const float* uptrf = (const float*) (bucket->ubuf + args->ubuf_pos);
  3616. const int32_t* uptri32 = (const int32_t*) uptrf;
  3617. if (!draw_dump) {
  3618. uint32_t u_off = 0;
  3619. for (int i = 0; i < SG_MAX_UNIFORMBLOCK_MEMBERS; i++) {
  3620. const sg_glsl_shader_uniform* ud = &ub_desc->glsl_uniforms[i];
  3621. if (ud->type == SG_UNIFORMTYPE_INVALID) {
  3622. break;
  3623. }
  3624. int num_items = (ud->array_count > 1) ? ud->array_count : 1;
  3625. if (num_items > 1) {
  3626. igText("%d: %s %s[%d] =", i, _sgimgui_uniformtype_string(ud->type), ud->glsl_name?ud->glsl_name:"", ud->array_count);
  3627. } else {
  3628. igText("%d: %s %s =", i, _sgimgui_uniformtype_string(ud->type), ud->glsl_name?ud->glsl_name:"");
  3629. }
  3630. for (int item_index = 0; item_index < num_items; item_index++) {
  3631. const uint32_t u_size = _sgimgui_std140_uniform_size(ud->type, ud->array_count) / 4;
  3632. const uint32_t u_align = _sgimgui_std140_uniform_alignment(ud->type, ud->array_count) / 4;
  3633. u_off = _sgimgui_align_u32(u_off, u_align);
  3634. switch (ud->type) {
  3635. case SG_UNIFORMTYPE_FLOAT:
  3636. igText(" %.3f", uptrf[u_off]);
  3637. break;
  3638. case SG_UNIFORMTYPE_INT:
  3639. igText(" %d", uptri32[u_off]);
  3640. break;
  3641. case SG_UNIFORMTYPE_FLOAT2:
  3642. igText(" %.3f, %.3f", uptrf[u_off], uptrf[u_off+1]);
  3643. break;
  3644. case SG_UNIFORMTYPE_INT2:
  3645. igText(" %d, %d", uptri32[u_off], uptri32[u_off+1]);
  3646. break;
  3647. case SG_UNIFORMTYPE_FLOAT3:
  3648. igText(" %.3f, %.3f, %.3f", uptrf[u_off], uptrf[u_off+1], uptrf[u_off+2]);
  3649. break;
  3650. case SG_UNIFORMTYPE_INT3:
  3651. igText(" %d, %d, %d", uptri32[u_off], uptri32[u_off+1], uptri32[u_off+2]);
  3652. break;
  3653. case SG_UNIFORMTYPE_FLOAT4:
  3654. igText(" %.3f, %.3f, %.3f, %.3f", uptrf[u_off], uptrf[u_off+1], uptrf[u_off+2], uptrf[u_off+3]);
  3655. break;
  3656. case SG_UNIFORMTYPE_INT4:
  3657. igText(" %d, %d, %d, %d", uptri32[u_off], uptri32[u_off+1], uptri32[u_off+2], uptri32[u_off+3]);
  3658. break;
  3659. case SG_UNIFORMTYPE_MAT4:
  3660. igText(" %.3f, %.3f, %.3f, %.3f\n"
  3661. " %.3f, %.3f, %.3f, %.3f\n"
  3662. " %.3f, %.3f, %.3f, %.3f\n"
  3663. " %.3f, %.3f, %.3f, %.3f",
  3664. uptrf[u_off+0], uptrf[u_off+1], uptrf[u_off+2], uptrf[u_off+3],
  3665. uptrf[u_off+4], uptrf[u_off+5], uptrf[u_off+6], uptrf[u_off+7],
  3666. uptrf[u_off+8], uptrf[u_off+9], uptrf[u_off+10], uptrf[u_off+11],
  3667. uptrf[u_off+12], uptrf[u_off+13], uptrf[u_off+14], uptrf[u_off+15]);
  3668. break;
  3669. default:
  3670. igText("???");
  3671. break;
  3672. }
  3673. u_off += u_size;
  3674. }
  3675. }
  3676. } else {
  3677. // FIXME: float vs int
  3678. const size_t num_floats = ub_desc->size / sizeof(float);
  3679. for (uint32_t i = 0; i < num_floats; i++) {
  3680. igText("%.3f, ", uptrf[i]);
  3681. if (((i + 1) % 4) != 0) {
  3682. igSameLine();
  3683. }
  3684. }
  3685. }
  3686. }
  3687. _SOKOL_PRIVATE void _sgimgui_draw_passaction_panel(sgimgui_t* ctx, sg_attachments atts, const sg_pass_action* action) {
  3688. /* determine number of valid color attachments */
  3689. int num_color_atts = 0;
  3690. if (SG_INVALID_ID == atts.id) {
  3691. /* a swapchain pass: one color attachment */
  3692. num_color_atts = 1;
  3693. } else {
  3694. const sgimgui_attachments_t* atts_ui = &ctx->attachments_window.slots[_sgimgui_slot_index(atts.id)];
  3695. for (int i = 0; i < SG_MAX_COLOR_ATTACHMENTS; i++) {
  3696. if (atts_ui->desc.colors[i].image.id != SG_INVALID_ID) {
  3697. num_color_atts++;
  3698. }
  3699. }
  3700. }
  3701. igText("Pass Action: ");
  3702. for (int i = 0; i < num_color_atts; i++) {
  3703. const sg_color_attachment_action* c_att = &action->colors[i];
  3704. igText(" Color Attachment %d:", i);
  3705. sgimgui_str_t color_str;
  3706. switch (c_att->load_action) {
  3707. case SG_LOADACTION_LOAD: igText(" SG_LOADACTION_LOAD"); break;
  3708. case SG_LOADACTION_DONTCARE: igText(" SG_LOADACTION_DONTCARE"); break;
  3709. case SG_LOADACTION_CLEAR:
  3710. igText(" SG_LOADACTION_CLEAR: %s", _sgimgui_color_string(&color_str, c_att->clear_value));
  3711. break;
  3712. default: igText(" ???"); break;
  3713. }
  3714. switch (c_att->store_action) {
  3715. case SG_STOREACTION_STORE: igText(" SG_STOREACTION_STORE"); break;
  3716. case SG_STOREACTION_DONTCARE: igText(" SG_STOREACTION_DONTCARE"); break;
  3717. default: igText(" ???"); break;
  3718. }
  3719. }
  3720. const sg_depth_attachment_action* d_att = &action->depth;
  3721. igText(" Depth Attachment:");
  3722. switch (d_att->load_action) {
  3723. case SG_LOADACTION_LOAD: igText(" SG_LOADACTION_LOAD"); break;
  3724. case SG_LOADACTION_DONTCARE: igText(" SG_LOADACTION_DONTCARE"); break;
  3725. case SG_LOADACTION_CLEAR: igText(" SG_LOADACTION_CLEAR: %.3f", d_att->clear_value); break;
  3726. default: igText(" ???"); break;
  3727. }
  3728. switch (d_att->store_action) {
  3729. case SG_STOREACTION_STORE: igText(" SG_STOREACTION_STORE"); break;
  3730. case SG_STOREACTION_DONTCARE: igText(" SG_STOREACTION_DONTCARE"); break;
  3731. default: igText(" ???"); break;
  3732. }
  3733. const sg_stencil_attachment_action* s_att = &action->stencil;
  3734. igText(" Stencil Attachment");
  3735. switch (s_att->load_action) {
  3736. case SG_LOADACTION_LOAD: igText(" SG_LOADACTION_LOAD"); break;
  3737. case SG_LOADACTION_DONTCARE: igText(" SG_LOADACTION_DONTCARE"); break;
  3738. case SG_LOADACTION_CLEAR: igText(" SG_LOADACTION_CLEAR: 0x%02X", s_att->clear_value); break;
  3739. default: igText(" ???"); break;
  3740. }
  3741. switch (d_att->store_action) {
  3742. case SG_STOREACTION_STORE: igText(" SG_STOREACTION_STORE"); break;
  3743. case SG_STOREACTION_DONTCARE: igText(" SG_STOREACTION_DONTCARE"); break;
  3744. default: igText(" ???"); break;
  3745. }
  3746. }
  3747. _SOKOL_PRIVATE void _sgimgui_draw_swapchain_panel(sg_swapchain* swapchain) {
  3748. igText("Swapchain");
  3749. igText(" Width: %d", swapchain->width);
  3750. igText(" Height: %d", swapchain->height);
  3751. igText(" Sample Count: %d", swapchain->sample_count);
  3752. igText(" Color Format: %s", _sgimgui_pixelformat_string(swapchain->color_format));
  3753. igText(" Depth Format: %s", _sgimgui_pixelformat_string(swapchain->depth_format));
  3754. igSeparator();
  3755. switch (sg_query_backend()) {
  3756. case SG_BACKEND_D3D11:
  3757. igText("D3D11 Objects:");
  3758. igText(" Render View: %p", swapchain->d3d11.render_view);
  3759. igText(" Resolve View: %p", swapchain->d3d11.resolve_view);
  3760. igText(" Depth Stencil View: %p", swapchain->d3d11.depth_stencil_view);
  3761. break;
  3762. case SG_BACKEND_WGPU:
  3763. igText("WGPU Objects:");
  3764. igText(" Render View: %p", swapchain->wgpu.render_view);
  3765. igText(" Resolve View: %p", swapchain->wgpu.resolve_view);
  3766. igText(" Depth Stencil View: %p", swapchain->wgpu.depth_stencil_view);
  3767. break;
  3768. case SG_BACKEND_METAL_MACOS:
  3769. case SG_BACKEND_METAL_IOS:
  3770. case SG_BACKEND_METAL_SIMULATOR:
  3771. igText("Metal Objects:");
  3772. igText(" Current Drawable: %p", swapchain->metal.current_drawable);
  3773. igText(" Depth Stencil Texture: %p", swapchain->metal.depth_stencil_texture);
  3774. igText(" MSAA Color Texture: %p", swapchain->metal.msaa_color_texture);
  3775. break;
  3776. case SG_BACKEND_GLCORE:
  3777. case SG_BACKEND_GLES3:
  3778. igText("GL Objects:");
  3779. igText(" Framebuffer: %d", swapchain->gl.framebuffer);
  3780. break;
  3781. default:
  3782. igText(" UNKNOWN BACKEND!");
  3783. break;
  3784. }
  3785. }
  3786. _SOKOL_PRIVATE void _sgimgui_draw_capture_panel(sgimgui_t* ctx) {
  3787. int sel_item_index = ctx->capture_window.sel_item;
  3788. if (sel_item_index >= _sgimgui_capture_num_read_items(ctx)) {
  3789. return;
  3790. }
  3791. sgimgui_capture_item_t* item = _sgimgui_capture_read_item_at(ctx, sel_item_index);
  3792. igBeginChild("capture_item", IMVEC2(0, 0), false, 0);
  3793. igPushStyleColor(ImGuiCol_Text, item->color);
  3794. igText("%s", _sgimgui_capture_item_string(ctx, sel_item_index, item).buf);
  3795. igPopStyleColor();
  3796. igSeparator();
  3797. switch (item->cmd) {
  3798. case SGIMGUI_CMD_RESET_STATE_CACHE:
  3799. break;
  3800. case SGIMGUI_CMD_MAKE_BUFFER:
  3801. _sgimgui_draw_buffer_panel(ctx, item->args.make_buffer.result);
  3802. break;
  3803. case SGIMGUI_CMD_MAKE_IMAGE:
  3804. _sgimgui_draw_image_panel(ctx, item->args.make_image.result);
  3805. break;
  3806. case SGIMGUI_CMD_MAKE_SAMPLER:
  3807. _sgimgui_draw_sampler_panel(ctx, item->args.make_sampler.result);
  3808. break;
  3809. case SGIMGUI_CMD_MAKE_SHADER:
  3810. _sgimgui_draw_shader_panel(ctx, item->args.make_shader.result);
  3811. break;
  3812. case SGIMGUI_CMD_MAKE_PIPELINE:
  3813. _sgimgui_draw_pipeline_panel(ctx, item->args.make_pipeline.result);
  3814. break;
  3815. case SGIMGUI_CMD_MAKE_ATTACHMENTS:
  3816. _sgimgui_draw_attachments_panel(ctx, item->args.make_attachments.result);
  3817. break;
  3818. case SGIMGUI_CMD_DESTROY_BUFFER:
  3819. _sgimgui_draw_buffer_panel(ctx, item->args.destroy_buffer.buffer);
  3820. break;
  3821. case SGIMGUI_CMD_DESTROY_IMAGE:
  3822. _sgimgui_draw_image_panel(ctx, item->args.destroy_image.image);
  3823. break;
  3824. case SGIMGUI_CMD_DESTROY_SAMPLER:
  3825. _sgimgui_draw_sampler_panel(ctx, item->args.destroy_sampler.sampler);
  3826. break;
  3827. case SGIMGUI_CMD_DESTROY_SHADER:
  3828. _sgimgui_draw_shader_panel(ctx, item->args.destroy_shader.shader);
  3829. break;
  3830. case SGIMGUI_CMD_DESTROY_PIPELINE:
  3831. _sgimgui_draw_pipeline_panel(ctx, item->args.destroy_pipeline.pipeline);
  3832. break;
  3833. case SGIMGUI_CMD_DESTROY_ATTACHMENTS:
  3834. _sgimgui_draw_attachments_panel(ctx, item->args.destroy_attachments.attachments);
  3835. break;
  3836. case SGIMGUI_CMD_UPDATE_BUFFER:
  3837. _sgimgui_draw_buffer_panel(ctx, item->args.update_buffer.buffer);
  3838. break;
  3839. case SGIMGUI_CMD_UPDATE_IMAGE:
  3840. _sgimgui_draw_image_panel(ctx, item->args.update_image.image);
  3841. break;
  3842. case SGIMGUI_CMD_APPEND_BUFFER:
  3843. _sgimgui_draw_buffer_panel(ctx, item->args.update_buffer.buffer);
  3844. break;
  3845. case SGIMGUI_CMD_BEGIN_PASS:
  3846. igText("Compute: %s", _sgimgui_bool_string(item->args.begin_pass.pass.compute));
  3847. if (item->args.begin_pass.pass.compute) {
  3848. if (item->args.begin_pass.pass.attachments.id != SG_INVALID_ID) {
  3849. _sgimgui_draw_attachments_panel(ctx, item->args.begin_pass.pass.attachments);
  3850. }
  3851. } else {
  3852. _sgimgui_draw_passaction_panel(ctx, item->args.begin_pass.pass.attachments, &item->args.begin_pass.pass.action);
  3853. igSeparator();
  3854. if (item->args.begin_pass.pass.attachments.id != SG_INVALID_ID) {
  3855. _sgimgui_draw_attachments_panel(ctx, item->args.begin_pass.pass.attachments);
  3856. } else {
  3857. _sgimgui_draw_swapchain_panel(&item->args.begin_pass.pass.swapchain);
  3858. }
  3859. }
  3860. break;
  3861. case SGIMGUI_CMD_APPLY_VIEWPORT:
  3862. case SGIMGUI_CMD_APPLY_SCISSOR_RECT:
  3863. break;
  3864. case SGIMGUI_CMD_APPLY_PIPELINE:
  3865. _sgimgui_draw_pipeline_panel(ctx, item->args.apply_pipeline.pipeline);
  3866. break;
  3867. case SGIMGUI_CMD_APPLY_BINDINGS:
  3868. _sgimgui_draw_bindings_panel(ctx, &item->args.apply_bindings.bindings);
  3869. break;
  3870. case SGIMGUI_CMD_APPLY_UNIFORMS:
  3871. _sgimgui_draw_uniforms_panel(ctx, &item->args.apply_uniforms);
  3872. break;
  3873. case SGIMGUI_CMD_DRAW:
  3874. case SGIMGUI_CMD_DISPATCH:
  3875. case SGIMGUI_CMD_END_PASS:
  3876. case SGIMGUI_CMD_COMMIT:
  3877. break;
  3878. case SGIMGUI_CMD_ALLOC_BUFFER:
  3879. _sgimgui_draw_buffer_panel(ctx, item->args.alloc_buffer.result);
  3880. break;
  3881. case SGIMGUI_CMD_ALLOC_IMAGE:
  3882. _sgimgui_draw_image_panel(ctx, item->args.alloc_image.result);
  3883. break;
  3884. case SGIMGUI_CMD_ALLOC_SAMPLER:
  3885. _sgimgui_draw_sampler_panel(ctx, item->args.alloc_sampler.result);
  3886. break;
  3887. case SGIMGUI_CMD_ALLOC_SHADER:
  3888. _sgimgui_draw_shader_panel(ctx, item->args.alloc_shader.result);
  3889. break;
  3890. case SGIMGUI_CMD_ALLOC_PIPELINE:
  3891. _sgimgui_draw_pipeline_panel(ctx, item->args.alloc_pipeline.result);
  3892. break;
  3893. case SGIMGUI_CMD_ALLOC_ATTACHMENTS:
  3894. _sgimgui_draw_attachments_panel(ctx, item->args.alloc_attachments.result);
  3895. break;
  3896. case SGIMGUI_CMD_INIT_BUFFER:
  3897. _sgimgui_draw_buffer_panel(ctx, item->args.init_buffer.buffer);
  3898. break;
  3899. case SGIMGUI_CMD_INIT_IMAGE:
  3900. _sgimgui_draw_image_panel(ctx, item->args.init_image.image);
  3901. break;
  3902. case SGIMGUI_CMD_INIT_SAMPLER:
  3903. _sgimgui_draw_sampler_panel(ctx, item->args.init_sampler.sampler);
  3904. break;
  3905. case SGIMGUI_CMD_INIT_SHADER:
  3906. _sgimgui_draw_shader_panel(ctx, item->args.init_shader.shader);
  3907. break;
  3908. case SGIMGUI_CMD_INIT_PIPELINE:
  3909. _sgimgui_draw_pipeline_panel(ctx, item->args.init_pipeline.pipeline);
  3910. break;
  3911. case SGIMGUI_CMD_INIT_ATTACHMENTS:
  3912. _sgimgui_draw_attachments_panel(ctx, item->args.init_attachments.attachments);
  3913. break;
  3914. case SGIMGUI_CMD_FAIL_BUFFER:
  3915. _sgimgui_draw_buffer_panel(ctx, item->args.fail_buffer.buffer);
  3916. break;
  3917. case SGIMGUI_CMD_FAIL_IMAGE:
  3918. _sgimgui_draw_image_panel(ctx, item->args.fail_image.image);
  3919. break;
  3920. case SGIMGUI_CMD_FAIL_SAMPLER:
  3921. _sgimgui_draw_sampler_panel(ctx, item->args.fail_sampler.sampler);
  3922. break;
  3923. case SGIMGUI_CMD_FAIL_SHADER:
  3924. _sgimgui_draw_shader_panel(ctx, item->args.fail_shader.shader);
  3925. break;
  3926. case SGIMGUI_CMD_FAIL_PIPELINE:
  3927. _sgimgui_draw_pipeline_panel(ctx, item->args.fail_pipeline.pipeline);
  3928. break;
  3929. case SGIMGUI_CMD_FAIL_ATTACHMENTS:
  3930. _sgimgui_draw_attachments_panel(ctx, item->args.fail_attachments.attachments);
  3931. break;
  3932. default:
  3933. break;
  3934. }
  3935. igEndChild();
  3936. }
  3937. _SOKOL_PRIVATE void _sgimgui_draw_caps_panel(void) {
  3938. igText("Backend: %s\n\n", _sgimgui_backend_string(sg_query_backend()));
  3939. sg_features f = sg_query_features();
  3940. igText("Features:");
  3941. igText(" origin_top_left: %s", _sgimgui_bool_string(f.origin_top_left));
  3942. igText(" image_clamp_to_border: %s", _sgimgui_bool_string(f.image_clamp_to_border));
  3943. igText(" mrt_independent_blend_state: %s", _sgimgui_bool_string(f.mrt_independent_blend_state));
  3944. igText(" mrt_independent_write_mask: %s", _sgimgui_bool_string(f.mrt_independent_write_mask));
  3945. igText(" compute: %s", _sgimgui_bool_string(f.compute));
  3946. igText(" msaa_image_bindings: %s", _sgimgui_bool_string(f.msaa_image_bindings));
  3947. igText(" separate_buffer_types: %s", _sgimgui_bool_string(f.separate_buffer_types));
  3948. sg_limits l = sg_query_limits();
  3949. igText("\nLimits:\n");
  3950. igText(" max_image_size_2d: %d", l.max_image_size_2d);
  3951. igText(" max_image_size_cube: %d", l.max_image_size_cube);
  3952. igText(" max_image_size_3d: %d", l.max_image_size_3d);
  3953. igText(" max_image_size_array: %d", l.max_image_size_array);
  3954. igText(" max_image_array_layers: %d", l.max_image_array_layers);
  3955. igText(" max_vertex_attrs: %d", l.max_vertex_attrs);
  3956. igText(" gl_max_vertex_uniform_components: %d", l.gl_max_vertex_uniform_components);
  3957. igText(" gl_max_combined_texture_image_units: %d", l.gl_max_combined_texture_image_units);
  3958. igText("\nUsable Pixelformats:");
  3959. for (int i = (int)(SG_PIXELFORMAT_NONE+1); i < (int)_SG_PIXELFORMAT_NUM; i++) {
  3960. sg_pixel_format fmt = (sg_pixel_format)i;
  3961. sg_pixelformat_info info = sg_query_pixelformat(fmt);
  3962. if (info.sample) {
  3963. igText(" %s: %s%s%s%s%s%s%s%s%s",
  3964. _sgimgui_pixelformat_string(fmt),
  3965. info.sample ? "SAMPLE ":"",
  3966. info.filter ? "FILTER ":"",
  3967. info.blend ? "BLEND ":"",
  3968. info.render ? "RENDER ":"",
  3969. info.msaa ? "MSAA ":"",
  3970. info.depth ? "DEPTH ":"",
  3971. info.compressed ? "COMPRESSED ":"",
  3972. info.read ? "READ ":"",
  3973. info.write ? "WRITE ":"");
  3974. }
  3975. }
  3976. }
  3977. _SOKOL_PRIVATE void _sgimgui_frame_add_stats_row(const char* key, uint32_t value) {
  3978. igTableNextRow();
  3979. igTableSetColumnIndex(0);
  3980. igText("%s", key);
  3981. igTableSetColumnIndex(1);
  3982. igText("%d", value);
  3983. }
  3984. #define _sgimgui_frame_stats(key) _sgimgui_frame_add_stats_row(#key, stats->key)
  3985. _SOKOL_PRIVATE void _sgimgui_draw_frame_stats_panel(sgimgui_t* ctx) {
  3986. _SOKOL_UNUSED(ctx);
  3987. igCheckbox("Ignore sokol_imgui.h", &ctx->frame_stats_window.disable_sokol_imgui_stats);
  3988. const sg_frame_stats* stats = &ctx->frame_stats_window.stats;
  3989. const ImGuiTableFlags flags =
  3990. ImGuiTableFlags_Resizable |
  3991. ImGuiTableFlags_ScrollY |
  3992. ImGuiTableFlags_SizingFixedFit |
  3993. ImGuiTableFlags_Borders;
  3994. if (igBeginTable("##frame_stats_table", 2, flags)) {
  3995. igTableSetupScrollFreeze(0, 1);
  3996. igTableSetupColumn("key", ImGuiTableColumnFlags_None);
  3997. igTableSetupColumn("value", ImGuiTableColumnFlags_None);
  3998. igTableHeadersRow();
  3999. _sgimgui_frame_stats(frame_index);
  4000. _sgimgui_frame_stats(num_passes);
  4001. _sgimgui_frame_stats(num_apply_viewport);
  4002. _sgimgui_frame_stats(num_apply_scissor_rect);
  4003. _sgimgui_frame_stats(num_apply_pipeline);
  4004. _sgimgui_frame_stats(num_apply_bindings);
  4005. _sgimgui_frame_stats(num_apply_uniforms);
  4006. _sgimgui_frame_stats(num_draw);
  4007. _sgimgui_frame_stats(num_dispatch);
  4008. _sgimgui_frame_stats(num_update_buffer);
  4009. _sgimgui_frame_stats(num_append_buffer);
  4010. _sgimgui_frame_stats(num_update_image);
  4011. _sgimgui_frame_stats(size_apply_uniforms);
  4012. _sgimgui_frame_stats(size_update_buffer);
  4013. _sgimgui_frame_stats(size_append_buffer);
  4014. _sgimgui_frame_stats(size_update_image);
  4015. switch (sg_query_backend()) {
  4016. case SG_BACKEND_GLCORE:
  4017. case SG_BACKEND_GLES3:
  4018. _sgimgui_frame_stats(gl.num_bind_buffer);
  4019. _sgimgui_frame_stats(gl.num_active_texture);
  4020. _sgimgui_frame_stats(gl.num_bind_texture);
  4021. _sgimgui_frame_stats(gl.num_bind_sampler);
  4022. _sgimgui_frame_stats(gl.num_use_program);
  4023. _sgimgui_frame_stats(gl.num_render_state);
  4024. _sgimgui_frame_stats(gl.num_vertex_attrib_pointer);
  4025. _sgimgui_frame_stats(gl.num_vertex_attrib_divisor);
  4026. _sgimgui_frame_stats(gl.num_enable_vertex_attrib_array);
  4027. _sgimgui_frame_stats(gl.num_disable_vertex_attrib_array);
  4028. _sgimgui_frame_stats(gl.num_uniform);
  4029. _sgimgui_frame_stats(gl.num_memory_barriers);
  4030. break;
  4031. case SG_BACKEND_WGPU:
  4032. _sgimgui_frame_stats(wgpu.uniforms.num_set_bindgroup);
  4033. _sgimgui_frame_stats(wgpu.uniforms.size_write_buffer);
  4034. _sgimgui_frame_stats(wgpu.bindings.num_set_vertex_buffer);
  4035. _sgimgui_frame_stats(wgpu.bindings.num_skip_redundant_vertex_buffer);
  4036. _sgimgui_frame_stats(wgpu.bindings.num_set_index_buffer);
  4037. _sgimgui_frame_stats(wgpu.bindings.num_skip_redundant_index_buffer);
  4038. _sgimgui_frame_stats(wgpu.bindings.num_create_bindgroup);
  4039. _sgimgui_frame_stats(wgpu.bindings.num_discard_bindgroup);
  4040. _sgimgui_frame_stats(wgpu.bindings.num_set_bindgroup);
  4041. _sgimgui_frame_stats(wgpu.bindings.num_skip_redundant_bindgroup);
  4042. _sgimgui_frame_stats(wgpu.bindings.num_bindgroup_cache_hits);
  4043. _sgimgui_frame_stats(wgpu.bindings.num_bindgroup_cache_misses);
  4044. _sgimgui_frame_stats(wgpu.bindings.num_bindgroup_cache_collisions);
  4045. _sgimgui_frame_stats(wgpu.bindings.num_bindgroup_cache_invalidates);
  4046. _sgimgui_frame_stats(wgpu.bindings.num_bindgroup_cache_hash_vs_key_mismatch);
  4047. break;
  4048. case SG_BACKEND_METAL_MACOS:
  4049. case SG_BACKEND_METAL_IOS:
  4050. case SG_BACKEND_METAL_SIMULATOR:
  4051. _sgimgui_frame_stats(metal.idpool.num_added);
  4052. _sgimgui_frame_stats(metal.idpool.num_released);
  4053. _sgimgui_frame_stats(metal.idpool.num_garbage_collected);
  4054. _sgimgui_frame_stats(metal.pipeline.num_set_blend_color);
  4055. _sgimgui_frame_stats(metal.pipeline.num_set_cull_mode);
  4056. _sgimgui_frame_stats(metal.pipeline.num_set_front_facing_winding);
  4057. _sgimgui_frame_stats(metal.pipeline.num_set_stencil_reference_value);
  4058. _sgimgui_frame_stats(metal.pipeline.num_set_depth_bias);
  4059. _sgimgui_frame_stats(metal.pipeline.num_set_render_pipeline_state);
  4060. _sgimgui_frame_stats(metal.pipeline.num_set_depth_stencil_state);
  4061. _sgimgui_frame_stats(metal.bindings.num_set_vertex_buffer);
  4062. _sgimgui_frame_stats(metal.bindings.num_set_vertex_texture);
  4063. _sgimgui_frame_stats(metal.bindings.num_set_vertex_sampler_state);
  4064. _sgimgui_frame_stats(metal.bindings.num_set_fragment_buffer);
  4065. _sgimgui_frame_stats(metal.bindings.num_set_fragment_texture);
  4066. _sgimgui_frame_stats(metal.bindings.num_set_fragment_sampler_state);
  4067. _sgimgui_frame_stats(metal.bindings.num_set_compute_buffer);
  4068. _sgimgui_frame_stats(metal.bindings.num_set_compute_texture);
  4069. _sgimgui_frame_stats(metal.bindings.num_set_compute_sampler_state);
  4070. _sgimgui_frame_stats(metal.uniforms.num_set_vertex_buffer_offset);
  4071. _sgimgui_frame_stats(metal.uniforms.num_set_fragment_buffer_offset);
  4072. _sgimgui_frame_stats(metal.uniforms.num_set_compute_buffer_offset);
  4073. break;
  4074. case SG_BACKEND_D3D11:
  4075. _sgimgui_frame_stats(d3d11.pass.num_om_set_render_targets);
  4076. _sgimgui_frame_stats(d3d11.pass.num_clear_render_target_view);
  4077. _sgimgui_frame_stats(d3d11.pass.num_clear_depth_stencil_view);
  4078. _sgimgui_frame_stats(d3d11.pass.num_resolve_subresource);
  4079. _sgimgui_frame_stats(d3d11.pipeline.num_rs_set_state);
  4080. _sgimgui_frame_stats(d3d11.pipeline.num_om_set_depth_stencil_state);
  4081. _sgimgui_frame_stats(d3d11.pipeline.num_om_set_blend_state);
  4082. _sgimgui_frame_stats(d3d11.pipeline.num_ia_set_primitive_topology);
  4083. _sgimgui_frame_stats(d3d11.pipeline.num_ia_set_input_layout);
  4084. _sgimgui_frame_stats(d3d11.pipeline.num_vs_set_shader);
  4085. _sgimgui_frame_stats(d3d11.pipeline.num_vs_set_constant_buffers);
  4086. _sgimgui_frame_stats(d3d11.pipeline.num_ps_set_shader);
  4087. _sgimgui_frame_stats(d3d11.pipeline.num_ps_set_constant_buffers);
  4088. _sgimgui_frame_stats(d3d11.pipeline.num_cs_set_shader);
  4089. _sgimgui_frame_stats(d3d11.pipeline.num_cs_set_constant_buffers);
  4090. _sgimgui_frame_stats(d3d11.bindings.num_ia_set_vertex_buffers);
  4091. _sgimgui_frame_stats(d3d11.bindings.num_ia_set_index_buffer);
  4092. _sgimgui_frame_stats(d3d11.bindings.num_vs_set_shader_resources);
  4093. _sgimgui_frame_stats(d3d11.bindings.num_ps_set_shader_resources);
  4094. _sgimgui_frame_stats(d3d11.bindings.num_cs_set_shader_resources);
  4095. _sgimgui_frame_stats(d3d11.bindings.num_vs_set_samplers);
  4096. _sgimgui_frame_stats(d3d11.bindings.num_ps_set_samplers);
  4097. _sgimgui_frame_stats(d3d11.bindings.num_cs_set_samplers);
  4098. _sgimgui_frame_stats(d3d11.bindings.num_cs_set_unordered_access_views);
  4099. _sgimgui_frame_stats(d3d11.uniforms.num_update_subresource);
  4100. _sgimgui_frame_stats(d3d11.draw.num_draw_indexed_instanced);
  4101. _sgimgui_frame_stats(d3d11.draw.num_draw_indexed);
  4102. _sgimgui_frame_stats(d3d11.draw.num_draw_instanced);
  4103. _sgimgui_frame_stats(d3d11.draw.num_draw);
  4104. _sgimgui_frame_stats(d3d11.num_map);
  4105. _sgimgui_frame_stats(d3d11.num_unmap);
  4106. break;
  4107. default: break;
  4108. }
  4109. igEndTable();
  4110. }
  4111. }
  4112. #define _sgimgui_def(val, def) (((val) == 0) ? (def) : (val))
  4113. _SOKOL_PRIVATE sgimgui_desc_t _sgimgui_desc_defaults(const sgimgui_desc_t* desc) {
  4114. SOKOL_ASSERT((desc->allocator.alloc_fn && desc->allocator.free_fn) || (!desc->allocator.alloc_fn && !desc->allocator.free_fn));
  4115. sgimgui_desc_t res = *desc;
  4116. // FIXME: any additional default overrides would go here
  4117. return res;
  4118. }
  4119. /*--- PUBLIC FUNCTIONS -------------------------------------------------------*/
  4120. SOKOL_API_IMPL void sgimgui_init(sgimgui_t* ctx, const sgimgui_desc_t* desc) {
  4121. SOKOL_ASSERT(ctx && desc);
  4122. _sgimgui_clear(ctx, sizeof(sgimgui_t));
  4123. ctx->init_tag = 0xABCDABCD;
  4124. ctx->desc = _sgimgui_desc_defaults(desc);
  4125. _sgimgui_capture_init(ctx);
  4126. /* hook into sokol_gfx functions */
  4127. sg_trace_hooks hooks;
  4128. _sgimgui_clear(&hooks, sizeof(hooks));
  4129. hooks.user_data = (void*) ctx;
  4130. hooks.reset_state_cache = _sgimgui_reset_state_cache;
  4131. hooks.make_buffer = _sgimgui_make_buffer;
  4132. hooks.make_image = _sgimgui_make_image;
  4133. hooks.make_sampler = _sgimgui_make_sampler;
  4134. hooks.make_shader = _sgimgui_make_shader;
  4135. hooks.make_pipeline = _sgimgui_make_pipeline;
  4136. hooks.make_attachments = _sgimgui_make_attachments;
  4137. hooks.destroy_buffer = _sgimgui_destroy_buffer;
  4138. hooks.destroy_image = _sgimgui_destroy_image;
  4139. hooks.destroy_sampler = _sgimgui_destroy_sampler;
  4140. hooks.destroy_shader = _sgimgui_destroy_shader;
  4141. hooks.destroy_pipeline = _sgimgui_destroy_pipeline;
  4142. hooks.destroy_attachments = _sgimgui_destroy_attachments;
  4143. hooks.update_buffer = _sgimgui_update_buffer;
  4144. hooks.update_image = _sgimgui_update_image;
  4145. hooks.append_buffer = _sgimgui_append_buffer;
  4146. hooks.begin_pass = _sgimgui_begin_pass;
  4147. hooks.apply_viewport = _sgimgui_apply_viewport;
  4148. hooks.apply_scissor_rect = _sgimgui_apply_scissor_rect;
  4149. hooks.apply_pipeline = _sgimgui_apply_pipeline;
  4150. hooks.apply_bindings = _sgimgui_apply_bindings;
  4151. hooks.apply_uniforms = _sgimgui_apply_uniforms;
  4152. hooks.draw = _sgimgui_draw;
  4153. hooks.dispatch = _sgimgui_dispatch;
  4154. hooks.end_pass = _sgimgui_end_pass;
  4155. hooks.commit = _sgimgui_commit;
  4156. hooks.alloc_buffer = _sgimgui_alloc_buffer;
  4157. hooks.alloc_image = _sgimgui_alloc_image;
  4158. hooks.alloc_sampler = _sgimgui_alloc_sampler;
  4159. hooks.alloc_shader = _sgimgui_alloc_shader;
  4160. hooks.alloc_pipeline = _sgimgui_alloc_pipeline;
  4161. hooks.alloc_attachments = _sgimgui_alloc_attachments;
  4162. hooks.dealloc_buffer = _sgimgui_dealloc_buffer;
  4163. hooks.dealloc_image = _sgimgui_dealloc_image;
  4164. hooks.dealloc_sampler = _sgimgui_dealloc_sampler;
  4165. hooks.dealloc_shader = _sgimgui_dealloc_shader;
  4166. hooks.dealloc_pipeline = _sgimgui_dealloc_pipeline;
  4167. hooks.dealloc_attachments = _sgimgui_dealloc_attachments;
  4168. hooks.init_buffer = _sgimgui_init_buffer;
  4169. hooks.init_image = _sgimgui_init_image;
  4170. hooks.init_sampler = _sgimgui_init_sampler;
  4171. hooks.init_shader = _sgimgui_init_shader;
  4172. hooks.init_pipeline = _sgimgui_init_pipeline;
  4173. hooks.init_attachments = _sgimgui_init_attachments;
  4174. hooks.uninit_buffer = _sgimgui_uninit_buffer;
  4175. hooks.uninit_image = _sgimgui_uninit_image;
  4176. hooks.uninit_sampler = _sgimgui_uninit_sampler;
  4177. hooks.uninit_shader = _sgimgui_uninit_shader;
  4178. hooks.uninit_pipeline = _sgimgui_uninit_pipeline;
  4179. hooks.uninit_attachments = _sgimgui_uninit_attachments;
  4180. hooks.fail_buffer = _sgimgui_fail_buffer;
  4181. hooks.fail_image = _sgimgui_fail_image;
  4182. hooks.fail_sampler = _sgimgui_fail_sampler;
  4183. hooks.fail_shader = _sgimgui_fail_shader;
  4184. hooks.fail_pipeline = _sgimgui_fail_pipeline;
  4185. hooks.fail_attachments = _sgimgui_fail_attachments;
  4186. hooks.push_debug_group = _sgimgui_push_debug_group;
  4187. hooks.pop_debug_group = _sgimgui_pop_debug_group;
  4188. ctx->hooks = sg_install_trace_hooks(&hooks);
  4189. /* allocate resource debug-info slots */
  4190. const sg_desc sgdesc = sg_query_desc();
  4191. ctx->buffer_window.num_slots = sgdesc.buffer_pool_size;
  4192. ctx->image_window.num_slots = sgdesc.image_pool_size;
  4193. ctx->sampler_window.num_slots = sgdesc.sampler_pool_size;
  4194. ctx->shader_window.num_slots = sgdesc.shader_pool_size;
  4195. ctx->pipeline_window.num_slots = sgdesc.pipeline_pool_size;
  4196. ctx->attachments_window.num_slots = sgdesc.attachments_pool_size;
  4197. const size_t buffer_pool_size = (size_t)ctx->buffer_window.num_slots * sizeof(sgimgui_buffer_t);
  4198. ctx->buffer_window.slots = (sgimgui_buffer_t*) _sgimgui_malloc_clear(&ctx->desc.allocator, buffer_pool_size);
  4199. const size_t image_pool_size = (size_t)ctx->image_window.num_slots * sizeof(sgimgui_image_t);
  4200. ctx->image_window.slots = (sgimgui_image_t*) _sgimgui_malloc_clear(&ctx->desc.allocator, image_pool_size);
  4201. const size_t sampler_pool_size = (size_t)ctx->sampler_window.num_slots * sizeof(sgimgui_sampler_t);
  4202. ctx->sampler_window.slots = (sgimgui_sampler_t*) _sgimgui_malloc_clear(&ctx->desc.allocator, sampler_pool_size);
  4203. const size_t shader_pool_size = (size_t)ctx->shader_window.num_slots * sizeof(sgimgui_shader_t);
  4204. ctx->shader_window.slots = (sgimgui_shader_t*) _sgimgui_malloc_clear(&ctx->desc.allocator, shader_pool_size);
  4205. const size_t pipeline_pool_size = (size_t)ctx->pipeline_window.num_slots * sizeof(sgimgui_pipeline_t);
  4206. ctx->pipeline_window.slots = (sgimgui_pipeline_t*) _sgimgui_malloc_clear(&ctx->desc.allocator, pipeline_pool_size);
  4207. const size_t attachments_pool_size = (size_t)ctx->attachments_window.num_slots * sizeof(sgimgui_attachments_t);
  4208. ctx->attachments_window.slots = (sgimgui_attachments_t*) _sgimgui_malloc_clear(&ctx->desc.allocator, attachments_pool_size);
  4209. }
  4210. SOKOL_API_IMPL void sgimgui_discard(sgimgui_t* ctx) {
  4211. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4212. /* restore original trace hooks */
  4213. sg_install_trace_hooks(&ctx->hooks);
  4214. ctx->init_tag = 0;
  4215. _sgimgui_capture_discard(ctx);
  4216. if (ctx->buffer_window.slots) {
  4217. for (int i = 0; i < ctx->buffer_window.num_slots; i++) {
  4218. if (ctx->buffer_window.slots[i].res_id.id != SG_INVALID_ID) {
  4219. _sgimgui_buffer_destroyed(ctx, i);
  4220. }
  4221. }
  4222. _sgimgui_free(&ctx->desc.allocator, (void*)ctx->buffer_window.slots);
  4223. ctx->buffer_window.slots = 0;
  4224. }
  4225. if (ctx->image_window.slots) {
  4226. for (int i = 0; i < ctx->image_window.num_slots; i++) {
  4227. if (ctx->image_window.slots[i].res_id.id != SG_INVALID_ID) {
  4228. _sgimgui_image_destroyed(ctx, i);
  4229. }
  4230. }
  4231. _sgimgui_free(&ctx->desc.allocator, (void*)ctx->image_window.slots);
  4232. ctx->image_window.slots = 0;
  4233. }
  4234. if (ctx->sampler_window.slots) {
  4235. for (int i = 0; i < ctx->sampler_window.num_slots; i++) {
  4236. if (ctx->sampler_window.slots[i].res_id.id != SG_INVALID_ID) {
  4237. _sgimgui_sampler_destroyed(ctx, i);
  4238. }
  4239. }
  4240. _sgimgui_free(&ctx->desc.allocator, (void*)ctx->sampler_window.slots);
  4241. ctx->sampler_window.slots = 0;
  4242. }
  4243. if (ctx->shader_window.slots) {
  4244. for (int i = 0; i < ctx->shader_window.num_slots; i++) {
  4245. if (ctx->shader_window.slots[i].res_id.id != SG_INVALID_ID) {
  4246. _sgimgui_shader_destroyed(ctx, i);
  4247. }
  4248. }
  4249. _sgimgui_free(&ctx->desc.allocator, (void*)ctx->shader_window.slots);
  4250. ctx->shader_window.slots = 0;
  4251. }
  4252. if (ctx->pipeline_window.slots) {
  4253. for (int i = 0; i < ctx->pipeline_window.num_slots; i++) {
  4254. if (ctx->pipeline_window.slots[i].res_id.id != SG_INVALID_ID) {
  4255. _sgimgui_pipeline_destroyed(ctx, i);
  4256. }
  4257. }
  4258. _sgimgui_free(&ctx->desc.allocator, (void*)ctx->pipeline_window.slots);
  4259. ctx->pipeline_window.slots = 0;
  4260. }
  4261. if (ctx->attachments_window.slots) {
  4262. for (int i = 0; i < ctx->attachments_window.num_slots; i++) {
  4263. if (ctx->attachments_window.slots[i].res_id.id != SG_INVALID_ID) {
  4264. _sgimgui_attachments_destroyed(ctx, i);
  4265. }
  4266. }
  4267. _sgimgui_free(&ctx->desc.allocator, (void*)ctx->attachments_window.slots);
  4268. ctx->attachments_window.slots = 0;
  4269. }
  4270. }
  4271. SOKOL_API_IMPL void sgimgui_draw(sgimgui_t* ctx) {
  4272. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4273. sgimgui_draw_buffer_window(ctx);
  4274. sgimgui_draw_image_window(ctx);
  4275. sgimgui_draw_sampler_window(ctx);
  4276. sgimgui_draw_shader_window(ctx);
  4277. sgimgui_draw_pipeline_window(ctx);
  4278. sgimgui_draw_attachments_window(ctx);
  4279. sgimgui_draw_capture_window(ctx);
  4280. sgimgui_draw_capabilities_window(ctx);
  4281. sgimgui_draw_frame_stats_window(ctx);
  4282. }
  4283. SOKOL_API_IMPL void sgimgui_draw_menu(sgimgui_t* ctx, const char* title) {
  4284. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4285. SOKOL_ASSERT(title);
  4286. if (igBeginMenu(title)) {
  4287. igMenuItemBoolPtr("Capabilities", 0, &ctx->caps_window.open, true);
  4288. igMenuItemBoolPtr("Frame Stats", 0, &ctx->frame_stats_window.open, true);
  4289. igMenuItemBoolPtr("Buffers", 0, &ctx->buffer_window.open, true);
  4290. igMenuItemBoolPtr("Images", 0, &ctx->image_window.open, true);
  4291. igMenuItemBoolPtr("Samplers", 0, &ctx->sampler_window.open, true);
  4292. igMenuItemBoolPtr("Shaders", 0, &ctx->shader_window.open, true);
  4293. igMenuItemBoolPtr("Pipelines", 0, &ctx->pipeline_window.open, true);
  4294. igMenuItemBoolPtr("Attachments", 0, &ctx->attachments_window.open, true);
  4295. igMenuItemBoolPtr("Calls", 0, &ctx->capture_window.open, true);
  4296. igEndMenu();
  4297. }
  4298. }
  4299. SOKOL_API_IMPL void sgimgui_draw_buffer_window(sgimgui_t* ctx) {
  4300. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4301. if (!ctx->buffer_window.open) {
  4302. return;
  4303. }
  4304. igSetNextWindowSize(IMVEC2(440, 280), ImGuiCond_Once);
  4305. if (igBegin("Buffers", &ctx->buffer_window.open, 0)) {
  4306. sgimgui_draw_buffer_window_content(ctx);
  4307. }
  4308. igEnd();
  4309. }
  4310. SOKOL_API_IMPL void sgimgui_draw_image_window(sgimgui_t* ctx) {
  4311. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4312. if (!ctx->image_window.open) {
  4313. return;
  4314. }
  4315. igSetNextWindowSize(IMVEC2(440, 400), ImGuiCond_Once);
  4316. if (igBegin("Images", &ctx->image_window.open, 0)) {
  4317. sgimgui_draw_image_window_content(ctx);
  4318. }
  4319. igEnd();
  4320. }
  4321. SOKOL_API_IMPL void sgimgui_draw_sampler_window(sgimgui_t* ctx) {
  4322. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4323. if (!ctx->sampler_window.open) {
  4324. return;
  4325. }
  4326. igSetNextWindowSize(IMVEC2(440, 400), ImGuiCond_Once);
  4327. if (igBegin("Samplers", &ctx->sampler_window.open, 0)) {
  4328. sgimgui_draw_sampler_window_content(ctx);
  4329. }
  4330. igEnd();
  4331. }
  4332. SOKOL_API_IMPL void sgimgui_draw_shader_window(sgimgui_t* ctx) {
  4333. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4334. if (!ctx->shader_window.open) {
  4335. return;
  4336. }
  4337. igSetNextWindowSize(IMVEC2(440, 400), ImGuiCond_Once);
  4338. if (igBegin("Shaders", &ctx->shader_window.open, 0)) {
  4339. sgimgui_draw_shader_window_content(ctx);
  4340. }
  4341. igEnd();
  4342. }
  4343. SOKOL_API_IMPL void sgimgui_draw_pipeline_window(sgimgui_t* ctx) {
  4344. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4345. if (!ctx->pipeline_window.open) {
  4346. return;
  4347. }
  4348. igSetNextWindowSize(IMVEC2(540, 400), ImGuiCond_Once);
  4349. if (igBegin("Pipelines", &ctx->pipeline_window.open, 0)) {
  4350. sgimgui_draw_pipeline_window_content(ctx);
  4351. }
  4352. igEnd();
  4353. }
  4354. SOKOL_API_IMPL void sgimgui_draw_attachments_window(sgimgui_t* ctx) {
  4355. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4356. if (!ctx->attachments_window.open) {
  4357. return;
  4358. }
  4359. igSetNextWindowSize(IMVEC2(440, 400), ImGuiCond_Once);
  4360. if (igBegin("Attachments", &ctx->attachments_window.open, 0)) {
  4361. sgimgui_draw_attachments_window_content(ctx);
  4362. }
  4363. igEnd();
  4364. }
  4365. SOKOL_API_IMPL void sgimgui_draw_capture_window(sgimgui_t* ctx) {
  4366. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4367. if (!ctx->capture_window.open) {
  4368. return;
  4369. }
  4370. igSetNextWindowSize(IMVEC2(640, 400), ImGuiCond_Once);
  4371. if (igBegin("Frame Capture", &ctx->capture_window.open, 0)) {
  4372. sgimgui_draw_capture_window_content(ctx);
  4373. }
  4374. igEnd();
  4375. }
  4376. SOKOL_API_IMPL void sgimgui_draw_capabilities_window(sgimgui_t* ctx) {
  4377. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4378. if (!ctx->caps_window.open) {
  4379. return;
  4380. }
  4381. igSetNextWindowSize(IMVEC2(440, 400), ImGuiCond_Once);
  4382. if (igBegin("Capabilities", &ctx->caps_window.open, 0)) {
  4383. sgimgui_draw_capabilities_window_content(ctx);
  4384. }
  4385. igEnd();
  4386. }
  4387. SOKOL_API_IMPL void sgimgui_draw_frame_stats_window(sgimgui_t* ctx) {
  4388. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4389. if (!ctx->frame_stats_window.open) {
  4390. return;
  4391. }
  4392. igSetNextWindowSize(IMVEC2(512, 400), ImGuiCond_Once);
  4393. if (igBegin("Frame Stats", &ctx->frame_stats_window.open, 0)) {
  4394. sgimgui_draw_frame_stats_window_content(ctx);
  4395. }
  4396. igEnd();
  4397. }
  4398. SOKOL_API_IMPL void sgimgui_draw_buffer_window_content(sgimgui_t* ctx) {
  4399. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4400. _sgimgui_draw_buffer_list(ctx);
  4401. igSameLine();
  4402. _sgimgui_draw_buffer_panel(ctx, ctx->buffer_window.sel_buf);
  4403. }
  4404. SOKOL_API_IMPL void sgimgui_draw_image_window_content(sgimgui_t* ctx) {
  4405. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4406. _sgimgui_draw_image_list(ctx);
  4407. igSameLine();
  4408. _sgimgui_draw_image_panel(ctx, ctx->image_window.sel_img);
  4409. }
  4410. SOKOL_API_IMPL void sgimgui_draw_sampler_window_content(sgimgui_t* ctx) {
  4411. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4412. _sgimgui_draw_sampler_list(ctx);
  4413. igSameLine();
  4414. _sgimgui_draw_sampler_panel(ctx, ctx->sampler_window.sel_smp);
  4415. }
  4416. SOKOL_API_IMPL void sgimgui_draw_shader_window_content(sgimgui_t* ctx) {
  4417. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4418. _sgimgui_draw_shader_list(ctx);
  4419. igSameLine();
  4420. _sgimgui_draw_shader_panel(ctx, ctx->shader_window.sel_shd);
  4421. }
  4422. SOKOL_API_IMPL void sgimgui_draw_pipeline_window_content(sgimgui_t* ctx) {
  4423. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4424. _sgimgui_draw_pipeline_list(ctx);
  4425. igSameLine();
  4426. _sgimgui_draw_pipeline_panel(ctx, ctx->pipeline_window.sel_pip);
  4427. }
  4428. SOKOL_API_IMPL void sgimgui_draw_attachments_window_content(sgimgui_t* ctx) {
  4429. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4430. _sgimgui_draw_attachments_list(ctx);
  4431. igSameLine();
  4432. _sgimgui_draw_attachments_panel(ctx, ctx->attachments_window.sel_atts);
  4433. }
  4434. SOKOL_API_IMPL void sgimgui_draw_capture_window_content(sgimgui_t* ctx) {
  4435. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4436. _sgimgui_draw_capture_list(ctx);
  4437. igSameLine();
  4438. _sgimgui_draw_capture_panel(ctx);
  4439. }
  4440. SOKOL_API_IMPL void sgimgui_draw_capabilities_window_content(sgimgui_t* ctx) {
  4441. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4442. _SOKOL_UNUSED(ctx);
  4443. _sgimgui_draw_caps_panel();
  4444. }
  4445. SOKOL_API_IMPL void sgimgui_draw_frame_stats_window_content(sgimgui_t* ctx) {
  4446. SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
  4447. ctx->frame_stats_window.stats = sg_query_frame_stats();
  4448. _sgimgui_draw_frame_stats_panel(ctx);
  4449. }
  4450. #endif /* SOKOL_GFX_IMGUI_IMPL */