bgfx.cpp 111 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967
  1. /*
  2. * Copyright 2011-2015 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include "bgfx_p.h"
  6. namespace bgfx
  7. {
  8. #define BGFX_MAIN_THREAD_MAGIC UINT32_C(0x78666762)
  9. #if BGFX_CONFIG_MULTITHREADED && !BX_PLATFORM_OSX && !BX_PLATFORM_IOS
  10. # define BGFX_CHECK_MAIN_THREAD() \
  11. BX_CHECK(NULL != s_ctx, "Library is not initialized yet."); \
  12. BX_CHECK(BGFX_MAIN_THREAD_MAGIC == s_threadIndex, "Must be called from main thread.")
  13. # define BGFX_CHECK_RENDER_THREAD() BX_CHECK(BGFX_MAIN_THREAD_MAGIC != s_threadIndex, "Must be called from render thread.")
  14. #else
  15. # define BGFX_CHECK_MAIN_THREAD()
  16. # define BGFX_CHECK_RENDER_THREAD()
  17. #endif // BGFX_CONFIG_MULTITHREADED && !BX_PLATFORM_OSX && !BX_PLATFORM_IOS
  18. #if BGFX_CONFIG_USE_TINYSTL
  19. void* TinyStlAllocator::static_allocate(size_t _bytes)
  20. {
  21. return BX_ALLOC(g_allocator, _bytes);
  22. }
  23. void TinyStlAllocator::static_deallocate(void* _ptr, size_t /*_bytes*/)
  24. {
  25. if (NULL != _ptr)
  26. {
  27. BX_FREE(g_allocator, _ptr);
  28. }
  29. }
  30. #endif // BGFX_CONFIG_USE_TINYSTL
  31. struct CallbackStub : public CallbackI
  32. {
  33. virtual ~CallbackStub()
  34. {
  35. }
  36. virtual void traceVargs(const char* _filePath, uint16_t _line, const char* _format, va_list _argList) BX_OVERRIDE
  37. {
  38. dbgPrintf("%s (%d): ", _filePath, _line);
  39. dbgPrintfVargs(_format, _argList);
  40. }
  41. virtual void fatal(Fatal::Enum _code, const char* _str) BX_OVERRIDE
  42. {
  43. if (Fatal::DebugCheck == _code)
  44. {
  45. bx::debugBreak();
  46. }
  47. else
  48. {
  49. BX_TRACE("0x%08x: %s", _code, _str);
  50. BX_UNUSED(_code, _str);
  51. abort();
  52. }
  53. }
  54. virtual uint32_t cacheReadSize(uint64_t /*_id*/) BX_OVERRIDE
  55. {
  56. return 0;
  57. }
  58. virtual bool cacheRead(uint64_t /*_id*/, void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
  59. {
  60. return false;
  61. }
  62. virtual void cacheWrite(uint64_t /*_id*/, const void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
  63. {
  64. }
  65. virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t _size, bool _yflip) BX_OVERRIDE
  66. {
  67. BX_UNUSED(_filePath, _width, _height, _pitch, _data, _size, _yflip);
  68. #if BX_CONFIG_CRT_FILE_READER_WRITER
  69. char* filePath = (char*)alloca(strlen(_filePath)+5);
  70. strcpy(filePath, _filePath);
  71. strcat(filePath, ".tga");
  72. bx::CrtFileWriter writer;
  73. if (0 == writer.open(filePath) )
  74. {
  75. imageWriteTga(&writer, _width, _height, _pitch, _data, false, _yflip);
  76. writer.close();
  77. }
  78. #endif // BX_CONFIG_CRT_FILE_READER_WRITER
  79. }
  80. virtual void captureBegin(uint32_t /*_width*/, uint32_t /*_height*/, uint32_t /*_pitch*/, TextureFormat::Enum /*_format*/, bool /*_yflip*/) BX_OVERRIDE
  81. {
  82. BX_TRACE("Warning: using capture without callback (a.k.a. pointless).");
  83. }
  84. virtual void captureEnd() BX_OVERRIDE
  85. {
  86. }
  87. virtual void captureFrame(const void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
  88. {
  89. }
  90. };
  91. #ifndef BGFX_CONFIG_MEMORY_TRACKING
  92. # define BGFX_CONFIG_MEMORY_TRACKING (BGFX_CONFIG_DEBUG && BX_CONFIG_SUPPORTS_THREADING)
  93. #endif // BGFX_CONFIG_MEMORY_TRACKING
  94. class AllocatorStub : public bx::ReallocatorI
  95. {
  96. public:
  97. AllocatorStub()
  98. #if BGFX_CONFIG_MEMORY_TRACKING
  99. : m_numBlocks(0)
  100. , m_maxBlocks(0)
  101. #endif // BGFX_CONFIG_MEMORY_TRACKING
  102. {
  103. }
  104. virtual void* alloc(size_t _size, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE
  105. {
  106. if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
  107. {
  108. #if BGFX_CONFIG_MEMORY_TRACKING
  109. {
  110. bx::LwMutexScope scope(m_mutex);
  111. ++m_numBlocks;
  112. m_maxBlocks = bx::uint32_max(m_maxBlocks, m_numBlocks);
  113. }
  114. #endif // BGFX_CONFIG_MEMORY_TRACKING
  115. return ::malloc(_size);
  116. }
  117. return bx::alignedAlloc(this, _size, _align, _file, _line);
  118. }
  119. virtual void free(void* _ptr, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE
  120. {
  121. if (NULL != _ptr)
  122. {
  123. if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
  124. {
  125. #if BGFX_CONFIG_MEMORY_TRACKING
  126. {
  127. bx::LwMutexScope scope(m_mutex);
  128. BX_CHECK(m_numBlocks > 0, "Number of blocks is 0. Possible alloc/free mismatch?");
  129. --m_numBlocks;
  130. }
  131. #endif // BGFX_CONFIG_MEMORY_TRACKING
  132. ::free(_ptr);
  133. }
  134. else
  135. {
  136. bx::alignedFree(this, _ptr, _align, _file, _line);
  137. }
  138. }
  139. }
  140. virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE
  141. {
  142. if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
  143. {
  144. #if BGFX_CONFIG_MEMORY_TRACKING
  145. if (NULL == _ptr)
  146. {
  147. bx::LwMutexScope scope(m_mutex);
  148. ++m_numBlocks;
  149. m_maxBlocks = bx::uint32_max(m_maxBlocks, m_numBlocks);
  150. }
  151. #endif // BGFX_CONFIG_MEMORY_TRACKING
  152. return ::realloc(_ptr, _size);
  153. }
  154. return bx::alignedRealloc(this, _ptr, _size, _align, _file, _line);
  155. }
  156. void checkLeaks()
  157. {
  158. #if BGFX_CONFIG_MEMORY_TRACKING
  159. BX_WARN(0 == m_numBlocks, "MEMORY LEAK: %d (max: %d)", m_numBlocks, m_maxBlocks);
  160. #endif // BGFX_CONFIG_MEMORY_TRACKING
  161. }
  162. protected:
  163. #if BGFX_CONFIG_MEMORY_TRACKING
  164. bx::LwMutex m_mutex;
  165. uint32_t m_numBlocks;
  166. uint32_t m_maxBlocks;
  167. #endif // BGFX_CONFIG_MEMORY_TRACKING
  168. };
  169. static CallbackStub* s_callbackStub = NULL;
  170. static AllocatorStub* s_allocatorStub = NULL;
  171. static bool s_graphicsDebuggerPresent = false;
  172. CallbackI* g_callback = NULL;
  173. bx::ReallocatorI* g_allocator = NULL;
  174. Caps g_caps;
  175. static BX_THREAD uint32_t s_threadIndex = 0;
  176. static Context* s_ctx = NULL;
  177. static bool s_renderFrameCalled = false;
  178. PlatformData g_platformData;
  179. void setPlatformData(const PlatformData& _pd)
  180. {
  181. if (NULL != s_ctx)
  182. {
  183. BGFX_FATAL(true
  184. && g_platformData.ndt == _pd.ndt
  185. && g_platformData.nwh == _pd.nwh
  186. && g_platformData.context == _pd.context
  187. , Fatal::UnableToInitialize
  188. , "Only backbuffer pointer can be changed after initialization!"
  189. );
  190. }
  191. memcpy(&g_platformData, &_pd, sizeof(PlatformData) );
  192. }
  193. void setGraphicsDebuggerPresent(bool _present)
  194. {
  195. BX_TRACE("Graphics debugger is %spresent.", _present ? "" : "not ");
  196. s_graphicsDebuggerPresent = _present;
  197. }
  198. bool isGraphicsDebuggerPresent()
  199. {
  200. return s_graphicsDebuggerPresent;
  201. }
  202. void fatal(Fatal::Enum _code, const char* _format, ...)
  203. {
  204. char temp[8192];
  205. va_list argList;
  206. va_start(argList, _format);
  207. char* out = temp;
  208. int32_t len = bx::vsnprintf(out, sizeof(temp), _format, argList);
  209. if ( (int32_t)sizeof(temp) < len)
  210. {
  211. out = (char*)alloca(len+1);
  212. len = bx::vsnprintf(out, len, _format, argList);
  213. }
  214. out[len] = '\0';
  215. va_end(argList);
  216. g_callback->fatal(_code, out);
  217. }
  218. void trace(const char* _filePath, uint16_t _line, const char* _format, ...)
  219. {
  220. va_list argList;
  221. va_start(argList, _format);
  222. g_callback->traceVargs(_filePath, _line, _format, argList);
  223. va_end(argList);
  224. }
  225. #include "charset.h"
  226. void charsetFillTexture(const uint8_t* _charset, uint8_t* _rgba, uint32_t _height, uint32_t _pitch, uint32_t _bpp)
  227. {
  228. for (uint32_t ii = 0; ii < 256; ++ii)
  229. {
  230. uint8_t* pix = &_rgba[ii*8*_bpp];
  231. for (uint32_t yy = 0; yy < _height; ++yy)
  232. {
  233. for (uint32_t xx = 0; xx < 8; ++xx)
  234. {
  235. uint8_t bit = 1<<(7-xx);
  236. memset(&pix[xx*_bpp], _charset[ii*_height+yy]&bit ? 255 : 0, _bpp);
  237. }
  238. pix += _pitch;
  239. }
  240. }
  241. }
  242. static const uint32_t numCharsPerBatch = 1024;
  243. static const uint32_t numBatchVertices = numCharsPerBatch*4;
  244. static const uint32_t numBatchIndices = numCharsPerBatch*6;
  245. void TextVideoMemBlitter::init()
  246. {
  247. BGFX_CHECK_MAIN_THREAD();
  248. m_decl
  249. .begin()
  250. .add(Attrib::Position, 3, AttribType::Float)
  251. .add(Attrib::Color0, 4, AttribType::Uint8, true)
  252. .add(Attrib::Color1, 4, AttribType::Uint8, true)
  253. .add(Attrib::TexCoord0, 2, AttribType::Float)
  254. .end();
  255. uint16_t width = 2048;
  256. uint16_t height = 24;
  257. uint8_t bpp = 1;
  258. uint32_t pitch = width*bpp;
  259. const Memory* mem;
  260. mem = alloc(pitch*height);
  261. uint8_t* rgba = mem->data;
  262. charsetFillTexture(vga8x8, rgba, 8, pitch, bpp);
  263. charsetFillTexture(vga8x16, &rgba[8*pitch], 16, pitch, bpp);
  264. m_texture = createTexture2D(width, height, 1, TextureFormat::R8
  265. , BGFX_TEXTURE_MIN_POINT
  266. | BGFX_TEXTURE_MAG_POINT
  267. | BGFX_TEXTURE_MIP_POINT
  268. | BGFX_TEXTURE_U_CLAMP
  269. | BGFX_TEXTURE_V_CLAMP
  270. , mem
  271. );
  272. switch (g_caps.rendererType)
  273. {
  274. case RendererType::Direct3D9:
  275. mem = makeRef(vs_debugfont_dx9, sizeof(vs_debugfont_dx9) );
  276. break;
  277. case RendererType::Direct3D11:
  278. case RendererType::Direct3D12:
  279. mem = makeRef(vs_debugfont_dx11, sizeof(vs_debugfont_dx11) );
  280. break;
  281. default:
  282. mem = makeRef(vs_debugfont_glsl, sizeof(vs_debugfont_glsl) );
  283. break;
  284. }
  285. ShaderHandle vsh = createShader(mem);
  286. switch (g_caps.rendererType)
  287. {
  288. case RendererType::Direct3D9:
  289. mem = makeRef(fs_debugfont_dx9, sizeof(fs_debugfont_dx9) );
  290. break;
  291. case RendererType::Direct3D11:
  292. case RendererType::Direct3D12:
  293. mem = makeRef(fs_debugfont_dx11, sizeof(fs_debugfont_dx11) );
  294. break;
  295. default:
  296. mem = makeRef(fs_debugfont_glsl, sizeof(fs_debugfont_glsl) );
  297. break;
  298. }
  299. ShaderHandle fsh = createShader(mem);
  300. m_program = createProgram(vsh, fsh, true);
  301. m_vb = s_ctx->createTransientVertexBuffer(numBatchVertices*m_decl.m_stride, &m_decl);
  302. m_ib = s_ctx->createTransientIndexBuffer(numBatchIndices*2);
  303. }
  304. void TextVideoMemBlitter::shutdown()
  305. {
  306. BGFX_CHECK_MAIN_THREAD();
  307. destroyProgram(m_program);
  308. destroyTexture(m_texture);
  309. s_ctx->destroyTransientVertexBuffer(m_vb);
  310. s_ctx->destroyTransientIndexBuffer(m_ib);
  311. }
  312. void blit(RendererContextI* _renderCtx, TextVideoMemBlitter& _blitter, const TextVideoMem& _mem)
  313. {
  314. struct Vertex
  315. {
  316. float m_x;
  317. float m_y;
  318. float m_z;
  319. uint32_t m_fg;
  320. uint32_t m_bg;
  321. float m_u;
  322. float m_v;
  323. };
  324. static uint32_t palette[16] =
  325. {
  326. 0x0,
  327. 0xff0000cc,
  328. 0xff069a4e,
  329. 0xff00a0c4,
  330. 0xffa46534,
  331. 0xff7b5075,
  332. 0xff9a9806,
  333. 0xffcfd7d3,
  334. 0xff535755,
  335. 0xff2929ef,
  336. 0xff34e28a,
  337. 0xff4fe9fc,
  338. 0xffcf9f72,
  339. 0xffa87fad,
  340. 0xffe2e234,
  341. 0xffeceeee,
  342. };
  343. uint32_t yy = 0;
  344. uint32_t xx = 0;
  345. const float texelWidth = 1.0f/2048.0f;
  346. const float texelWidthHalf = RendererType::Direct3D9 == g_caps.rendererType ? 0.0f : texelWidth*0.5f;
  347. const float texelHeight = 1.0f/24.0f;
  348. const float texelHeightHalf = RendererType::Direct3D9 == g_caps.rendererType ? texelHeight*0.5f : 0.0f;
  349. const float utop = (_mem.m_small ? 0.0f : 8.0f)*texelHeight + texelHeightHalf;
  350. const float ubottom = (_mem.m_small ? 8.0f : 24.0f)*texelHeight + texelHeightHalf;
  351. const float fontHeight = (_mem.m_small ? 8.0f : 16.0f);
  352. _renderCtx->blitSetup(_blitter);
  353. for (;yy < _mem.m_height;)
  354. {
  355. Vertex* vertex = (Vertex*)_blitter.m_vb->data;
  356. uint16_t* indices = (uint16_t*)_blitter.m_ib->data;
  357. uint32_t startVertex = 0;
  358. uint32_t numIndices = 0;
  359. for (; yy < _mem.m_height && numIndices < numBatchIndices; ++yy)
  360. {
  361. xx = xx < _mem.m_width ? xx : 0;
  362. const uint8_t* line = &_mem.m_mem[(yy*_mem.m_width+xx)*2];
  363. for (; xx < _mem.m_width && numIndices < numBatchIndices; ++xx)
  364. {
  365. uint8_t ch = line[0];
  366. uint8_t attr = line[1];
  367. if (0 != (ch|attr)
  368. && (' ' != ch || 0 != (attr&0xf0) ) )
  369. {
  370. uint32_t fg = palette[attr&0xf];
  371. uint32_t bg = palette[(attr>>4)&0xf];
  372. Vertex vert[4] =
  373. {
  374. { (xx )*8.0f, (yy )*fontHeight, 0.0f, fg, bg, (ch )*8.0f*texelWidth - texelWidthHalf, utop },
  375. { (xx+1)*8.0f, (yy )*fontHeight, 0.0f, fg, bg, (ch+1)*8.0f*texelWidth - texelWidthHalf, utop },
  376. { (xx+1)*8.0f, (yy+1)*fontHeight, 0.0f, fg, bg, (ch+1)*8.0f*texelWidth - texelWidthHalf, ubottom },
  377. { (xx )*8.0f, (yy+1)*fontHeight, 0.0f, fg, bg, (ch )*8.0f*texelWidth - texelWidthHalf, ubottom },
  378. };
  379. memcpy(vertex, vert, sizeof(vert) );
  380. vertex += 4;
  381. indices[0] = uint16_t(startVertex+0);
  382. indices[1] = uint16_t(startVertex+1);
  383. indices[2] = uint16_t(startVertex+2);
  384. indices[3] = uint16_t(startVertex+2);
  385. indices[4] = uint16_t(startVertex+3);
  386. indices[5] = uint16_t(startVertex+0);
  387. startVertex += 4;
  388. indices += 6;
  389. numIndices += 6;
  390. }
  391. line += 2;
  392. }
  393. if (numIndices >= numBatchIndices)
  394. {
  395. break;
  396. }
  397. }
  398. _renderCtx->blitRender(_blitter, numIndices);
  399. }
  400. }
  401. void ClearQuad::init()
  402. {
  403. BGFX_CHECK_MAIN_THREAD();
  404. if (RendererType::Null != g_caps.rendererType)
  405. {
  406. m_decl
  407. .begin()
  408. .add(Attrib::Position, 3, AttribType::Float)
  409. .end();
  410. ShaderHandle vsh = BGFX_INVALID_HANDLE;
  411. struct Mem
  412. {
  413. Mem(const void* _data, size_t _size)
  414. : data(_data)
  415. , size(_size)
  416. {
  417. }
  418. const void* data;
  419. size_t size;
  420. };
  421. const Memory* fragMem[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  422. if (RendererType::Direct3D9 == g_caps.rendererType)
  423. {
  424. vsh = createShader(makeRef(vs_clear_dx9, sizeof(vs_clear_dx9) ) );
  425. const Mem mem[] =
  426. {
  427. Mem(fs_clear0_dx9, sizeof(fs_clear0_dx9) ),
  428. Mem(fs_clear1_dx9, sizeof(fs_clear1_dx9) ),
  429. Mem(fs_clear2_dx9, sizeof(fs_clear2_dx9) ),
  430. Mem(fs_clear3_dx9, sizeof(fs_clear3_dx9) ),
  431. Mem(fs_clear4_dx9, sizeof(fs_clear4_dx9) ),
  432. Mem(fs_clear5_dx9, sizeof(fs_clear5_dx9) ),
  433. Mem(fs_clear6_dx9, sizeof(fs_clear6_dx9) ),
  434. Mem(fs_clear7_dx9, sizeof(fs_clear7_dx9) ),
  435. };
  436. for (uint32_t ii = 0, num = g_caps.maxFBAttachments; ii < num; ++ii)
  437. {
  438. fragMem[ii] = makeRef(mem[ii].data, uint32_t(mem[ii].size) );
  439. }
  440. }
  441. else if (RendererType::Direct3D11 == g_caps.rendererType
  442. || RendererType::Direct3D12 == g_caps.rendererType)
  443. {
  444. vsh = createShader(makeRef(vs_clear_dx11, sizeof(vs_clear_dx11) ) );
  445. const Mem mem[] =
  446. {
  447. Mem(fs_clear0_dx11, sizeof(fs_clear0_dx11) ),
  448. Mem(fs_clear1_dx11, sizeof(fs_clear1_dx11) ),
  449. Mem(fs_clear2_dx11, sizeof(fs_clear2_dx11) ),
  450. Mem(fs_clear3_dx11, sizeof(fs_clear3_dx11) ),
  451. Mem(fs_clear4_dx11, sizeof(fs_clear4_dx11) ),
  452. Mem(fs_clear5_dx11, sizeof(fs_clear5_dx11) ),
  453. Mem(fs_clear6_dx11, sizeof(fs_clear6_dx11) ),
  454. Mem(fs_clear7_dx11, sizeof(fs_clear7_dx11) ),
  455. };
  456. for (uint32_t ii = 0, num = g_caps.maxFBAttachments; ii < num; ++ii)
  457. {
  458. fragMem[ii] = makeRef(mem[ii].data, uint32_t(mem[ii].size) );
  459. }
  460. }
  461. else if (RendererType::OpenGLES == g_caps.rendererType
  462. || RendererType::OpenGL == g_caps.rendererType)
  463. {
  464. vsh = createShader(makeRef(vs_clear_glsl, sizeof(vs_clear_glsl) ) );
  465. const Mem mem[] =
  466. {
  467. Mem(fs_clear0_glsl, sizeof(fs_clear0_glsl) ),
  468. Mem(fs_clear1_glsl, sizeof(fs_clear1_glsl) ),
  469. Mem(fs_clear2_glsl, sizeof(fs_clear2_glsl) ),
  470. Mem(fs_clear3_glsl, sizeof(fs_clear3_glsl) ),
  471. Mem(fs_clear4_glsl, sizeof(fs_clear4_glsl) ),
  472. Mem(fs_clear5_glsl, sizeof(fs_clear5_glsl) ),
  473. Mem(fs_clear6_glsl, sizeof(fs_clear6_glsl) ),
  474. Mem(fs_clear7_glsl, sizeof(fs_clear7_glsl) ),
  475. };
  476. for (uint32_t ii = 0, num = g_caps.maxFBAttachments; ii < num; ++ii)
  477. {
  478. fragMem[ii] = makeRef(mem[ii].data, uint32_t(mem[ii].size) );
  479. }
  480. }
  481. else
  482. {
  483. BGFX_FATAL(false, Fatal::UnableToInitialize, "Unknown renderer type %d", g_caps.rendererType);
  484. }
  485. for (uint32_t ii = 0, num = g_caps.maxFBAttachments; ii < num; ++ii)
  486. {
  487. ShaderHandle fsh = createShader(fragMem[ii]);
  488. m_program[ii] = createProgram(vsh, fsh);
  489. BX_CHECK(isValid(m_program[ii]), "Failed to create clear quad program.");
  490. destroyShader(fsh);
  491. }
  492. destroyShader(vsh);
  493. m_vb = s_ctx->createTransientVertexBuffer(4*m_decl.m_stride, &m_decl);
  494. }
  495. }
  496. void ClearQuad::shutdown()
  497. {
  498. BGFX_CHECK_MAIN_THREAD();
  499. if (RendererType::Null != g_caps.rendererType)
  500. {
  501. for (uint32_t ii = 0, num = g_caps.maxFBAttachments; ii < num; ++ii)
  502. {
  503. if (isValid(m_program[ii]) )
  504. {
  505. destroyProgram(m_program[ii]);
  506. m_program[ii].idx = invalidHandle;
  507. }
  508. }
  509. s_ctx->destroyTransientVertexBuffer(m_vb);
  510. }
  511. }
  512. const char* s_uniformTypeName[] =
  513. {
  514. "int1",
  515. NULL,
  516. "vec4",
  517. "mat3",
  518. "mat4",
  519. };
  520. BX_STATIC_ASSERT(UniformType::Count == BX_COUNTOF(s_uniformTypeName) );
  521. const char* getUniformTypeName(UniformType::Enum _enum)
  522. {
  523. BX_CHECK(_enum < UniformType::Count, "%d < UniformType::Count %d", _enum, UniformType::Count);
  524. return s_uniformTypeName[_enum];
  525. }
  526. UniformType::Enum nameToUniformTypeEnum(const char* _name)
  527. {
  528. for (uint32_t ii = 0; ii < UniformType::Count; ++ii)
  529. {
  530. if (NULL != s_uniformTypeName[ii]
  531. && 0 == strcmp(_name, s_uniformTypeName[ii]) )
  532. {
  533. return UniformType::Enum(ii);
  534. }
  535. }
  536. return UniformType::Count;
  537. }
  538. static const char* s_predefinedName[PredefinedUniform::Count] =
  539. {
  540. "u_viewRect",
  541. "u_viewTexel",
  542. "u_view",
  543. "u_invView",
  544. "u_proj",
  545. "u_invProj",
  546. "u_viewProj",
  547. "u_invViewProj",
  548. "u_model",
  549. "u_modelView",
  550. "u_modelViewProj",
  551. "u_alphaRef",
  552. };
  553. const char* getPredefinedUniformName(PredefinedUniform::Enum _enum)
  554. {
  555. return s_predefinedName[_enum];
  556. }
  557. PredefinedUniform::Enum nameToPredefinedUniformEnum(const char* _name)
  558. {
  559. for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
  560. {
  561. if (0 == strcmp(_name, s_predefinedName[ii]) )
  562. {
  563. return PredefinedUniform::Enum(ii);
  564. }
  565. }
  566. return PredefinedUniform::Count;
  567. }
  568. uint32_t Frame::submit(uint8_t _id, ProgramHandle _handle, int32_t _depth)
  569. {
  570. if (m_discard)
  571. {
  572. discard();
  573. return m_num;
  574. }
  575. if (BGFX_CONFIG_MAX_DRAW_CALLS-1 <= m_num
  576. || (0 == m_draw.m_numVertices && 0 == m_draw.m_numIndices) )
  577. {
  578. ++m_numDropped;
  579. return m_num;
  580. }
  581. m_constEnd = m_constantBuffer->getPos();
  582. m_key.m_program = invalidHandle == _handle.idx
  583. ? 0
  584. : _handle.idx
  585. ;
  586. m_key.m_depth = (uint32_t)_depth;
  587. m_key.m_view = _id;
  588. m_key.m_seq = s_ctx->m_seq[_id] & s_ctx->m_seqMask[_id];
  589. s_ctx->m_seq[_id]++;
  590. uint64_t key = m_key.encodeDraw();
  591. m_sortKeys[m_num] = key;
  592. m_sortValues[m_num] = m_numRenderItems;
  593. ++m_num;
  594. m_draw.m_constBegin = m_constBegin;
  595. m_draw.m_constEnd = m_constEnd;
  596. m_draw.m_flags |= m_flags;
  597. m_renderItem[m_numRenderItems].draw = m_draw;
  598. ++m_numRenderItems;
  599. m_draw.clear();
  600. m_constBegin = m_constEnd;
  601. m_flags = BGFX_STATE_NONE;
  602. return m_num;
  603. }
  604. uint32_t Frame::dispatch(uint8_t _id, ProgramHandle _handle, uint16_t _numX, uint16_t _numY, uint16_t _numZ, uint8_t _flags)
  605. {
  606. if (m_discard)
  607. {
  608. discard();
  609. return m_num;
  610. }
  611. if (BGFX_CONFIG_MAX_DRAW_CALLS-1 <= m_num)
  612. {
  613. ++m_numDropped;
  614. return m_num;
  615. }
  616. m_constEnd = m_constantBuffer->getPos();
  617. m_compute.m_matrix = m_draw.m_matrix;
  618. m_compute.m_num = m_draw.m_num;
  619. m_compute.m_numX = bx::uint16_max(_numX, 1);
  620. m_compute.m_numY = bx::uint16_max(_numY, 1);
  621. m_compute.m_numZ = bx::uint16_max(_numZ, 1);
  622. m_compute.m_submitFlags = _flags;
  623. m_key.m_program = _handle.idx;
  624. m_key.m_depth = 0;
  625. m_key.m_view = _id;
  626. m_key.m_seq = s_ctx->m_seq[_id];
  627. s_ctx->m_seq[_id]++;
  628. uint64_t key = m_key.encodeCompute();
  629. m_sortKeys[m_num] = key;
  630. m_sortValues[m_num] = m_numRenderItems;
  631. ++m_num;
  632. m_compute.m_constBegin = m_constBegin;
  633. m_compute.m_constEnd = m_constEnd;
  634. m_renderItem[m_numRenderItems].compute = m_compute;
  635. ++m_numRenderItems;
  636. m_compute.clear();
  637. m_constBegin = m_constEnd;
  638. return m_num;
  639. }
  640. void Frame::sort()
  641. {
  642. for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
  643. {
  644. m_sortKeys[ii] = SortKey::remapView(m_sortKeys[ii], m_viewRemap);
  645. }
  646. bx::radixSort64(m_sortKeys, s_ctx->m_tempKeys, m_sortValues, s_ctx->m_tempValues, m_num);
  647. }
  648. RenderFrame::Enum renderFrame()
  649. {
  650. if (BX_ENABLED(BGFX_CONFIG_MULTITHREADED) )
  651. {
  652. if (NULL == s_ctx)
  653. {
  654. s_renderFrameCalled = true;
  655. s_threadIndex = ~BGFX_MAIN_THREAD_MAGIC;
  656. return RenderFrame::NoContext;
  657. }
  658. BGFX_CHECK_RENDER_THREAD();
  659. if (s_ctx->renderFrame() )
  660. {
  661. Context* ctx = s_ctx;
  662. ctx->gameSemWait();
  663. s_ctx = NULL;
  664. ctx->renderSemPost();
  665. return RenderFrame::Exiting;
  666. }
  667. return RenderFrame::Render;
  668. }
  669. BX_CHECK(false, "This call only makes sense if used with multi-threaded renderer.");
  670. return RenderFrame::NoContext;
  671. }
  672. const uint32_t g_uniformTypeSize[UniformType::Count+1] =
  673. {
  674. sizeof(int32_t),
  675. 0,
  676. 4*sizeof(float),
  677. 3*3*sizeof(float),
  678. 4*4*sizeof(float),
  679. 1,
  680. };
  681. void ConstantBuffer::writeUniform(UniformType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num)
  682. {
  683. uint32_t opcode = encodeOpcode(_type, _loc, _num, true);
  684. write(opcode);
  685. write(_value, g_uniformTypeSize[_type]*_num);
  686. }
  687. void ConstantBuffer::writeUniformHandle(UniformType::Enum _type, uint16_t _loc, UniformHandle _handle, uint16_t _num)
  688. {
  689. uint32_t opcode = encodeOpcode(_type, _loc, _num, false);
  690. write(opcode);
  691. write(&_handle, sizeof(UniformHandle) );
  692. }
  693. void ConstantBuffer::writeMarker(const char* _marker)
  694. {
  695. uint16_t num = (uint16_t)strlen(_marker)+1;
  696. uint32_t opcode = encodeOpcode(bgfx::UniformType::Count, 0, num, true);
  697. write(opcode);
  698. write(_marker, num);
  699. }
  700. struct CapsFlags
  701. {
  702. uint64_t m_flag;
  703. const char* m_str;
  704. };
  705. static const CapsFlags s_capsFlags[] =
  706. {
  707. #define CAPS_FLAGS(_x) { _x, #_x }
  708. CAPS_FLAGS(BGFX_CAPS_TEXTURE_COMPARE_LEQUAL),
  709. CAPS_FLAGS(BGFX_CAPS_TEXTURE_COMPARE_ALL),
  710. CAPS_FLAGS(BGFX_CAPS_TEXTURE_3D),
  711. CAPS_FLAGS(BGFX_CAPS_VERTEX_ATTRIB_HALF),
  712. CAPS_FLAGS(BGFX_CAPS_VERTEX_ATTRIB_UINT10),
  713. CAPS_FLAGS(BGFX_CAPS_INSTANCING),
  714. CAPS_FLAGS(BGFX_CAPS_RENDERER_MULTITHREADED),
  715. CAPS_FLAGS(BGFX_CAPS_FRAGMENT_DEPTH),
  716. CAPS_FLAGS(BGFX_CAPS_BLEND_INDEPENDENT),
  717. CAPS_FLAGS(BGFX_CAPS_COMPUTE),
  718. CAPS_FLAGS(BGFX_CAPS_FRAGMENT_ORDERING),
  719. CAPS_FLAGS(BGFX_CAPS_SWAP_CHAIN),
  720. CAPS_FLAGS(BGFX_CAPS_HMD),
  721. CAPS_FLAGS(BGFX_CAPS_INDEX32),
  722. CAPS_FLAGS(BGFX_CAPS_DRAW_INDIRECT),
  723. #undef CAPS_FLAGS
  724. };
  725. static void dumpCaps()
  726. {
  727. BX_TRACE("Supported capabilities (renderer %s, vendor 0x%04x, device 0x%04x):"
  728. , s_ctx->m_renderCtx->getRendererName()
  729. , g_caps.vendorId
  730. , g_caps.deviceId
  731. );
  732. for (uint32_t ii = 0; ii < BX_COUNTOF(s_capsFlags); ++ii)
  733. {
  734. if (0 != (g_caps.supported & s_capsFlags[ii].m_flag) )
  735. {
  736. BX_TRACE("\t%s", s_capsFlags[ii].m_str);
  737. }
  738. }
  739. BX_TRACE("Supported texture formats:");
  740. BX_TRACE("\t +--------- x = supported / * = emulated");
  741. BX_TRACE("\t |+-------- sRGB format");
  742. BX_TRACE("\t ||+------- vertex format");
  743. BX_TRACE("\t |||+------ image");
  744. BX_TRACE("\t ||||+----- framebuffer");
  745. BX_TRACE("\t ||||| +-- name");
  746. for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
  747. {
  748. if (TextureFormat::Unknown != ii
  749. && TextureFormat::UnknownDepth != ii)
  750. {
  751. uint8_t flags = g_caps.formats[ii];
  752. BX_TRACE("\t[%c%c%c%c%c] %s"
  753. , flags&BGFX_CAPS_FORMAT_TEXTURE_COLOR ? 'x' : flags&BGFX_CAPS_FORMAT_TEXTURE_EMULATED ? '*' : ' '
  754. , flags&BGFX_CAPS_FORMAT_TEXTURE_COLOR_SRGB ? 'l' : ' '
  755. , flags&BGFX_CAPS_FORMAT_TEXTURE_VERTEX ? 'v' : ' '
  756. , flags&BGFX_CAPS_FORMAT_TEXTURE_IMAGE ? 'i' : ' '
  757. , flags&BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER ? 'f' : ' '
  758. , getName(TextureFormat::Enum(ii) )
  759. );
  760. BX_UNUSED(flags);
  761. }
  762. }
  763. BX_TRACE("Max FB attachments: %d", g_caps.maxFBAttachments);
  764. }
  765. static TextureFormat::Enum s_emulatedFormats[] =
  766. {
  767. TextureFormat::BC1,
  768. TextureFormat::BC2,
  769. TextureFormat::BC3,
  770. TextureFormat::BC4,
  771. TextureFormat::BC5,
  772. TextureFormat::ETC1,
  773. TextureFormat::ETC2,
  774. TextureFormat::ETC2A,
  775. TextureFormat::ETC2A1,
  776. TextureFormat::PTC14,
  777. TextureFormat::PTC14A,
  778. TextureFormat::BGRA8, // GL doesn't support BGRA8 without extensions.
  779. TextureFormat::RGBA8, // D3D9 doesn't support RGBA8
  780. };
  781. bool Context::init(RendererType::Enum _type)
  782. {
  783. BX_CHECK(!m_rendererInitialized, "Already initialized?");
  784. m_exit = false;
  785. m_frames = 0;
  786. m_debug = BGFX_DEBUG_NONE;
  787. m_submit->create();
  788. #if BGFX_CONFIG_MULTITHREADED
  789. m_render->create();
  790. if (s_renderFrameCalled)
  791. {
  792. // When bgfx::renderFrame is called before init render thread
  793. // should not be created.
  794. BX_TRACE("Application called bgfx::renderFrame directly, not creating render thread.");
  795. m_singleThreaded = true
  796. && !BX_ENABLED(BX_PLATFORM_OSX || BX_PLATFORM_IOS)
  797. && ~BGFX_MAIN_THREAD_MAGIC == s_threadIndex
  798. ;
  799. }
  800. else
  801. {
  802. BX_TRACE("Creating rendering thread.");
  803. m_thread.init(renderThread, this);
  804. m_singleThreaded = false;
  805. }
  806. #else
  807. BX_TRACE("Multithreaded renderer is disabled.");
  808. m_singleThreaded = true;
  809. #endif // BGFX_CONFIG_MULTITHREADED
  810. BX_TRACE("Running in %s-threaded mode", m_singleThreaded ? "single" : "multi");
  811. s_threadIndex = BGFX_MAIN_THREAD_MAGIC;
  812. for (uint32_t ii = 0; ii < BX_COUNTOF(m_viewRemap); ++ii)
  813. {
  814. m_viewRemap[ii] = uint8_t(ii);
  815. }
  816. memset(m_fb, 0xff, sizeof(m_fb) );
  817. memset(m_clear, 0, sizeof(m_clear) );
  818. memset(m_rect, 0, sizeof(m_rect) );
  819. memset(m_scissor, 0, sizeof(m_scissor) );
  820. memset(m_seq, 0, sizeof(m_seq) );
  821. memset(m_seqMask, 0, sizeof(m_seqMask) );
  822. for (uint32_t ii = 0; ii < BX_COUNTOF(m_rect); ++ii)
  823. {
  824. m_rect[ii].m_width = 1;
  825. m_rect[ii].m_height = 1;
  826. }
  827. for (uint32_t ii = 0; ii < BX_COUNTOF(m_clearColor); ++ii)
  828. {
  829. m_clearColor[ii][0] = 0.0f;
  830. m_clearColor[ii][1] = 0.0f;
  831. m_clearColor[ii][2] = 0.0f;
  832. m_clearColor[ii][3] = 1.0f;
  833. }
  834. m_declRef.init();
  835. CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::RendererInit);
  836. cmdbuf.write(_type);
  837. frameNoRenderWait();
  838. // Make sure renderer init is called from render thread.
  839. // g_caps is initialized and available after this point.
  840. frame();
  841. if (!m_rendererInitialized)
  842. {
  843. getCommandBuffer(CommandBuffer::RendererShutdownEnd);
  844. frame();
  845. frame();
  846. m_declRef.shutdown(m_vertexDeclHandle);
  847. m_submit->destroy();
  848. #if BGFX_CONFIG_MULTITHREADED
  849. m_render->destroy();
  850. #endif // BGFX_CONFIG_MULTITHREADED
  851. return false;
  852. }
  853. for (uint32_t ii = 0; ii < BX_COUNTOF(s_emulatedFormats); ++ii)
  854. {
  855. if (0 == (g_caps.formats[s_emulatedFormats[ii] ] & BGFX_CAPS_FORMAT_TEXTURE_COLOR) )
  856. {
  857. g_caps.formats[s_emulatedFormats[ii] ] |= BGFX_CAPS_FORMAT_TEXTURE_EMULATED;
  858. }
  859. }
  860. g_caps.rendererType = m_renderCtx->getRendererType();
  861. initAttribTypeSizeTable(g_caps.rendererType);
  862. g_caps.supported |= 0
  863. | (BX_ENABLED(BGFX_CONFIG_MULTITHREADED) && !m_singleThreaded ? BGFX_CAPS_RENDERER_MULTITHREADED : 0)
  864. ;
  865. dumpCaps();
  866. m_textVideoMemBlitter.init();
  867. m_clearQuad.init();
  868. m_submit->m_transientVb = createTransientVertexBuffer(BGFX_CONFIG_TRANSIENT_VERTEX_BUFFER_SIZE);
  869. m_submit->m_transientIb = createTransientIndexBuffer(BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE);
  870. frame();
  871. if (BX_ENABLED(BGFX_CONFIG_MULTITHREADED) )
  872. {
  873. m_submit->m_transientVb = createTransientVertexBuffer(BGFX_CONFIG_TRANSIENT_VERTEX_BUFFER_SIZE);
  874. m_submit->m_transientIb = createTransientIndexBuffer(BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE);
  875. frame();
  876. }
  877. return true;
  878. }
  879. void Context::shutdown()
  880. {
  881. getCommandBuffer(CommandBuffer::RendererShutdownBegin);
  882. frame();
  883. destroyTransientVertexBuffer(m_submit->m_transientVb);
  884. destroyTransientIndexBuffer(m_submit->m_transientIb);
  885. m_textVideoMemBlitter.shutdown();
  886. m_clearQuad.shutdown();
  887. frame();
  888. if (BX_ENABLED(BGFX_CONFIG_MULTITHREADED) )
  889. {
  890. destroyTransientVertexBuffer(m_submit->m_transientVb);
  891. destroyTransientIndexBuffer(m_submit->m_transientIb);
  892. frame();
  893. }
  894. frame(); // If any VertexDecls needs to be destroyed.
  895. getCommandBuffer(CommandBuffer::RendererShutdownEnd);
  896. frame();
  897. m_dynVertexBufferAllocator.compact();
  898. m_dynIndexBufferAllocator.compact();
  899. m_declRef.shutdown(m_vertexDeclHandle);
  900. #if BGFX_CONFIG_MULTITHREADED
  901. // Render thread shutdown sequence.
  902. renderSemWait(); // Wait for previous frame.
  903. gameSemPost(); // OK to set context to NULL.
  904. // s_ctx is NULL here.
  905. renderSemWait(); // In RenderFrame::Exiting state.
  906. if (m_thread.isRunning() )
  907. {
  908. m_thread.shutdown();
  909. }
  910. m_render->destroy();
  911. #endif // BGFX_CONFIG_MULTITHREADED
  912. s_ctx = NULL;
  913. m_submit->destroy();
  914. if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
  915. {
  916. #define CHECK_HANDLE_LEAK(_handleAlloc) \
  917. BX_MACRO_BLOCK_BEGIN \
  918. BX_WARN(0 == _handleAlloc.getNumHandles() \
  919. , "LEAK: " #_handleAlloc " %d (max: %d)" \
  920. , _handleAlloc.getNumHandles() \
  921. , _handleAlloc.getMaxHandles() \
  922. ); \
  923. BX_MACRO_BLOCK_END
  924. CHECK_HANDLE_LEAK(m_dynamicIndexBufferHandle);
  925. CHECK_HANDLE_LEAK(m_dynamicVertexBufferHandle);
  926. CHECK_HANDLE_LEAK(m_indexBufferHandle);
  927. CHECK_HANDLE_LEAK(m_vertexDeclHandle);
  928. CHECK_HANDLE_LEAK(m_vertexBufferHandle);
  929. CHECK_HANDLE_LEAK(m_shaderHandle);
  930. CHECK_HANDLE_LEAK(m_programHandle);
  931. CHECK_HANDLE_LEAK(m_textureHandle);
  932. CHECK_HANDLE_LEAK(m_frameBufferHandle);
  933. CHECK_HANDLE_LEAK(m_uniformHandle);
  934. #undef CHECK_HANDLE_LEAK
  935. }
  936. }
  937. void Context::freeDynamicBuffers()
  938. {
  939. for (uint16_t ii = 0, num = m_numFreeDynamicIndexBufferHandles; ii < num; ++ii)
  940. {
  941. destroyDynamicIndexBufferInternal(m_freeDynamicIndexBufferHandle[ii]);
  942. }
  943. m_numFreeDynamicIndexBufferHandles = 0;
  944. for (uint16_t ii = 0, num = m_numFreeDynamicVertexBufferHandles; ii < num; ++ii)
  945. {
  946. destroyDynamicVertexBufferInternal(m_freeDynamicVertexBufferHandle[ii]);
  947. }
  948. m_numFreeDynamicVertexBufferHandles = 0;
  949. }
  950. void Context::freeAllHandles(Frame* _frame)
  951. {
  952. for (uint16_t ii = 0, num = _frame->m_numFreeIndexBufferHandles; ii < num; ++ii)
  953. {
  954. m_indexBufferHandle.free(_frame->m_freeIndexBufferHandle[ii].idx);
  955. }
  956. for (uint16_t ii = 0, num = _frame->m_numFreeVertexDeclHandles; ii < num; ++ii)
  957. {
  958. m_vertexDeclHandle.free(_frame->m_freeVertexDeclHandle[ii].idx);
  959. }
  960. for (uint16_t ii = 0, num = _frame->m_numFreeVertexBufferHandles; ii < num; ++ii)
  961. {
  962. destroyVertexBufferInternal(_frame->m_freeVertexBufferHandle[ii]);
  963. }
  964. for (uint16_t ii = 0, num = _frame->m_numFreeShaderHandles; ii < num; ++ii)
  965. {
  966. m_shaderHandle.free(_frame->m_freeShaderHandle[ii].idx);
  967. }
  968. for (uint16_t ii = 0, num = _frame->m_numFreeProgramHandles; ii < num; ++ii)
  969. {
  970. m_programHandle.free(_frame->m_freeProgramHandle[ii].idx);
  971. }
  972. for (uint16_t ii = 0, num = _frame->m_numFreeTextureHandles; ii < num; ++ii)
  973. {
  974. m_textureHandle.free(_frame->m_freeTextureHandle[ii].idx);
  975. }
  976. for (uint16_t ii = 0, num = _frame->m_numFreeFrameBufferHandles; ii < num; ++ii)
  977. {
  978. m_frameBufferHandle.free(_frame->m_freeFrameBufferHandle[ii].idx);
  979. }
  980. for (uint16_t ii = 0, num = _frame->m_numFreeUniformHandles; ii < num; ++ii)
  981. {
  982. m_uniformHandle.free(_frame->m_freeUniformHandle[ii].idx);
  983. }
  984. }
  985. uint32_t Context::frame()
  986. {
  987. BX_CHECK(0 == m_instBufferCount, "Instance buffer allocated, but not used. This is incorrect, and causes memory leak.");
  988. // wait for render thread to finish
  989. renderSemWait();
  990. frameNoRenderWait();
  991. return m_frames;
  992. }
  993. void Context::frameNoRenderWait()
  994. {
  995. swap();
  996. // release render thread
  997. gameSemPost();
  998. }
  999. void Context::swap()
  1000. {
  1001. freeDynamicBuffers();
  1002. m_submit->m_resolution = m_resolution;
  1003. m_submit->m_debug = m_debug;
  1004. memcpy(m_submit->m_viewRemap, m_viewRemap, sizeof(m_viewRemap) );
  1005. memcpy(m_submit->m_fb, m_fb, sizeof(m_fb) );
  1006. memcpy(m_submit->m_clear, m_clear, sizeof(m_clear) );
  1007. memcpy(m_submit->m_rect, m_rect, sizeof(m_rect) );
  1008. memcpy(m_submit->m_scissor, m_scissor, sizeof(m_scissor) );
  1009. memcpy(m_submit->m_view, m_view, sizeof(m_view) );
  1010. memcpy(m_submit->m_proj, m_proj, sizeof(m_proj) );
  1011. memcpy(m_submit->m_viewFlags, m_viewFlags, sizeof(m_viewFlags) );
  1012. if (m_clearColorDirty > 0)
  1013. {
  1014. --m_clearColorDirty;
  1015. memcpy(m_submit->m_clearColor, m_clearColor, sizeof(m_clearColor) );
  1016. }
  1017. m_submit->finish();
  1018. bx::xchg(m_render, m_submit);
  1019. if (!BX_ENABLED(BGFX_CONFIG_MULTITHREADED)
  1020. || m_singleThreaded)
  1021. {
  1022. renderFrame();
  1023. }
  1024. m_frames++;
  1025. m_submit->start();
  1026. memset(m_seq, 0, sizeof(m_seq) );
  1027. freeAllHandles(m_submit);
  1028. m_submit->resetFreeHandles();
  1029. m_submit->m_textVideoMem->resize(m_render->m_textVideoMem->m_small
  1030. , m_resolution.m_width
  1031. , m_resolution.m_height
  1032. );
  1033. }
  1034. bool Context::renderFrame()
  1035. {
  1036. if (m_rendererInitialized
  1037. && !m_flipAfterRender)
  1038. {
  1039. m_renderCtx->flip(m_render->m_hmd);
  1040. }
  1041. gameSemWait();
  1042. rendererExecCommands(m_render->m_cmdPre);
  1043. if (m_rendererInitialized)
  1044. {
  1045. m_renderCtx->submit(m_render, m_clearQuad, m_textVideoMemBlitter);
  1046. }
  1047. rendererExecCommands(m_render->m_cmdPost);
  1048. renderSemPost();
  1049. if (m_rendererInitialized
  1050. && m_flipAfterRender)
  1051. {
  1052. m_renderCtx->flip(m_render->m_hmd);
  1053. }
  1054. return m_exit;
  1055. }
  1056. void rendererUpdateUniforms(RendererContextI* _renderCtx, ConstantBuffer* _constantBuffer, uint32_t _begin, uint32_t _end)
  1057. {
  1058. _constantBuffer->reset(_begin);
  1059. while (_constantBuffer->getPos() < _end)
  1060. {
  1061. uint32_t opcode = _constantBuffer->read();
  1062. if (UniformType::End == opcode)
  1063. {
  1064. break;
  1065. }
  1066. UniformType::Enum type;
  1067. uint16_t loc;
  1068. uint16_t num;
  1069. uint16_t copy;
  1070. ConstantBuffer::decodeOpcode(opcode, type, loc, num, copy);
  1071. uint32_t size = g_uniformTypeSize[type]*num;
  1072. const char* data = _constantBuffer->read(size);
  1073. if (UniformType::Count > type)
  1074. {
  1075. if (copy)
  1076. {
  1077. _renderCtx->updateUniform(loc, data, size);
  1078. }
  1079. else
  1080. {
  1081. _renderCtx->updateUniform(loc, *(const char**)(data), size);
  1082. }
  1083. }
  1084. else
  1085. {
  1086. _renderCtx->setMarker(data, size);
  1087. }
  1088. }
  1089. }
  1090. void Context::flushTextureUpdateBatch(CommandBuffer& _cmdbuf)
  1091. {
  1092. if (m_textureUpdateBatch.sort() )
  1093. {
  1094. const uint32_t pos = _cmdbuf.m_pos;
  1095. uint32_t currentKey = UINT32_MAX;
  1096. for (uint32_t ii = 0, num = m_textureUpdateBatch.m_num; ii < num; ++ii)
  1097. {
  1098. _cmdbuf.m_pos = m_textureUpdateBatch.m_values[ii];
  1099. TextureHandle handle;
  1100. _cmdbuf.read(handle);
  1101. uint8_t side;
  1102. _cmdbuf.read(side);
  1103. uint8_t mip;
  1104. _cmdbuf.read(mip);
  1105. Rect rect;
  1106. _cmdbuf.read(rect);
  1107. uint16_t zz;
  1108. _cmdbuf.read(zz);
  1109. uint16_t depth;
  1110. _cmdbuf.read(depth);
  1111. uint16_t pitch;
  1112. _cmdbuf.read(pitch);
  1113. Memory* mem;
  1114. _cmdbuf.read(mem);
  1115. uint32_t key = m_textureUpdateBatch.m_keys[ii];
  1116. if (key != currentKey)
  1117. {
  1118. if (currentKey != UINT32_MAX)
  1119. {
  1120. m_renderCtx->updateTextureEnd();
  1121. }
  1122. currentKey = key;
  1123. m_renderCtx->updateTextureBegin(handle, side, mip);
  1124. }
  1125. m_renderCtx->updateTexture(handle, side, mip, rect, zz, depth, pitch, mem);
  1126. release(mem);
  1127. }
  1128. if (currentKey != UINT32_MAX)
  1129. {
  1130. m_renderCtx->updateTextureEnd();
  1131. }
  1132. m_textureUpdateBatch.reset();
  1133. _cmdbuf.m_pos = pos;
  1134. }
  1135. }
  1136. typedef RendererContextI* (*RendererCreateFn)();
  1137. typedef void (*RendererDestroyFn)();
  1138. #define BGFX_RENDERER_CONTEXT(_namespace) \
  1139. namespace _namespace \
  1140. { \
  1141. extern RendererContextI* rendererCreate(); \
  1142. extern void rendererDestroy(); \
  1143. }
  1144. BGFX_RENDERER_CONTEXT(noop);
  1145. BGFX_RENDERER_CONTEXT(d3d9);
  1146. BGFX_RENDERER_CONTEXT(d3d11);
  1147. BGFX_RENDERER_CONTEXT(d3d12);
  1148. BGFX_RENDERER_CONTEXT(mtl);
  1149. BGFX_RENDERER_CONTEXT(gl);
  1150. BGFX_RENDERER_CONTEXT(vk);
  1151. #undef BGFX_RENDERER_CONTEXT
  1152. struct RendererCreator
  1153. {
  1154. RendererCreateFn createFn;
  1155. RendererDestroyFn destroyFn;
  1156. const char* name;
  1157. bool supported;
  1158. };
  1159. static RendererCreator s_rendererCreator[] =
  1160. {
  1161. { noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NULL_NAME, !!BGFX_CONFIG_RENDERER_NULL }, // Noop
  1162. { d3d9::rendererCreate, d3d9::rendererDestroy, BGFX_RENDERER_DIRECT3D9_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D9 }, // Direct3D9
  1163. { d3d11::rendererCreate, d3d11::rendererDestroy, BGFX_RENDERER_DIRECT3D11_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D11 }, // Direct3D11
  1164. { d3d12::rendererCreate, d3d12::rendererDestroy, BGFX_RENDERER_DIRECT3D12_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D12 }, // Direct3D12
  1165. #if BX_PLATFORM_OSX || BX_PLATFORM_IOS
  1166. { mtl::rendererCreate, mtl::rendererDestroy, BGFX_RENDERER_METAL_NAME, !!BGFX_CONFIG_RENDERER_METAL }, // Metal
  1167. #else
  1168. { noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NULL_NAME, !!BGFX_CONFIG_RENDERER_NULL }, // Noop
  1169. #endif // BX_PLATFORM_OSX || BX_PLATFORM_IOS
  1170. { gl::rendererCreate, gl::rendererDestroy, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGLES }, // OpenGLES
  1171. { gl::rendererCreate, gl::rendererDestroy, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGL }, // OpenGL
  1172. { vk::rendererCreate, vk::rendererDestroy, BGFX_RENDERER_VULKAN_NAME, !!BGFX_CONFIG_RENDERER_VULKAN }, // Vulkan
  1173. };
  1174. BX_STATIC_ASSERT(BX_COUNTOF(s_rendererCreator) == RendererType::Count);
  1175. static RendererDestroyFn s_rendererDestroyFn;
  1176. struct Condition
  1177. {
  1178. enum Enum
  1179. {
  1180. LessEqual,
  1181. GreaterEqual,
  1182. };
  1183. };
  1184. bool windowsVersionIs(Condition::Enum _op, uint32_t _version)
  1185. {
  1186. #if BX_PLATFORM_WINDOWS
  1187. static const uint8_t s_condition[] =
  1188. {
  1189. VER_LESS_EQUAL,
  1190. VER_GREATER_EQUAL,
  1191. };
  1192. OSVERSIONINFOEXA ovi;
  1193. memset(&ovi, 0, sizeof(ovi) );
  1194. ovi.dwOSVersionInfoSize = sizeof(ovi);
  1195. // _WIN32_WINNT_WINBLUE 0x0603
  1196. // _WIN32_WINNT_WIN8 0x0602
  1197. // _WIN32_WINNT_WIN7 0x0601
  1198. // _WIN32_WINNT_VISTA 0x0600
  1199. ovi.dwMajorVersion = HIBYTE(_version);
  1200. ovi.dwMinorVersion = LOBYTE(_version);
  1201. DWORDLONG cond = 0;
  1202. VER_SET_CONDITION(cond, VER_MAJORVERSION, s_condition[_op]);
  1203. VER_SET_CONDITION(cond, VER_MINORVERSION, s_condition[_op]);
  1204. return !!VerifyVersionInfoA(&ovi, VER_MAJORVERSION | VER_MINORVERSION, cond);
  1205. #else
  1206. BX_UNUSED(_op, _version);
  1207. return false;
  1208. #endif // BX_PLATFORM_WINDOWS
  1209. }
  1210. RendererContextI* rendererCreate(RendererType::Enum _type)
  1211. {
  1212. if (RendererType::Count == _type)
  1213. {
  1214. again:
  1215. if (BX_ENABLED(BX_PLATFORM_WINDOWS) )
  1216. {
  1217. RendererType::Enum first = RendererType::Direct3D9;
  1218. RendererType::Enum second = RendererType::Direct3D11;
  1219. if (windowsVersionIs(Condition::GreaterEqual, 0x0602) )
  1220. {
  1221. first = RendererType::Direct3D12;
  1222. second = RendererType::Direct3D11;
  1223. if (!s_rendererCreator[second].supported)
  1224. {
  1225. second = RendererType::Direct3D9;
  1226. }
  1227. }
  1228. else if (windowsVersionIs(Condition::GreaterEqual, 0x0601) )
  1229. {
  1230. first = RendererType::Direct3D11;
  1231. second = RendererType::Direct3D9;
  1232. }
  1233. if (s_rendererCreator[first].supported)
  1234. {
  1235. _type = first;
  1236. }
  1237. else if (s_rendererCreator[second].supported)
  1238. {
  1239. _type = second;
  1240. }
  1241. else if (s_rendererCreator[RendererType::OpenGL].supported)
  1242. {
  1243. _type = RendererType::OpenGL;
  1244. }
  1245. else if (s_rendererCreator[RendererType::OpenGLES].supported)
  1246. {
  1247. _type = RendererType::OpenGLES;
  1248. }
  1249. else if (s_rendererCreator[RendererType::Direct3D12].supported)
  1250. {
  1251. _type = RendererType::Direct3D12;
  1252. }
  1253. else if (s_rendererCreator[RendererType::Vulkan].supported)
  1254. {
  1255. _type = RendererType::Vulkan;
  1256. }
  1257. else
  1258. {
  1259. _type = RendererType::Null;
  1260. }
  1261. }
  1262. else if (BX_ENABLED(0
  1263. || BX_PLATFORM_ANDROID
  1264. || BX_PLATFORM_EMSCRIPTEN
  1265. || BX_PLATFORM_IOS
  1266. || BX_PLATFORM_NACL
  1267. || BX_PLATFORM_RPI
  1268. ) )
  1269. {
  1270. _type = RendererType::OpenGLES;
  1271. }
  1272. else if (BX_ENABLED(BX_PLATFORM_WINRT) )
  1273. {
  1274. _type = RendererType::Direct3D11;
  1275. }
  1276. else
  1277. {
  1278. if (s_rendererCreator[RendererType::OpenGL].supported)
  1279. {
  1280. _type = RendererType::OpenGL;
  1281. }
  1282. else if (s_rendererCreator[RendererType::OpenGLES].supported)
  1283. {
  1284. _type = RendererType::OpenGLES;
  1285. }
  1286. }
  1287. if (!s_rendererCreator[_type].supported)
  1288. {
  1289. _type = RendererType::Null;
  1290. }
  1291. }
  1292. RendererContextI* renderCtx = s_rendererCreator[_type].createFn();
  1293. if (NULL == renderCtx)
  1294. {
  1295. s_rendererCreator[_type].supported = false;
  1296. goto again;
  1297. }
  1298. s_rendererDestroyFn = s_rendererCreator[_type].destroyFn;
  1299. return renderCtx;
  1300. }
  1301. void rendererDestroy()
  1302. {
  1303. s_rendererDestroyFn();
  1304. }
  1305. void Context::rendererExecCommands(CommandBuffer& _cmdbuf)
  1306. {
  1307. _cmdbuf.reset();
  1308. bool end = false;
  1309. if (NULL == m_renderCtx)
  1310. {
  1311. uint8_t command;
  1312. _cmdbuf.read(command);
  1313. switch (command)
  1314. {
  1315. case CommandBuffer::RendererShutdownEnd:
  1316. m_exit = true;
  1317. return;
  1318. case CommandBuffer::End:
  1319. return;
  1320. default:
  1321. {
  1322. BX_CHECK(CommandBuffer::RendererInit == command
  1323. , "RendererInit must be the first command in command buffer before initialization. Unexpected command %d?"
  1324. , command
  1325. );
  1326. BX_CHECK(!m_rendererInitialized, "This shouldn't happen! Bad synchronization?");
  1327. RendererType::Enum type;
  1328. _cmdbuf.read(type);
  1329. m_renderCtx = rendererCreate(type);
  1330. m_rendererInitialized = NULL != m_renderCtx;
  1331. if (!m_rendererInitialized)
  1332. {
  1333. _cmdbuf.read(command);
  1334. BX_CHECK(CommandBuffer::End == command, "Unexpected command %d?"
  1335. , command
  1336. );
  1337. return;
  1338. }
  1339. }
  1340. break;
  1341. }
  1342. }
  1343. do
  1344. {
  1345. uint8_t command;
  1346. _cmdbuf.read(command);
  1347. switch (command)
  1348. {
  1349. case CommandBuffer::RendererShutdownBegin:
  1350. {
  1351. BX_CHECK(m_rendererInitialized, "This shouldn't happen! Bad synchronization?");
  1352. m_rendererInitialized = false;
  1353. }
  1354. break;
  1355. case CommandBuffer::RendererShutdownEnd:
  1356. {
  1357. BX_CHECK(!m_rendererInitialized && !m_exit, "This shouldn't happen! Bad synchronization?");
  1358. rendererDestroy();
  1359. m_renderCtx = NULL;
  1360. m_exit = true;
  1361. }
  1362. // fall through
  1363. case CommandBuffer::End:
  1364. end = true;
  1365. break;
  1366. case CommandBuffer::CreateIndexBuffer:
  1367. {
  1368. IndexBufferHandle handle;
  1369. _cmdbuf.read(handle);
  1370. Memory* mem;
  1371. _cmdbuf.read(mem);
  1372. uint16_t flags;
  1373. _cmdbuf.read(flags);
  1374. m_renderCtx->createIndexBuffer(handle, mem, flags);
  1375. release(mem);
  1376. }
  1377. break;
  1378. case CommandBuffer::DestroyIndexBuffer:
  1379. {
  1380. IndexBufferHandle handle;
  1381. _cmdbuf.read(handle);
  1382. m_renderCtx->destroyIndexBuffer(handle);
  1383. }
  1384. break;
  1385. case CommandBuffer::CreateVertexDecl:
  1386. {
  1387. VertexDeclHandle handle;
  1388. _cmdbuf.read(handle);
  1389. VertexDecl decl;
  1390. _cmdbuf.read(decl);
  1391. m_renderCtx->createVertexDecl(handle, decl);
  1392. }
  1393. break;
  1394. case CommandBuffer::DestroyVertexDecl:
  1395. {
  1396. VertexDeclHandle handle;
  1397. _cmdbuf.read(handle);
  1398. m_renderCtx->destroyVertexDecl(handle);
  1399. }
  1400. break;
  1401. case CommandBuffer::CreateVertexBuffer:
  1402. {
  1403. VertexBufferHandle handle;
  1404. _cmdbuf.read(handle);
  1405. Memory* mem;
  1406. _cmdbuf.read(mem);
  1407. VertexDeclHandle declHandle;
  1408. _cmdbuf.read(declHandle);
  1409. uint16_t flags;
  1410. _cmdbuf.read(flags);
  1411. m_renderCtx->createVertexBuffer(handle, mem, declHandle, flags);
  1412. release(mem);
  1413. }
  1414. break;
  1415. case CommandBuffer::DestroyVertexBuffer:
  1416. {
  1417. VertexBufferHandle handle;
  1418. _cmdbuf.read(handle);
  1419. m_renderCtx->destroyVertexBuffer(handle);
  1420. }
  1421. break;
  1422. case CommandBuffer::CreateDynamicIndexBuffer:
  1423. {
  1424. IndexBufferHandle handle;
  1425. _cmdbuf.read(handle);
  1426. uint32_t size;
  1427. _cmdbuf.read(size);
  1428. uint16_t flags;
  1429. _cmdbuf.read(flags);
  1430. m_renderCtx->createDynamicIndexBuffer(handle, size, flags);
  1431. }
  1432. break;
  1433. case CommandBuffer::UpdateDynamicIndexBuffer:
  1434. {
  1435. IndexBufferHandle handle;
  1436. _cmdbuf.read(handle);
  1437. uint32_t offset;
  1438. _cmdbuf.read(offset);
  1439. uint32_t size;
  1440. _cmdbuf.read(size);
  1441. Memory* mem;
  1442. _cmdbuf.read(mem);
  1443. m_renderCtx->updateDynamicIndexBuffer(handle, offset, size, mem);
  1444. release(mem);
  1445. }
  1446. break;
  1447. case CommandBuffer::DestroyDynamicIndexBuffer:
  1448. {
  1449. IndexBufferHandle handle;
  1450. _cmdbuf.read(handle);
  1451. m_renderCtx->destroyDynamicIndexBuffer(handle);
  1452. }
  1453. break;
  1454. case CommandBuffer::CreateDynamicVertexBuffer:
  1455. {
  1456. VertexBufferHandle handle;
  1457. _cmdbuf.read(handle);
  1458. uint32_t size;
  1459. _cmdbuf.read(size);
  1460. uint16_t flags;
  1461. _cmdbuf.read(flags);
  1462. m_renderCtx->createDynamicVertexBuffer(handle, size, flags);
  1463. }
  1464. break;
  1465. case CommandBuffer::UpdateDynamicVertexBuffer:
  1466. {
  1467. VertexBufferHandle handle;
  1468. _cmdbuf.read(handle);
  1469. uint32_t offset;
  1470. _cmdbuf.read(offset);
  1471. uint32_t size;
  1472. _cmdbuf.read(size);
  1473. Memory* mem;
  1474. _cmdbuf.read(mem);
  1475. m_renderCtx->updateDynamicVertexBuffer(handle, offset, size, mem);
  1476. release(mem);
  1477. }
  1478. break;
  1479. case CommandBuffer::DestroyDynamicVertexBuffer:
  1480. {
  1481. VertexBufferHandle handle;
  1482. _cmdbuf.read(handle);
  1483. m_renderCtx->destroyDynamicVertexBuffer(handle);
  1484. }
  1485. break;
  1486. case CommandBuffer::CreateShader:
  1487. {
  1488. ShaderHandle handle;
  1489. _cmdbuf.read(handle);
  1490. Memory* mem;
  1491. _cmdbuf.read(mem);
  1492. m_renderCtx->createShader(handle, mem);
  1493. release(mem);
  1494. }
  1495. break;
  1496. case CommandBuffer::DestroyShader:
  1497. {
  1498. ShaderHandle handle;
  1499. _cmdbuf.read(handle);
  1500. m_renderCtx->destroyShader(handle);
  1501. }
  1502. break;
  1503. case CommandBuffer::CreateProgram:
  1504. {
  1505. ProgramHandle handle;
  1506. _cmdbuf.read(handle);
  1507. ShaderHandle vsh;
  1508. _cmdbuf.read(vsh);
  1509. ShaderHandle fsh;
  1510. _cmdbuf.read(fsh);
  1511. m_renderCtx->createProgram(handle, vsh, fsh);
  1512. }
  1513. break;
  1514. case CommandBuffer::DestroyProgram:
  1515. {
  1516. ProgramHandle handle;
  1517. _cmdbuf.read(handle);
  1518. m_renderCtx->destroyProgram(handle);
  1519. }
  1520. break;
  1521. case CommandBuffer::CreateTexture:
  1522. {
  1523. TextureHandle handle;
  1524. _cmdbuf.read(handle);
  1525. Memory* mem;
  1526. _cmdbuf.read(mem);
  1527. uint32_t flags;
  1528. _cmdbuf.read(flags);
  1529. uint8_t skip;
  1530. _cmdbuf.read(skip);
  1531. m_renderCtx->createTexture(handle, mem, flags, skip);
  1532. bx::MemoryReader reader(mem->data, mem->size);
  1533. uint32_t magic;
  1534. bx::read(&reader, magic);
  1535. if (BGFX_CHUNK_MAGIC_TEX == magic)
  1536. {
  1537. TextureCreate tc;
  1538. bx::read(&reader, tc);
  1539. if (NULL != tc.m_mem)
  1540. {
  1541. release(tc.m_mem);
  1542. }
  1543. }
  1544. release(mem);
  1545. }
  1546. break;
  1547. case CommandBuffer::UpdateTexture:
  1548. {
  1549. if (m_textureUpdateBatch.isFull() )
  1550. {
  1551. flushTextureUpdateBatch(_cmdbuf);
  1552. }
  1553. uint32_t value = _cmdbuf.m_pos;
  1554. TextureHandle handle;
  1555. _cmdbuf.read(handle);
  1556. uint8_t side;
  1557. _cmdbuf.read(side);
  1558. uint8_t mip;
  1559. _cmdbuf.read(mip);
  1560. _cmdbuf.skip<Rect>();
  1561. _cmdbuf.skip<uint16_t>();
  1562. _cmdbuf.skip<uint16_t>();
  1563. _cmdbuf.skip<uint16_t>();
  1564. _cmdbuf.skip<Memory*>();
  1565. uint32_t key = (handle.idx<<16)
  1566. | (side<<8)
  1567. | mip
  1568. ;
  1569. m_textureUpdateBatch.add(key, value);
  1570. }
  1571. break;
  1572. case CommandBuffer::ResizeTexture:
  1573. {
  1574. TextureHandle handle;
  1575. _cmdbuf.read(handle);
  1576. uint16_t width;
  1577. _cmdbuf.read(width);
  1578. uint16_t height;
  1579. _cmdbuf.read(height);
  1580. m_renderCtx->resizeTexture(handle, width, height);
  1581. }
  1582. break;
  1583. case CommandBuffer::DestroyTexture:
  1584. {
  1585. TextureHandle handle;
  1586. _cmdbuf.read(handle);
  1587. m_renderCtx->destroyTexture(handle);
  1588. }
  1589. break;
  1590. case CommandBuffer::CreateFrameBuffer:
  1591. {
  1592. FrameBufferHandle handle;
  1593. _cmdbuf.read(handle);
  1594. bool window;
  1595. _cmdbuf.read(window);
  1596. if (window)
  1597. {
  1598. void* nwh;
  1599. _cmdbuf.read(nwh);
  1600. uint16_t width;
  1601. _cmdbuf.read(width);
  1602. uint16_t height;
  1603. _cmdbuf.read(height);
  1604. TextureFormat::Enum depthFormat;
  1605. _cmdbuf.read(depthFormat);
  1606. m_renderCtx->createFrameBuffer(handle, nwh, width, height, depthFormat);
  1607. }
  1608. else
  1609. {
  1610. uint8_t num;
  1611. _cmdbuf.read(num);
  1612. TextureHandle textureHandles[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  1613. for (uint32_t ii = 0; ii < num; ++ii)
  1614. {
  1615. _cmdbuf.read(textureHandles[ii]);
  1616. }
  1617. m_renderCtx->createFrameBuffer(handle, num, textureHandles);
  1618. }
  1619. }
  1620. break;
  1621. case CommandBuffer::DestroyFrameBuffer:
  1622. {
  1623. FrameBufferHandle handle;
  1624. _cmdbuf.read(handle);
  1625. m_renderCtx->destroyFrameBuffer(handle);
  1626. }
  1627. break;
  1628. case CommandBuffer::CreateUniform:
  1629. {
  1630. UniformHandle handle;
  1631. _cmdbuf.read(handle);
  1632. UniformType::Enum type;
  1633. _cmdbuf.read(type);
  1634. uint16_t num;
  1635. _cmdbuf.read(num);
  1636. uint8_t len;
  1637. _cmdbuf.read(len);
  1638. const char* name = (const char*)_cmdbuf.skip(len);
  1639. m_renderCtx->createUniform(handle, type, num, name);
  1640. }
  1641. break;
  1642. case CommandBuffer::DestroyUniform:
  1643. {
  1644. UniformHandle handle;
  1645. _cmdbuf.read(handle);
  1646. m_renderCtx->destroyUniform(handle);
  1647. }
  1648. break;
  1649. case CommandBuffer::SaveScreenShot:
  1650. {
  1651. uint16_t len;
  1652. _cmdbuf.read(len);
  1653. const char* filePath = (const char*)_cmdbuf.skip(len);
  1654. m_renderCtx->saveScreenShot(filePath);
  1655. }
  1656. break;
  1657. case CommandBuffer::UpdateViewName:
  1658. {
  1659. uint8_t id;
  1660. _cmdbuf.read(id);
  1661. uint16_t len;
  1662. _cmdbuf.read(len);
  1663. const char* name = (const char*)_cmdbuf.skip(len);
  1664. m_renderCtx->updateViewName(id, name);
  1665. }
  1666. break;
  1667. default:
  1668. BX_CHECK(false, "Invalid command: %d", command);
  1669. break;
  1670. }
  1671. } while (!end);
  1672. flushTextureUpdateBatch(_cmdbuf);
  1673. }
  1674. uint8_t getSupportedRenderers(RendererType::Enum _enum[RendererType::Count])
  1675. {
  1676. uint8_t num = 0;
  1677. for (uint8_t ii = 0; ii < uint8_t(RendererType::Count); ++ii)
  1678. {
  1679. if ( (RendererType::Direct3D11 == ii || RendererType::Direct3D12 == ii)
  1680. && windowsVersionIs(Condition::LessEqual, 0x0502) )
  1681. {
  1682. continue;
  1683. }
  1684. if (s_rendererCreator[ii].supported)
  1685. {
  1686. _enum[num++] = RendererType::Enum(ii);
  1687. }
  1688. }
  1689. return num;
  1690. }
  1691. const char* getRendererName(RendererType::Enum _type)
  1692. {
  1693. BX_CHECK(_type < RendererType::Count, "Invalid renderer type %d.", _type);
  1694. return s_rendererCreator[_type].name;
  1695. }
  1696. bool init(RendererType::Enum _type, uint16_t _vendorId, uint16_t _deviceId, CallbackI* _callback, bx::ReallocatorI* _allocator)
  1697. {
  1698. BX_CHECK(NULL == s_ctx, "bgfx is already initialized.");
  1699. memset(&g_caps, 0, sizeof(g_caps) );
  1700. g_caps.maxViews = BGFX_CONFIG_MAX_VIEWS;
  1701. g_caps.maxDrawCalls = BGFX_CONFIG_MAX_DRAW_CALLS;
  1702. g_caps.maxFBAttachments = 1;
  1703. g_caps.vendorId = _vendorId;
  1704. g_caps.deviceId = _deviceId;
  1705. if (NULL != _allocator)
  1706. {
  1707. g_allocator = _allocator;
  1708. }
  1709. else
  1710. {
  1711. bx::CrtAllocator allocator;
  1712. g_allocator =
  1713. s_allocatorStub = BX_NEW(&allocator, AllocatorStub);
  1714. }
  1715. if (NULL != _callback)
  1716. {
  1717. g_callback = _callback;
  1718. }
  1719. else
  1720. {
  1721. g_callback =
  1722. s_callbackStub = BX_NEW(g_allocator, CallbackStub);
  1723. }
  1724. BX_TRACE("Init...");
  1725. s_ctx = BX_ALIGNED_NEW(g_allocator, Context, 16);
  1726. if (!s_ctx->init(_type) )
  1727. {
  1728. BX_TRACE("Init failed.");
  1729. BX_ALIGNED_DELETE(g_allocator, s_ctx, 16);
  1730. s_ctx = NULL;
  1731. if (NULL != s_callbackStub)
  1732. {
  1733. BX_DELETE(g_allocator, s_callbackStub);
  1734. s_callbackStub = NULL;
  1735. }
  1736. if (NULL != s_allocatorStub)
  1737. {
  1738. // s_allocatorStub->checkLeaks();
  1739. bx::CrtAllocator allocator;
  1740. BX_DELETE(&allocator, s_allocatorStub);
  1741. s_allocatorStub = NULL;
  1742. }
  1743. s_threadIndex = 0;
  1744. g_callback = NULL;
  1745. g_allocator = NULL;
  1746. return false;
  1747. }
  1748. BX_TRACE("Init complete.");
  1749. return true;
  1750. }
  1751. void shutdown()
  1752. {
  1753. BX_TRACE("Shutdown...");
  1754. BGFX_CHECK_MAIN_THREAD();
  1755. Context* ctx = s_ctx; // it's going to be NULLd inside shutdown.
  1756. ctx->shutdown();
  1757. BX_CHECK(NULL == s_ctx, "bgfx is should be uninitialized here.");
  1758. BX_ALIGNED_DELETE(g_allocator, ctx, 16);
  1759. BX_TRACE("Shutdown complete.");
  1760. if (NULL != s_callbackStub)
  1761. {
  1762. BX_DELETE(g_allocator, s_callbackStub);
  1763. s_callbackStub = NULL;
  1764. }
  1765. if (NULL != s_allocatorStub)
  1766. {
  1767. s_allocatorStub->checkLeaks();
  1768. bx::CrtAllocator allocator;
  1769. BX_DELETE(&allocator, s_allocatorStub);
  1770. s_allocatorStub = NULL;
  1771. }
  1772. s_threadIndex = 0;
  1773. g_callback = NULL;
  1774. g_allocator = NULL;
  1775. }
  1776. void reset(uint32_t _width, uint32_t _height, uint32_t _flags)
  1777. {
  1778. BGFX_CHECK_MAIN_THREAD();
  1779. s_ctx->reset(_width, _height, _flags);
  1780. }
  1781. uint32_t frame()
  1782. {
  1783. BGFX_CHECK_MAIN_THREAD();
  1784. return s_ctx->frame();
  1785. }
  1786. const Caps* getCaps()
  1787. {
  1788. return &g_caps;
  1789. }
  1790. const HMD* getHMD()
  1791. {
  1792. return s_ctx->getHMD();
  1793. }
  1794. const Stats* getStats()
  1795. {
  1796. return s_ctx->getPerfStats();
  1797. }
  1798. RendererType::Enum getRendererType()
  1799. {
  1800. return g_caps.rendererType;
  1801. }
  1802. const Memory* alloc(uint32_t _size)
  1803. {
  1804. BX_CHECK(0 < _size, "Invalid memory operation. _size is 0.");
  1805. Memory* mem = (Memory*)BX_ALLOC(g_allocator, sizeof(Memory) + _size);
  1806. mem->size = _size;
  1807. mem->data = (uint8_t*)mem + sizeof(Memory);
  1808. return mem;
  1809. }
  1810. const Memory* copy(const void* _data, uint32_t _size)
  1811. {
  1812. BX_CHECK(0 < _size, "Invalid memory operation. _size is 0.");
  1813. const Memory* mem = alloc(_size);
  1814. memcpy(mem->data, _data, _size);
  1815. return mem;
  1816. }
  1817. struct MemoryRef
  1818. {
  1819. Memory mem;
  1820. ReleaseFn releaseFn;
  1821. void* userData;
  1822. };
  1823. const Memory* makeRef(const void* _data, uint32_t _size, ReleaseFn _releaseFn, void* _userData)
  1824. {
  1825. MemoryRef* memRef = (MemoryRef*)BX_ALLOC(g_allocator, sizeof(MemoryRef) );
  1826. memRef->mem.size = _size;
  1827. memRef->mem.data = (uint8_t*)_data;
  1828. memRef->releaseFn = _releaseFn;
  1829. memRef->userData = _userData;
  1830. return &memRef->mem;
  1831. }
  1832. bool isMemoryRef(const Memory* _mem)
  1833. {
  1834. return _mem->data != (uint8_t*)_mem + sizeof(Memory);
  1835. }
  1836. void release(const Memory* _mem)
  1837. {
  1838. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1839. Memory* mem = const_cast<Memory*>(_mem);
  1840. if (isMemoryRef(mem) )
  1841. {
  1842. MemoryRef* memRef = reinterpret_cast<MemoryRef*>(mem);
  1843. if (NULL != memRef->releaseFn)
  1844. {
  1845. memRef->releaseFn(mem->data, memRef->userData);
  1846. }
  1847. }
  1848. BX_FREE(g_allocator, mem);
  1849. }
  1850. void setDebug(uint32_t _debug)
  1851. {
  1852. BGFX_CHECK_MAIN_THREAD();
  1853. s_ctx->setDebug(_debug);
  1854. }
  1855. void dbgTextClear(uint8_t _attr, bool _small)
  1856. {
  1857. BGFX_CHECK_MAIN_THREAD();
  1858. s_ctx->dbgTextClear(_attr, _small);
  1859. }
  1860. void dbgTextPrintfVargs(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, va_list _argList)
  1861. {
  1862. s_ctx->dbgTextPrintfVargs(_x, _y, _attr, _format, _argList);
  1863. }
  1864. void dbgTextPrintf(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, ...)
  1865. {
  1866. BGFX_CHECK_MAIN_THREAD();
  1867. va_list argList;
  1868. va_start(argList, _format);
  1869. s_ctx->dbgTextPrintfVargs(_x, _y, _attr, _format, argList);
  1870. va_end(argList);
  1871. }
  1872. void dbgTextImage(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const void* _data, uint16_t _pitch)
  1873. {
  1874. BGFX_CHECK_MAIN_THREAD();
  1875. s_ctx->dbgTextImage(_x, _y, _width, _height, _data, _pitch);
  1876. }
  1877. IndexBufferHandle createIndexBuffer(const Memory* _mem, uint16_t _flags)
  1878. {
  1879. BGFX_CHECK_MAIN_THREAD();
  1880. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1881. return s_ctx->createIndexBuffer(_mem, _flags);
  1882. }
  1883. void destroyIndexBuffer(IndexBufferHandle _handle)
  1884. {
  1885. BGFX_CHECK_MAIN_THREAD();
  1886. s_ctx->destroyIndexBuffer(_handle);
  1887. }
  1888. VertexBufferHandle createVertexBuffer(const Memory* _mem, const VertexDecl& _decl, uint16_t _flags)
  1889. {
  1890. BGFX_CHECK_MAIN_THREAD();
  1891. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1892. BX_CHECK(0 != _decl.m_stride, "Invalid VertexDecl.");
  1893. return s_ctx->createVertexBuffer(_mem, _decl, _flags);
  1894. }
  1895. void destroyVertexBuffer(VertexBufferHandle _handle)
  1896. {
  1897. BGFX_CHECK_MAIN_THREAD();
  1898. s_ctx->destroyVertexBuffer(_handle);
  1899. }
  1900. DynamicIndexBufferHandle createDynamicIndexBuffer(uint32_t _num, uint16_t _flags)
  1901. {
  1902. BGFX_CHECK_MAIN_THREAD();
  1903. return s_ctx->createDynamicIndexBuffer(_num, _flags);
  1904. }
  1905. DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem, uint16_t _flags)
  1906. {
  1907. BGFX_CHECK_MAIN_THREAD();
  1908. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1909. return s_ctx->createDynamicIndexBuffer(_mem, _flags);
  1910. }
  1911. void updateDynamicIndexBuffer(DynamicIndexBufferHandle _handle, uint32_t _startIndex, const Memory* _mem)
  1912. {
  1913. BGFX_CHECK_MAIN_THREAD();
  1914. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1915. s_ctx->updateDynamicIndexBuffer(_handle, _startIndex, _mem);
  1916. }
  1917. void destroyDynamicIndexBuffer(DynamicIndexBufferHandle _handle)
  1918. {
  1919. BGFX_CHECK_MAIN_THREAD();
  1920. s_ctx->destroyDynamicIndexBuffer(_handle);
  1921. }
  1922. DynamicVertexBufferHandle createDynamicVertexBuffer(uint32_t _num, const VertexDecl& _decl, uint16_t _flags)
  1923. {
  1924. BGFX_CHECK_MAIN_THREAD();
  1925. BX_CHECK(0 != _decl.m_stride, "Invalid VertexDecl.");
  1926. return s_ctx->createDynamicVertexBuffer(_num, _decl, _flags);
  1927. }
  1928. DynamicVertexBufferHandle createDynamicVertexBuffer(const Memory* _mem, const VertexDecl& _decl, uint16_t _flags)
  1929. {
  1930. BGFX_CHECK_MAIN_THREAD();
  1931. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1932. BX_CHECK(0 != _decl.m_stride, "Invalid VertexDecl.");
  1933. return s_ctx->createDynamicVertexBuffer(_mem, _decl, _flags);
  1934. }
  1935. void updateDynamicVertexBuffer(DynamicVertexBufferHandle _handle, uint32_t _startVertex, const Memory* _mem)
  1936. {
  1937. BGFX_CHECK_MAIN_THREAD();
  1938. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1939. s_ctx->updateDynamicVertexBuffer(_handle, _startVertex, _mem);
  1940. }
  1941. void destroyDynamicVertexBuffer(DynamicVertexBufferHandle _handle)
  1942. {
  1943. BGFX_CHECK_MAIN_THREAD();
  1944. s_ctx->destroyDynamicVertexBuffer(_handle);
  1945. }
  1946. bool checkAvailTransientIndexBuffer(uint32_t _num)
  1947. {
  1948. BGFX_CHECK_MAIN_THREAD();
  1949. BX_CHECK(0 < _num, "Requesting 0 indices.");
  1950. return s_ctx->checkAvailTransientIndexBuffer(_num);
  1951. }
  1952. bool checkAvailTransientVertexBuffer(uint32_t _num, const VertexDecl& _decl)
  1953. {
  1954. BGFX_CHECK_MAIN_THREAD();
  1955. BX_CHECK(0 < _num, "Requesting 0 vertices.");
  1956. BX_CHECK(0 != _decl.m_stride, "Invalid VertexDecl.");
  1957. return s_ctx->checkAvailTransientVertexBuffer(_num, _decl.m_stride);
  1958. }
  1959. bool checkAvailInstanceDataBuffer(uint32_t _num, uint16_t _stride)
  1960. {
  1961. BGFX_CHECK_MAIN_THREAD();
  1962. BX_CHECK(0 < _num, "Requesting 0 instances.");
  1963. return s_ctx->checkAvailTransientVertexBuffer(_num, _stride);
  1964. }
  1965. bool checkAvailTransientBuffers(uint32_t _numVertices, const VertexDecl& _decl, uint32_t _numIndices)
  1966. {
  1967. BX_CHECK(0 != _decl.m_stride, "Invalid VertexDecl.");
  1968. return checkAvailTransientVertexBuffer(_numVertices, _decl)
  1969. && checkAvailTransientIndexBuffer(_numIndices)
  1970. ;
  1971. }
  1972. void allocTransientIndexBuffer(TransientIndexBuffer* _tib, uint32_t _num)
  1973. {
  1974. BGFX_CHECK_MAIN_THREAD();
  1975. BX_CHECK(NULL != _tib, "_tib can't be NULL");
  1976. BX_CHECK(0 < _num, "Requesting 0 indices.");
  1977. return s_ctx->allocTransientIndexBuffer(_tib, _num);
  1978. }
  1979. void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint32_t _num, const VertexDecl& _decl)
  1980. {
  1981. BGFX_CHECK_MAIN_THREAD();
  1982. BX_CHECK(NULL != _tvb, "_tvb can't be NULL");
  1983. BX_CHECK(0 < _num, "Requesting 0 vertices.");
  1984. BX_CHECK(UINT16_MAX >= _num, "Requesting %d vertices (max: %d).", _num, UINT16_MAX);
  1985. BX_CHECK(0 != _decl.m_stride, "Invalid VertexDecl.");
  1986. return s_ctx->allocTransientVertexBuffer(_tvb, _num, _decl);
  1987. }
  1988. bool allocTransientBuffers(bgfx::TransientVertexBuffer* _tvb, const bgfx::VertexDecl& _decl, uint32_t _numVertices, bgfx::TransientIndexBuffer* _tib, uint32_t _numIndices)
  1989. {
  1990. if (checkAvailTransientBuffers(_numVertices, _decl, _numIndices) )
  1991. {
  1992. allocTransientVertexBuffer(_tvb, _numVertices, _decl);
  1993. allocTransientIndexBuffer(_tib, _numIndices);
  1994. return true;
  1995. }
  1996. return false;
  1997. }
  1998. const InstanceDataBuffer* allocInstanceDataBuffer(uint32_t _num, uint16_t _stride)
  1999. {
  2000. BGFX_CHECK_MAIN_THREAD();
  2001. BX_CHECK(0 != (g_caps.supported & BGFX_CAPS_INSTANCING), "Instancing is not supported! Use bgfx::getCaps to check backend renderer capabilities.");
  2002. BX_CHECK(0 < _num, "Requesting 0 instanced data vertices.");
  2003. return s_ctx->allocInstanceDataBuffer(_num, _stride);
  2004. }
  2005. IndirectBufferHandle createIndirectBuffer(uint32_t _num)
  2006. {
  2007. BGFX_CHECK_MAIN_THREAD();
  2008. return s_ctx->createIndirectBuffer(_num);
  2009. }
  2010. void destroyIndirectBuffer(IndirectBufferHandle _handle)
  2011. {
  2012. BGFX_CHECK_MAIN_THREAD();
  2013. s_ctx->destroyIndirectBuffer(_handle);
  2014. }
  2015. ShaderHandle createShader(const Memory* _mem)
  2016. {
  2017. BGFX_CHECK_MAIN_THREAD();
  2018. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  2019. return s_ctx->createShader(_mem);
  2020. }
  2021. uint16_t getShaderUniforms(ShaderHandle _handle, UniformHandle* _uniforms, uint16_t _max)
  2022. {
  2023. BGFX_CHECK_MAIN_THREAD();
  2024. return s_ctx->getShaderUniforms(_handle, _uniforms, _max);
  2025. }
  2026. void destroyShader(ShaderHandle _handle)
  2027. {
  2028. BGFX_CHECK_MAIN_THREAD();
  2029. s_ctx->destroyShader(_handle);
  2030. }
  2031. ProgramHandle createProgram(ShaderHandle _vsh, ShaderHandle _fsh, bool _destroyShaders)
  2032. {
  2033. BGFX_CHECK_MAIN_THREAD();
  2034. ProgramHandle handle = s_ctx->createProgram(_vsh, _fsh);
  2035. if (_destroyShaders)
  2036. {
  2037. destroyShader(_vsh);
  2038. destroyShader(_fsh);
  2039. }
  2040. return handle;
  2041. }
  2042. ProgramHandle createProgram(ShaderHandle _csh, bool _destroyShader)
  2043. {
  2044. BGFX_CHECK_MAIN_THREAD();
  2045. ProgramHandle handle = s_ctx->createProgram(_csh);
  2046. if (_destroyShader)
  2047. {
  2048. destroyShader(_csh);
  2049. }
  2050. return handle;
  2051. }
  2052. void destroyProgram(ProgramHandle _handle)
  2053. {
  2054. BGFX_CHECK_MAIN_THREAD();
  2055. s_ctx->destroyProgram(_handle);
  2056. }
  2057. void calcTextureSize(TextureInfo& _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, uint8_t _numMips, TextureFormat::Enum _format)
  2058. {
  2059. const ImageBlockInfo& blockInfo = getBlockInfo(_format);
  2060. const uint8_t bpp = blockInfo.bitsPerPixel;
  2061. const uint16_t blockWidth = blockInfo.blockWidth;
  2062. const uint16_t blockHeight = blockInfo.blockHeight;
  2063. const uint16_t minBlockX = blockInfo.minBlockX;
  2064. const uint16_t minBlockY = blockInfo.minBlockY;
  2065. _width = bx::uint16_max(blockWidth * minBlockX, ( (_width + blockWidth - 1) / blockWidth)*blockWidth);
  2066. _height = bx::uint16_max(blockHeight * minBlockY, ( (_height + blockHeight - 1) / blockHeight)*blockHeight);
  2067. _depth = bx::uint16_max(1, _depth);
  2068. _numMips = uint8_t(bx::uint16_max(1, _numMips) );
  2069. uint32_t width = _width;
  2070. uint32_t height = _height;
  2071. uint32_t depth = _depth;
  2072. uint32_t sides = _cubeMap ? 6 : 1;
  2073. uint32_t size = 0;
  2074. for (uint32_t lod = 0; lod < _numMips; ++lod)
  2075. {
  2076. width = bx::uint32_max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth);
  2077. height = bx::uint32_max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight);
  2078. depth = bx::uint32_max(1, depth);
  2079. size += width*height*depth*bpp/8 * sides;
  2080. width >>= 1;
  2081. height >>= 1;
  2082. depth >>= 1;
  2083. }
  2084. _info.format = _format;
  2085. _info.width = _width;
  2086. _info.height = _height;
  2087. _info.depth = _depth;
  2088. _info.numMips = _numMips;
  2089. _info.cubeMap = _cubeMap;
  2090. _info.storageSize = size;
  2091. _info.bitsPerPixel = bpp;
  2092. }
  2093. TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint8_t _skip, TextureInfo* _info)
  2094. {
  2095. BGFX_CHECK_MAIN_THREAD();
  2096. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  2097. return s_ctx->createTexture(_mem, _flags, _skip, _info, BackbufferRatio::Count);
  2098. }
  2099. void getTextureSizeFromRatio(BackbufferRatio::Enum _ratio, uint16_t& _width, uint16_t& _height)
  2100. {
  2101. switch (_ratio)
  2102. {
  2103. case BackbufferRatio::Half: _width /= 2; _height /= 2; break;
  2104. case BackbufferRatio::Quarter: _width /= 4; _height /= 4; break;
  2105. case BackbufferRatio::Eighth: _width /= 8; _height /= 8; break;
  2106. case BackbufferRatio::Sixteenth: _width /= 16; _height /= 16; break;
  2107. case BackbufferRatio::Double: _width *= 2; _height *= 2; break;
  2108. default:
  2109. break;
  2110. }
  2111. _width = bx::uint16_max(1, _width);
  2112. _height = bx::uint16_max(1, _height);
  2113. }
  2114. TextureHandle createTexture2D(BackbufferRatio::Enum _ratio, uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
  2115. {
  2116. BGFX_CHECK_MAIN_THREAD();
  2117. _numMips = uint8_t(bx::uint32_max(1, _numMips) );
  2118. if (BX_ENABLED(BGFX_CONFIG_DEBUG)
  2119. && NULL != _mem)
  2120. {
  2121. TextureInfo ti;
  2122. calcTextureSize(ti, _width, _height, 1, false, _numMips, _format);
  2123. BX_CHECK(ti.storageSize == _mem->size
  2124. , "createTexture2D: Texture storage size doesn't match passed memory size (storage size: %d, memory size: %d)"
  2125. , ti.storageSize
  2126. , _mem->size
  2127. );
  2128. }
  2129. uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
  2130. const Memory* mem = alloc(size);
  2131. bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
  2132. uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
  2133. bx::write(&writer, magic);
  2134. if (BackbufferRatio::Count != _ratio)
  2135. {
  2136. _width = uint16_t(s_ctx->m_frame->m_resolution.m_width);
  2137. _height = uint16_t(s_ctx->m_frame->m_resolution.m_height);
  2138. getTextureSizeFromRatio(_ratio, _width, _height);
  2139. }
  2140. TextureCreate tc;
  2141. tc.m_flags = _flags;
  2142. tc.m_width = _width;
  2143. tc.m_height = _height;
  2144. tc.m_sides = 0;
  2145. tc.m_depth = 0;
  2146. tc.m_numMips = _numMips;
  2147. tc.m_format = uint8_t(_format);
  2148. tc.m_cubeMap = false;
  2149. tc.m_mem = _mem;
  2150. bx::write(&writer, tc);
  2151. return s_ctx->createTexture(mem, _flags, 0, NULL, _ratio);
  2152. }
  2153. TextureHandle createTexture2D(uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
  2154. {
  2155. BX_CHECK(_width > 0 && _height > 0, "Invalid texture size (width %d, height %d).", _width, _height);
  2156. return createTexture2D(BackbufferRatio::Count, _width, _height, _numMips, _format, _flags, _mem);
  2157. }
  2158. TextureHandle createTexture2D(BackbufferRatio::Enum _ratio, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags)
  2159. {
  2160. BX_CHECK(_ratio < BackbufferRatio::Count, "Invalid back buffer ratio.");
  2161. return createTexture2D(_ratio, 0, 0, _numMips, _format, _flags, NULL);
  2162. }
  2163. TextureHandle createTexture3D(uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
  2164. {
  2165. BGFX_CHECK_MAIN_THREAD();
  2166. BX_CHECK(0 != (g_caps.supported & BGFX_CAPS_TEXTURE_3D), "Texture3D is not supported! Use bgfx::getCaps to check backend renderer capabilities.");
  2167. _numMips = uint8_t(bx::uint32_max(1, _numMips) );
  2168. if (BX_ENABLED(BGFX_CONFIG_DEBUG)
  2169. && NULL != _mem)
  2170. {
  2171. TextureInfo ti;
  2172. calcTextureSize(ti, _width, _height, _depth, false, _numMips, _format);
  2173. BX_CHECK(ti.storageSize == _mem->size
  2174. , "createTexture3D: Texture storage size doesn't match passed memory size (storage size: %d, memory size: %d)"
  2175. , ti.storageSize
  2176. , _mem->size
  2177. );
  2178. }
  2179. uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
  2180. const Memory* mem = alloc(size);
  2181. bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
  2182. uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
  2183. bx::write(&writer, magic);
  2184. TextureCreate tc;
  2185. tc.m_flags = _flags;
  2186. tc.m_width = _width;
  2187. tc.m_height = _height;
  2188. tc.m_sides = 0;
  2189. tc.m_depth = _depth;
  2190. tc.m_numMips = _numMips;
  2191. tc.m_format = uint8_t(_format);
  2192. tc.m_cubeMap = false;
  2193. tc.m_mem = _mem;
  2194. bx::write(&writer, tc);
  2195. return s_ctx->createTexture(mem, _flags, 0, NULL, BackbufferRatio::Count);
  2196. }
  2197. TextureHandle createTextureCube(uint16_t _size, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
  2198. {
  2199. BGFX_CHECK_MAIN_THREAD();
  2200. _numMips = uint8_t(bx::uint32_max(1, _numMips) );
  2201. if (BX_ENABLED(BGFX_CONFIG_DEBUG)
  2202. && NULL != _mem)
  2203. {
  2204. TextureInfo ti;
  2205. calcTextureSize(ti, _size, _size, 1, true, _numMips, _format);
  2206. BX_CHECK(ti.storageSize == _mem->size
  2207. , "createTextureCube: Texture storage size doesn't match passed memory size (storage size: %d, memory size: %d)"
  2208. , ti.storageSize
  2209. , _mem->size
  2210. );
  2211. }
  2212. uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
  2213. const Memory* mem = alloc(size);
  2214. bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
  2215. uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
  2216. bx::write(&writer, magic);
  2217. TextureCreate tc;
  2218. tc.m_flags = _flags;
  2219. tc.m_width = _size;
  2220. tc.m_height = _size;
  2221. tc.m_sides = 6;
  2222. tc.m_depth = 0;
  2223. tc.m_numMips = _numMips;
  2224. tc.m_format = uint8_t(_format);
  2225. tc.m_cubeMap = true;
  2226. tc.m_mem = _mem;
  2227. bx::write(&writer, tc);
  2228. return s_ctx->createTexture(mem, _flags, 0, NULL, BackbufferRatio::Count);
  2229. }
  2230. void destroyTexture(TextureHandle _handle)
  2231. {
  2232. BGFX_CHECK_MAIN_THREAD();
  2233. s_ctx->destroyTexture(_handle);
  2234. }
  2235. void updateTexture2D(TextureHandle _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const Memory* _mem, uint16_t _pitch)
  2236. {
  2237. BGFX_CHECK_MAIN_THREAD();
  2238. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  2239. if (_width == 0
  2240. || _height == 0)
  2241. {
  2242. release(_mem);
  2243. }
  2244. else
  2245. {
  2246. s_ctx->updateTexture(_handle, 0, _mip, _x, _y, 0, _width, _height, 1, _pitch, _mem);
  2247. }
  2248. }
  2249. void updateTexture3D(TextureHandle _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _z, uint16_t _width, uint16_t _height, uint16_t _depth, const Memory* _mem)
  2250. {
  2251. BGFX_CHECK_MAIN_THREAD();
  2252. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  2253. if (_width == 0
  2254. || _height == 0
  2255. || _depth == 0)
  2256. {
  2257. release(_mem);
  2258. }
  2259. else
  2260. {
  2261. s_ctx->updateTexture(_handle, 0, _mip, _x, _y, _z, _width, _height, _depth, UINT16_MAX, _mem);
  2262. }
  2263. }
  2264. void updateTextureCube(TextureHandle _handle, uint8_t _side, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const Memory* _mem, uint16_t _pitch)
  2265. {
  2266. BGFX_CHECK_MAIN_THREAD();
  2267. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  2268. BX_CHECK(_side <= 5, "Invalid side %d.", _side);
  2269. if (_width == 0
  2270. || _height == 0)
  2271. {
  2272. release(_mem);
  2273. }
  2274. else
  2275. {
  2276. s_ctx->updateTexture(_handle, _side, _mip, _x, _y, 0, _width, _height, 1, _pitch, _mem);
  2277. }
  2278. }
  2279. FrameBufferHandle createFrameBuffer(uint16_t _width, uint16_t _height, TextureFormat::Enum _format, uint32_t _textureFlags)
  2280. {
  2281. _textureFlags |= _textureFlags&BGFX_TEXTURE_RT_MSAA_MASK ? 0 : BGFX_TEXTURE_RT;
  2282. TextureHandle th = createTexture2D(_width, _height, 1, _format, _textureFlags);
  2283. return createFrameBuffer(1, &th, true);
  2284. }
  2285. FrameBufferHandle createFrameBuffer(BackbufferRatio::Enum _ratio, TextureFormat::Enum _format, uint32_t _textureFlags)
  2286. {
  2287. BX_CHECK(_ratio < BackbufferRatio::Count, "Invalid back buffer ratio.");
  2288. _textureFlags |= _textureFlags&BGFX_TEXTURE_RT_MSAA_MASK ? 0 : BGFX_TEXTURE_RT;
  2289. TextureHandle th = createTexture2D(_ratio, 1, _format, _textureFlags);
  2290. return createFrameBuffer(1, &th, true);
  2291. }
  2292. FrameBufferHandle createFrameBuffer(uint8_t _num, TextureHandle* _handles, bool _destroyTextures)
  2293. {
  2294. BGFX_CHECK_MAIN_THREAD();
  2295. BX_CHECK(_num != 0, "Number of frame buffer attachments can't be 0.");
  2296. BX_CHECK(_num <= BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS, "Number of frame buffer attachments is larger than allowed %d (max: %d)."
  2297. , _num
  2298. , BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS
  2299. );
  2300. BX_CHECK(NULL != _handles, "_handles can't be NULL");
  2301. FrameBufferHandle handle = s_ctx->createFrameBuffer(_num, _handles);
  2302. if (_destroyTextures)
  2303. {
  2304. for (uint32_t ii = 0; ii < _num; ++ii)
  2305. {
  2306. destroyTexture(_handles[ii]);
  2307. }
  2308. }
  2309. return handle;
  2310. }
  2311. FrameBufferHandle createFrameBuffer(void* _nwh, uint16_t _width, uint16_t _height, TextureFormat::Enum _depthFormat)
  2312. {
  2313. BGFX_CHECK_MAIN_THREAD();
  2314. return s_ctx->createFrameBuffer(_nwh, _width, _height, _depthFormat);
  2315. }
  2316. void destroyFrameBuffer(FrameBufferHandle _handle)
  2317. {
  2318. BGFX_CHECK_MAIN_THREAD();
  2319. s_ctx->destroyFrameBuffer(_handle);
  2320. }
  2321. UniformHandle createUniform(const char* _name, UniformType::Enum _type, uint16_t _num)
  2322. {
  2323. BGFX_CHECK_MAIN_THREAD();
  2324. return s_ctx->createUniform(_name, _type, _num);
  2325. }
  2326. void destroyUniform(UniformHandle _handle)
  2327. {
  2328. BGFX_CHECK_MAIN_THREAD();
  2329. s_ctx->destroyUniform(_handle);
  2330. }
  2331. void setClearColor(uint8_t _index, uint32_t _rgba)
  2332. {
  2333. BGFX_CHECK_MAIN_THREAD();
  2334. const uint8_t rr = uint8_t(_rgba>>24);
  2335. const uint8_t gg = uint8_t(_rgba>>16);
  2336. const uint8_t bb = uint8_t(_rgba>> 8);
  2337. const uint8_t aa = uint8_t(_rgba>> 0);
  2338. float rgba[4] =
  2339. {
  2340. rr * 1.0f/255.0f,
  2341. gg * 1.0f/255.0f,
  2342. bb * 1.0f/255.0f,
  2343. aa * 1.0f/255.0f,
  2344. };
  2345. s_ctx->setClearColor(_index, rgba);
  2346. }
  2347. void setClearColor(uint8_t _index, float _r, float _g, float _b, float _a)
  2348. {
  2349. BGFX_CHECK_MAIN_THREAD();
  2350. float rgba[4] = { _r, _g, _b, _a };
  2351. s_ctx->setClearColor(_index, rgba);
  2352. }
  2353. void setClearColor(uint8_t _index, const float _rgba[4])
  2354. {
  2355. BGFX_CHECK_MAIN_THREAD();
  2356. s_ctx->setClearColor(_index, _rgba);
  2357. }
  2358. bool checkView(uint8_t _id)
  2359. {
  2360. // workaround GCC 4.9 type-limit check.
  2361. const uint32_t id = _id;
  2362. return id < BGFX_CONFIG_MAX_VIEWS;
  2363. }
  2364. void setViewName(uint8_t _id, const char* _name)
  2365. {
  2366. BGFX_CHECK_MAIN_THREAD();
  2367. BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
  2368. s_ctx->setViewName(_id, _name);
  2369. }
  2370. void setViewRect(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  2371. {
  2372. BGFX_CHECK_MAIN_THREAD();
  2373. BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
  2374. s_ctx->setViewRect(_id, _x, _y, _width, _height);
  2375. }
  2376. void setViewScissor(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  2377. {
  2378. BGFX_CHECK_MAIN_THREAD();
  2379. BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
  2380. s_ctx->setViewScissor(_id, _x, _y, _width, _height);
  2381. }
  2382. void setViewClear(uint8_t _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
  2383. {
  2384. BGFX_CHECK_MAIN_THREAD();
  2385. BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
  2386. s_ctx->setViewClear(_id, _flags, _rgba, _depth, _stencil);
  2387. }
  2388. void setViewClear(uint8_t _id, uint16_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7)
  2389. {
  2390. BGFX_CHECK_MAIN_THREAD();
  2391. BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
  2392. s_ctx->setViewClear(_id, _flags, _depth, _stencil, _0, _1, _2, _3, _4, _5, _6, _7);
  2393. }
  2394. void setViewSeq(uint8_t _id, bool _enabled)
  2395. {
  2396. BGFX_CHECK_MAIN_THREAD();
  2397. BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
  2398. s_ctx->setViewSeq(_id, _enabled);
  2399. }
  2400. void setViewFrameBuffer(uint8_t _id, FrameBufferHandle _handle)
  2401. {
  2402. BGFX_CHECK_MAIN_THREAD();
  2403. BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
  2404. s_ctx->setViewFrameBuffer(_id, _handle);
  2405. }
  2406. void setViewTransform(uint8_t _id, const void* _view, const void* _projL, uint8_t _flags, const void* _projR)
  2407. {
  2408. BGFX_CHECK_MAIN_THREAD();
  2409. BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
  2410. s_ctx->setViewTransform(_id, _view, _projL, _flags, _projR);
  2411. }
  2412. void setViewRemap(uint8_t _id, uint8_t _num, const void* _remap)
  2413. {
  2414. BGFX_CHECK_MAIN_THREAD();
  2415. BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
  2416. s_ctx->setViewRemap(_id, _num, _remap);
  2417. }
  2418. void setMarker(const char* _marker)
  2419. {
  2420. BGFX_CHECK_MAIN_THREAD();
  2421. s_ctx->setMarker(_marker);
  2422. }
  2423. void setState(uint64_t _state, uint32_t _rgba)
  2424. {
  2425. BGFX_CHECK_MAIN_THREAD();
  2426. s_ctx->setState(_state, _rgba);
  2427. }
  2428. void setStencil(uint32_t _fstencil, uint32_t _bstencil)
  2429. {
  2430. BGFX_CHECK_MAIN_THREAD();
  2431. s_ctx->setStencil(_fstencil, _bstencil);
  2432. }
  2433. uint16_t setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  2434. {
  2435. BGFX_CHECK_MAIN_THREAD();
  2436. return s_ctx->setScissor(_x, _y, _width, _height);
  2437. }
  2438. void setScissor(uint16_t _cache)
  2439. {
  2440. BGFX_CHECK_MAIN_THREAD();
  2441. s_ctx->setScissor(_cache);
  2442. }
  2443. uint32_t setTransform(const void* _mtx, uint16_t _num)
  2444. {
  2445. BGFX_CHECK_MAIN_THREAD();
  2446. return s_ctx->setTransform(_mtx, _num);
  2447. }
  2448. uint32_t allocTransform(Transform* _transform, uint16_t _num)
  2449. {
  2450. BGFX_CHECK_MAIN_THREAD();
  2451. return s_ctx->allocTransform(_transform, _num);
  2452. }
  2453. void setTransform(uint32_t _cache, uint16_t _num)
  2454. {
  2455. BGFX_CHECK_MAIN_THREAD();
  2456. s_ctx->setTransform(_cache, _num);
  2457. }
  2458. void setUniform(UniformHandle _handle, const void* _value, uint16_t _num)
  2459. {
  2460. BGFX_CHECK_MAIN_THREAD();
  2461. s_ctx->setUniform(_handle, _value, _num);
  2462. }
  2463. void setIndexBuffer(IndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices)
  2464. {
  2465. BGFX_CHECK_MAIN_THREAD();
  2466. s_ctx->setIndexBuffer(_handle, _firstIndex, _numIndices);
  2467. }
  2468. void setIndexBuffer(DynamicIndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices)
  2469. {
  2470. BGFX_CHECK_MAIN_THREAD();
  2471. s_ctx->setIndexBuffer(_handle, _firstIndex, _numIndices);
  2472. }
  2473. void setIndexBuffer(const TransientIndexBuffer* _tib)
  2474. {
  2475. setIndexBuffer(_tib, 0, UINT32_MAX);
  2476. }
  2477. void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _firstIndex, uint32_t _numIndices)
  2478. {
  2479. BGFX_CHECK_MAIN_THREAD();
  2480. BX_CHECK(NULL != _tib, "_tib can't be NULL");
  2481. uint32_t numIndices = bx::uint32_min(_numIndices, _tib->size/2);
  2482. s_ctx->setIndexBuffer(_tib, _tib->startIndex + _firstIndex, numIndices);
  2483. }
  2484. void setVertexBuffer(VertexBufferHandle _handle)
  2485. {
  2486. setVertexBuffer(_handle, 0, UINT32_MAX);
  2487. }
  2488. void setVertexBuffer(VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _numVertices)
  2489. {
  2490. BGFX_CHECK_MAIN_THREAD();
  2491. s_ctx->setVertexBuffer(_handle, _startVertex, _numVertices);
  2492. }
  2493. void setVertexBuffer(DynamicVertexBufferHandle _handle, uint32_t _numVertices)
  2494. {
  2495. BGFX_CHECK_MAIN_THREAD();
  2496. s_ctx->setVertexBuffer(_handle, _numVertices);
  2497. }
  2498. void setVertexBuffer(const TransientVertexBuffer* _tvb)
  2499. {
  2500. setVertexBuffer(_tvb, 0, UINT32_MAX);
  2501. }
  2502. void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _startVertex, uint32_t _numVertices)
  2503. {
  2504. BGFX_CHECK_MAIN_THREAD();
  2505. BX_CHECK(NULL != _tvb, "_tvb can't be NULL");
  2506. s_ctx->setVertexBuffer(_tvb, _startVertex, _numVertices);
  2507. }
  2508. void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint32_t _num)
  2509. {
  2510. BGFX_CHECK_MAIN_THREAD();
  2511. BX_CHECK(NULL != _idb, "_idb can't be NULL");
  2512. s_ctx->setInstanceDataBuffer(_idb, _num);
  2513. }
  2514. void setInstanceDataBuffer(VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _num)
  2515. {
  2516. BGFX_CHECK_MAIN_THREAD();
  2517. s_ctx->setInstanceDataBuffer(_handle, _startVertex, _num);
  2518. }
  2519. void setInstanceDataBuffer(DynamicVertexBufferHandle _handle, uint32_t _startVertex, uint32_t _num)
  2520. {
  2521. BGFX_CHECK_MAIN_THREAD();
  2522. s_ctx->setInstanceDataBuffer(_handle, _startVertex, _num);
  2523. }
  2524. void setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint32_t _flags)
  2525. {
  2526. BGFX_CHECK_MAIN_THREAD();
  2527. s_ctx->setTexture(_stage, _sampler, _handle, _flags);
  2528. }
  2529. void setTexture(uint8_t _stage, UniformHandle _sampler, FrameBufferHandle _handle, uint8_t _attachment, uint32_t _flags)
  2530. {
  2531. BGFX_CHECK_MAIN_THREAD();
  2532. s_ctx->setTexture(_stage, _sampler, _handle, _attachment, _flags);
  2533. }
  2534. uint32_t touch(uint8_t _id)
  2535. {
  2536. ProgramHandle handle = BGFX_INVALID_HANDLE;
  2537. return submit(_id, handle);
  2538. }
  2539. uint32_t submit(uint8_t _id, ProgramHandle _handle, int32_t _depth)
  2540. {
  2541. BGFX_CHECK_MAIN_THREAD();
  2542. return s_ctx->submit(_id, _handle, _depth);
  2543. }
  2544. uint32_t submit(uint8_t _id, ProgramHandle _handle, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, int32_t _depth)
  2545. {
  2546. BGFX_CHECK_MAIN_THREAD();
  2547. return s_ctx->submit(_id, _handle, _indirectHandle, _start, _num, _depth);
  2548. }
  2549. void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access)
  2550. {
  2551. BGFX_CHECK_MAIN_THREAD();
  2552. s_ctx->setBuffer(_stage, _handle, _access);
  2553. }
  2554. void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access)
  2555. {
  2556. BGFX_CHECK_MAIN_THREAD();
  2557. s_ctx->setBuffer(_stage, _handle, _access);
  2558. }
  2559. void setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access)
  2560. {
  2561. BGFX_CHECK_MAIN_THREAD();
  2562. s_ctx->setBuffer(_stage, _handle, _access);
  2563. }
  2564. void setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access)
  2565. {
  2566. BGFX_CHECK_MAIN_THREAD();
  2567. s_ctx->setBuffer(_stage, _handle, _access);
  2568. }
  2569. void setBuffer(uint8_t _stage, IndirectBufferHandle _handle, Access::Enum _access)
  2570. {
  2571. BGFX_CHECK_MAIN_THREAD();
  2572. s_ctx->setBuffer(_stage, _handle, _access);
  2573. }
  2574. void setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format)
  2575. {
  2576. BGFX_CHECK_MAIN_THREAD();
  2577. s_ctx->setImage(_stage, _sampler, _handle, _mip, _access, _format);
  2578. }
  2579. void setImage(uint8_t _stage, UniformHandle _sampler, FrameBufferHandle _handle, uint8_t _attachment, Access::Enum _access, TextureFormat::Enum _format)
  2580. {
  2581. BGFX_CHECK_MAIN_THREAD();
  2582. s_ctx->setImage(_stage, _sampler, _handle, _attachment, _access, _format);
  2583. }
  2584. uint32_t dispatch(uint8_t _id, ProgramHandle _handle, uint16_t _numX, uint16_t _numY, uint16_t _numZ, uint8_t _flags)
  2585. {
  2586. BGFX_CHECK_MAIN_THREAD();
  2587. return s_ctx->dispatch(_id, _handle, _numX, _numY, _numZ, _flags);
  2588. }
  2589. uint32_t dispatch(uint8_t _id, ProgramHandle _handle, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags)
  2590. {
  2591. BGFX_CHECK_MAIN_THREAD();
  2592. return s_ctx->dispatch(_id, _handle, _indirectHandle, _start, _num, _flags);
  2593. }
  2594. void discard()
  2595. {
  2596. BGFX_CHECK_MAIN_THREAD();
  2597. s_ctx->discard();
  2598. }
  2599. void saveScreenShot(const char* _filePath)
  2600. {
  2601. BGFX_CHECK_MAIN_THREAD();
  2602. s_ctx->saveScreenShot(_filePath);
  2603. }
  2604. } // namespace bgfx
  2605. #include <bgfx.c99.h>
  2606. #include <bgfxplatform.c99.h>
  2607. BX_STATIC_ASSERT(bgfx::Fatal::Count == bgfx::Fatal::Enum(BGFX_FATAL_COUNT) );
  2608. BX_STATIC_ASSERT(bgfx::RendererType::Count == bgfx::RendererType::Enum(BGFX_RENDERER_TYPE_COUNT) );
  2609. BX_STATIC_ASSERT(bgfx::Attrib::Count == bgfx::Attrib::Enum(BGFX_ATTRIB_COUNT) );
  2610. BX_STATIC_ASSERT(bgfx::AttribType::Count == bgfx::AttribType::Enum(BGFX_ATTRIB_TYPE_COUNT) );
  2611. BX_STATIC_ASSERT(bgfx::TextureFormat::Count == bgfx::TextureFormat::Enum(BGFX_TEXTURE_FORMAT_COUNT) );
  2612. BX_STATIC_ASSERT(bgfx::UniformType::Count == bgfx::UniformType::Enum(BGFX_UNIFORM_TYPE_COUNT) );
  2613. BX_STATIC_ASSERT(bgfx::RenderFrame::Count == bgfx::RenderFrame::Enum(BGFX_RENDER_FRAME_COUNT) );
  2614. BX_STATIC_ASSERT(sizeof(bgfx::Memory) == sizeof(bgfx_memory_t) );
  2615. BX_STATIC_ASSERT(sizeof(bgfx::VertexDecl) == sizeof(bgfx_vertex_decl_t) );
  2616. BX_STATIC_ASSERT(sizeof(bgfx::TransientIndexBuffer) == sizeof(bgfx_transient_index_buffer_t) );
  2617. BX_STATIC_ASSERT(sizeof(bgfx::TransientVertexBuffer) == sizeof(bgfx_transient_vertex_buffer_t) );
  2618. BX_STATIC_ASSERT(sizeof(bgfx::InstanceDataBuffer) == sizeof(bgfx_instance_data_buffer_t) );
  2619. BX_STATIC_ASSERT(sizeof(bgfx::TextureInfo) == sizeof(bgfx_texture_info_t) );
  2620. BX_STATIC_ASSERT(sizeof(bgfx::Caps) == sizeof(bgfx_caps_t) );
  2621. BX_STATIC_ASSERT(sizeof(bgfx::PlatformData) == sizeof(bgfx_platform_data_t) );
  2622. namespace bgfx
  2623. {
  2624. struct CallbackC99 : public CallbackI
  2625. {
  2626. virtual ~CallbackC99()
  2627. {
  2628. }
  2629. virtual void fatal(Fatal::Enum _code, const char* _str) BX_OVERRIDE
  2630. {
  2631. m_interface->vtbl->fatal(m_interface, (bgfx_fatal_t)_code, _str);
  2632. }
  2633. virtual void traceVargs(const char* _filePath, uint16_t _line, const char* _format, va_list _argList) BX_OVERRIDE
  2634. {
  2635. m_interface->vtbl->trace_vargs(m_interface, _filePath, _line, _format, _argList);
  2636. }
  2637. virtual uint32_t cacheReadSize(uint64_t _id) BX_OVERRIDE
  2638. {
  2639. return m_interface->vtbl->cache_read_size(m_interface, _id);
  2640. }
  2641. virtual bool cacheRead(uint64_t _id, void* _data, uint32_t _size) BX_OVERRIDE
  2642. {
  2643. return m_interface->vtbl->cache_read(m_interface, _id, _data, _size);
  2644. }
  2645. virtual void cacheWrite(uint64_t _id, const void* _data, uint32_t _size) BX_OVERRIDE
  2646. {
  2647. m_interface->vtbl->cache_write(m_interface, _id, _data, _size);
  2648. }
  2649. virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t _size, bool _yflip) BX_OVERRIDE
  2650. {
  2651. m_interface->vtbl->screen_shot(m_interface, _filePath, _width, _height, _pitch, _data, _size, _yflip);
  2652. }
  2653. virtual void captureBegin(uint32_t _width, uint32_t _height, uint32_t _pitch, TextureFormat::Enum _format, bool _yflip) BX_OVERRIDE
  2654. {
  2655. m_interface->vtbl->capture_begin(m_interface, _width, _height, _pitch, (bgfx_texture_format_t)_format, _yflip);
  2656. }
  2657. virtual void captureEnd() BX_OVERRIDE
  2658. {
  2659. m_interface->vtbl->capture_end(m_interface);
  2660. }
  2661. virtual void captureFrame(const void* _data, uint32_t _size) BX_OVERRIDE
  2662. {
  2663. m_interface->vtbl->capture_frame(m_interface, _data, _size);
  2664. }
  2665. bgfx_callback_interface_t* m_interface;
  2666. };
  2667. class AllocatorC99 : public bx::ReallocatorI
  2668. {
  2669. public:
  2670. virtual ~AllocatorC99()
  2671. {
  2672. }
  2673. virtual void* alloc(size_t _size, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE
  2674. {
  2675. return m_interface->vtbl->alloc(m_interface, _size, _align, _file, _line);
  2676. }
  2677. virtual void free(void* _ptr, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE
  2678. {
  2679. m_interface->vtbl->free(m_interface, _ptr, _align, _file, _line);
  2680. }
  2681. virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE
  2682. {
  2683. return m_interface->vtbl->realloc(m_interface, _ptr, _size, _align, _file, _line);
  2684. }
  2685. bgfx_reallocator_interface_t* m_interface;
  2686. };
  2687. } // namespace bgfx
  2688. BGFX_C_API void bgfx_vertex_decl_begin(bgfx_vertex_decl_t* _decl, bgfx_renderer_type_t _renderer)
  2689. {
  2690. bgfx::VertexDecl* decl = (bgfx::VertexDecl*)_decl;
  2691. decl->begin(bgfx::RendererType::Enum(_renderer) );
  2692. }
  2693. BGFX_C_API void bgfx_vertex_decl_add(bgfx_vertex_decl_t* _decl, bgfx_attrib_t _attrib, uint8_t _num, bgfx_attrib_type_t _type, bool _normalized, bool _asInt)
  2694. {
  2695. bgfx::VertexDecl* decl = (bgfx::VertexDecl*)_decl;
  2696. decl->add(bgfx::Attrib::Enum(_attrib)
  2697. , _num
  2698. , bgfx::AttribType::Enum(_type)
  2699. , _normalized
  2700. , _asInt
  2701. );
  2702. }
  2703. BGFX_C_API void bgfx_vertex_decl_skip(bgfx_vertex_decl_t* _decl, uint8_t _num)
  2704. {
  2705. bgfx::VertexDecl* decl = (bgfx::VertexDecl*)_decl;
  2706. decl->skip(_num);
  2707. }
  2708. BGFX_C_API void bgfx_vertex_decl_end(bgfx_vertex_decl_t* _decl)
  2709. {
  2710. bgfx::VertexDecl* decl = (bgfx::VertexDecl*)_decl;
  2711. decl->end();
  2712. }
  2713. BGFX_C_API void bgfx_vertex_pack(const float _input[4], bool _inputNormalized, bgfx_attrib_t _attr, const bgfx_vertex_decl_t* _decl, void* _data, uint32_t _index)
  2714. {
  2715. bgfx::VertexDecl& decl = *(bgfx::VertexDecl*)_decl;
  2716. bgfx::vertexPack(_input, _inputNormalized, bgfx::Attrib::Enum(_attr), decl, _data, _index);
  2717. }
  2718. BGFX_C_API void bgfx_vertex_unpack(float _output[4], bgfx_attrib_t _attr, const bgfx_vertex_decl_t* _decl, const void* _data, uint32_t _index)
  2719. {
  2720. bgfx::VertexDecl& decl = *(bgfx::VertexDecl*)_decl;
  2721. bgfx::vertexUnpack(_output, bgfx::Attrib::Enum(_attr), decl, _data, _index);
  2722. }
  2723. BGFX_C_API void bgfx_vertex_convert(const bgfx_vertex_decl_t* _destDecl, void* _destData, const bgfx_vertex_decl_t* _srcDecl, const void* _srcData, uint32_t _num)
  2724. {
  2725. bgfx::VertexDecl& destDecl = *(bgfx::VertexDecl*)_destDecl;
  2726. bgfx::VertexDecl& srcDecl = *(bgfx::VertexDecl*)_srcDecl;
  2727. bgfx::vertexConvert(destDecl, _destData, srcDecl, _srcData, _num);
  2728. }
  2729. BGFX_C_API uint16_t bgfx_weld_vertices(uint16_t* _output, const bgfx_vertex_decl_t* _decl, const void* _data, uint16_t _num, float _epsilon)
  2730. {
  2731. bgfx::VertexDecl& decl = *(bgfx::VertexDecl*)_decl;
  2732. return bgfx::weldVertices(_output, decl, _data, _num, _epsilon);
  2733. }
  2734. BGFX_C_API void bgfx_image_swizzle_bgra8(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst)
  2735. {
  2736. bgfx::imageSwizzleBgra8(_width, _height, _pitch, _src, _dst);
  2737. }
  2738. BGFX_C_API void bgfx_image_rgba8_downsample_2x2(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst)
  2739. {
  2740. bgfx::imageRgba8Downsample2x2(_width, _height, _pitch, _src, _dst);
  2741. }
  2742. BGFX_C_API uint8_t bgfx_get_supported_renderers(bgfx_renderer_type_t _enum[BGFX_RENDERER_TYPE_COUNT])
  2743. {
  2744. return bgfx::getSupportedRenderers( (bgfx::RendererType::Enum*)_enum);
  2745. }
  2746. BGFX_C_API const char* bgfx_get_renderer_name(bgfx_renderer_type_t _type)
  2747. {
  2748. return bgfx::getRendererName(bgfx::RendererType::Enum(_type) );
  2749. }
  2750. BGFX_C_API bool bgfx_init(bgfx_renderer_type_t _type, uint16_t _vendorId, uint16_t _deviceId, bgfx_callback_interface_t* _callback, bgfx_reallocator_interface_t* _allocator)
  2751. {
  2752. static bgfx::CallbackC99 s_callback;
  2753. s_callback.m_interface = _callback;
  2754. static bgfx::AllocatorC99 s_allocator;
  2755. s_allocator.m_interface = _allocator;
  2756. return bgfx::init(bgfx::RendererType::Enum(_type)
  2757. , _vendorId
  2758. , _deviceId
  2759. , NULL == _callback ? NULL : &s_callback
  2760. , NULL == _allocator ? NULL : &s_allocator
  2761. );
  2762. }
  2763. BGFX_C_API void bgfx_shutdown()
  2764. {
  2765. return bgfx::shutdown();
  2766. }
  2767. BGFX_C_API void bgfx_reset(uint32_t _width, uint32_t _height, uint32_t _flags)
  2768. {
  2769. bgfx::reset(_width, _height, _flags);
  2770. }
  2771. BGFX_C_API uint32_t bgfx_frame()
  2772. {
  2773. return bgfx::frame();
  2774. }
  2775. BGFX_C_API bgfx_renderer_type_t bgfx_get_renderer_type()
  2776. {
  2777. return bgfx_renderer_type_t(bgfx::getRendererType() );
  2778. }
  2779. BGFX_C_API const bgfx_caps_t* bgfx_get_caps()
  2780. {
  2781. return (const bgfx_caps_t*)bgfx::getCaps();
  2782. }
  2783. BGFX_C_API const bgfx_hmd_t* bgfx_get_hmd()
  2784. {
  2785. return (const bgfx_hmd_t*)bgfx::getHMD();
  2786. }
  2787. BGFX_C_API const bgfx_stats_t* bgfx_get_stats()
  2788. {
  2789. return (const bgfx_stats_t*)bgfx::getStats();
  2790. }
  2791. BGFX_C_API const bgfx_memory_t* bgfx_alloc(uint32_t _size)
  2792. {
  2793. return (const bgfx_memory_t*)bgfx::alloc(_size);
  2794. }
  2795. BGFX_C_API const bgfx_memory_t* bgfx_copy(const void* _data, uint32_t _size)
  2796. {
  2797. return (const bgfx_memory_t*)bgfx::copy(_data, _size);
  2798. }
  2799. BGFX_C_API const bgfx_memory_t* bgfx_make_ref(const void* _data, uint32_t _size)
  2800. {
  2801. return (const bgfx_memory_t*)bgfx::makeRef(_data, _size);
  2802. }
  2803. BGFX_C_API const bgfx_memory_t* bgfx_make_ref_release(const void* _data, uint32_t _size, bgfx_release_fn_t _releaseFn, void* _userData)
  2804. {
  2805. return (const bgfx_memory_t*)bgfx::makeRef(_data, _size, _releaseFn, _userData);
  2806. }
  2807. BGFX_C_API void bgfx_set_debug(uint32_t _debug)
  2808. {
  2809. bgfx::setDebug(_debug);
  2810. }
  2811. BGFX_C_API void bgfx_dbg_text_clear(uint8_t _attr, bool _small)
  2812. {
  2813. bgfx::dbgTextClear(_attr, _small);
  2814. }
  2815. BGFX_C_API void bgfx_dbg_text_printf(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, ...)
  2816. {
  2817. va_list argList;
  2818. va_start(argList, _format);
  2819. bgfx::dbgTextPrintfVargs(_x, _y, _attr, _format, argList);
  2820. va_end(argList);
  2821. }
  2822. BGFX_C_API void bgfx_dbg_text_image(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const void* _data, uint16_t _pitch)
  2823. {
  2824. bgfx::dbgTextImage(_x, _y, _width, _height, _data, _pitch);
  2825. }
  2826. BGFX_C_API bgfx_index_buffer_handle_t bgfx_create_index_buffer(const bgfx_memory_t* _mem, uint16_t _flags)
  2827. {
  2828. union { bgfx_index_buffer_handle_t c; bgfx::IndexBufferHandle cpp; } handle;
  2829. handle.cpp = bgfx::createIndexBuffer( (const bgfx::Memory*)_mem, _flags);
  2830. return handle.c;
  2831. }
  2832. BGFX_C_API void bgfx_destroy_index_buffer(bgfx_index_buffer_handle_t _handle)
  2833. {
  2834. union { bgfx_index_buffer_handle_t c; bgfx::IndexBufferHandle cpp; } handle = { _handle };
  2835. bgfx::destroyIndexBuffer(handle.cpp);
  2836. }
  2837. BGFX_C_API bgfx_vertex_buffer_handle_t bgfx_create_vertex_buffer(const bgfx_memory_t* _mem, const bgfx_vertex_decl_t* _decl, uint16_t _flags)
  2838. {
  2839. const bgfx::VertexDecl& decl = *(const bgfx::VertexDecl*)_decl;
  2840. union { bgfx_vertex_buffer_handle_t c; bgfx::VertexBufferHandle cpp; } handle;
  2841. handle.cpp = bgfx::createVertexBuffer( (const bgfx::Memory*)_mem, decl, _flags);
  2842. return handle.c;
  2843. }
  2844. BGFX_C_API void bgfx_destroy_vertex_buffer(bgfx_vertex_buffer_handle_t _handle)
  2845. {
  2846. union { bgfx_vertex_buffer_handle_t c; bgfx::VertexBufferHandle cpp; } handle = { _handle };
  2847. bgfx::destroyVertexBuffer(handle.cpp);
  2848. }
  2849. BGFX_C_API bgfx_dynamic_index_buffer_handle_t bgfx_create_dynamic_index_buffer(uint32_t _num, uint16_t _flags)
  2850. {
  2851. union { bgfx_dynamic_index_buffer_handle_t c; bgfx::DynamicIndexBufferHandle cpp; } handle;
  2852. handle.cpp = bgfx::createDynamicIndexBuffer(_num, _flags);
  2853. return handle.c;
  2854. }
  2855. BGFX_C_API bgfx_dynamic_index_buffer_handle_t bgfx_create_dynamic_index_buffer_mem(const bgfx_memory_t* _mem, uint16_t _flags)
  2856. {
  2857. union { bgfx_dynamic_index_buffer_handle_t c; bgfx::DynamicIndexBufferHandle cpp; } handle;
  2858. handle.cpp = bgfx::createDynamicIndexBuffer( (const bgfx::Memory*)_mem, _flags);
  2859. return handle.c;
  2860. }
  2861. BGFX_C_API void bgfx_update_dynamic_index_buffer(bgfx_dynamic_index_buffer_handle_t _handle, uint32_t _startIndex, const bgfx_memory_t* _mem)
  2862. {
  2863. union { bgfx_dynamic_index_buffer_handle_t c; bgfx::DynamicIndexBufferHandle cpp; } handle = { _handle };
  2864. bgfx::updateDynamicIndexBuffer(handle.cpp, _startIndex, (const bgfx::Memory*)_mem);
  2865. }
  2866. BGFX_C_API void bgfx_destroy_dynamic_index_buffer(bgfx_dynamic_index_buffer_handle_t _handle)
  2867. {
  2868. union { bgfx_dynamic_index_buffer_handle_t c; bgfx::DynamicIndexBufferHandle cpp; } handle = { _handle };
  2869. bgfx::destroyDynamicIndexBuffer(handle.cpp);
  2870. }
  2871. BGFX_C_API bgfx_dynamic_vertex_buffer_handle_t bgfx_create_dynamic_vertex_buffer(uint32_t _num, const bgfx_vertex_decl_t* _decl, uint16_t _flags)
  2872. {
  2873. const bgfx::VertexDecl& decl = *(const bgfx::VertexDecl*)_decl;
  2874. union { bgfx_dynamic_vertex_buffer_handle_t c; bgfx::DynamicVertexBufferHandle cpp; } handle;
  2875. handle.cpp = bgfx::createDynamicVertexBuffer(_num, decl, _flags);
  2876. return handle.c;
  2877. }
  2878. BGFX_C_API bgfx_dynamic_vertex_buffer_handle_t bgfx_create_dynamic_vertex_buffer_mem(const bgfx_memory_t* _mem, const bgfx_vertex_decl_t* _decl, uint16_t _flags)
  2879. {
  2880. const bgfx::VertexDecl& decl = *(const bgfx::VertexDecl*)_decl;
  2881. union { bgfx_dynamic_vertex_buffer_handle_t c; bgfx::DynamicVertexBufferHandle cpp; } handle;
  2882. handle.cpp = bgfx::createDynamicVertexBuffer( (const bgfx::Memory*)_mem, decl, _flags);
  2883. return handle.c;
  2884. }
  2885. BGFX_C_API void bgfx_update_dynamic_vertex_buffer(bgfx_dynamic_vertex_buffer_handle_t _handle, uint32_t _startVertex, const bgfx_memory_t* _mem)
  2886. {
  2887. union { bgfx_dynamic_vertex_buffer_handle_t c; bgfx::DynamicVertexBufferHandle cpp; } handle = { _handle };
  2888. bgfx::updateDynamicVertexBuffer(handle.cpp, _startVertex, (const bgfx::Memory*)_mem);
  2889. }
  2890. BGFX_C_API void bgfx_destroy_dynamic_vertex_buffer(bgfx_dynamic_vertex_buffer_handle_t _handle)
  2891. {
  2892. union { bgfx_dynamic_vertex_buffer_handle_t c; bgfx::DynamicVertexBufferHandle cpp; } handle = { _handle };
  2893. bgfx::destroyDynamicVertexBuffer(handle.cpp);
  2894. }
  2895. BGFX_C_API bool bgfx_check_avail_transient_index_buffer(uint32_t _num)
  2896. {
  2897. return bgfx::checkAvailTransientIndexBuffer(_num);
  2898. }
  2899. BGFX_C_API bool bgfx_check_avail_transient_vertex_buffer(uint32_t _num, const bgfx_vertex_decl_t* _decl)
  2900. {
  2901. const bgfx::VertexDecl& decl = *(const bgfx::VertexDecl*)_decl;
  2902. return bgfx::checkAvailTransientVertexBuffer(_num, decl);
  2903. }
  2904. BGFX_C_API bool bgfx_check_avail_instance_data_buffer(uint32_t _num, uint16_t _stride)
  2905. {
  2906. return bgfx::checkAvailInstanceDataBuffer(_num, _stride);
  2907. }
  2908. BGFX_C_API bool bgfx_check_avail_transient_buffers(uint32_t _numVertices, const bgfx_vertex_decl_t* _decl, uint32_t _numIndices)
  2909. {
  2910. const bgfx::VertexDecl& decl = *(const bgfx::VertexDecl*)_decl;
  2911. return bgfx::checkAvailTransientBuffers(_numVertices, decl, _numIndices);
  2912. }
  2913. BGFX_C_API void bgfx_alloc_transient_index_buffer(bgfx_transient_index_buffer_t* _tib, uint32_t _num)
  2914. {
  2915. bgfx::allocTransientIndexBuffer( (bgfx::TransientIndexBuffer*)_tib, _num);
  2916. }
  2917. BGFX_C_API void bgfx_alloc_transient_vertex_buffer(bgfx_transient_vertex_buffer_t* _tvb, uint32_t _num, const bgfx_vertex_decl_t* _decl)
  2918. {
  2919. const bgfx::VertexDecl& decl = *(const bgfx::VertexDecl*)_decl;
  2920. bgfx::allocTransientVertexBuffer( (bgfx::TransientVertexBuffer*)_tvb, _num, decl);
  2921. }
  2922. BGFX_C_API bool bgfx_alloc_transient_buffers(bgfx_transient_vertex_buffer_t* _tvb, const bgfx_vertex_decl_t* _decl, uint32_t _numVertices, bgfx_transient_index_buffer_t* _tib, uint32_t _numIndices)
  2923. {
  2924. const bgfx::VertexDecl& decl = *(const bgfx::VertexDecl*)_decl;
  2925. return bgfx::allocTransientBuffers( (bgfx::TransientVertexBuffer*)_tvb, decl, _numVertices, (bgfx::TransientIndexBuffer*)_tib, _numIndices);
  2926. }
  2927. BGFX_C_API const bgfx_instance_data_buffer_t* bgfx_alloc_instance_data_buffer(uint32_t _num, uint16_t _stride)
  2928. {
  2929. return (bgfx_instance_data_buffer_t*)bgfx::allocInstanceDataBuffer(_num, _stride);
  2930. }
  2931. BGFX_C_API bgfx_indirect_buffer_handle_t bgfx_create_indirect_buffer(uint32_t _num)
  2932. {
  2933. union { bgfx_indirect_buffer_handle_t c; bgfx::IndirectBufferHandle cpp; } handle;
  2934. handle.cpp = bgfx::createIndirectBuffer(_num);
  2935. return handle.c;
  2936. }
  2937. BGFX_C_API void bgfx_destroy_indirect_buffer(bgfx_indirect_buffer_handle_t _handle)
  2938. {
  2939. union { bgfx_indirect_buffer_handle_t c; bgfx::IndirectBufferHandle cpp; } handle = { _handle };
  2940. bgfx::destroyIndirectBuffer(handle.cpp);
  2941. }
  2942. BGFX_C_API bgfx_shader_handle_t bgfx_create_shader(const bgfx_memory_t* _mem)
  2943. {
  2944. union { bgfx_shader_handle_t c; bgfx::ShaderHandle cpp; } handle;
  2945. handle.cpp = bgfx::createShader( (const bgfx::Memory*)_mem);
  2946. return handle.c;
  2947. }
  2948. BGFX_C_API uint16_t bgfx_get_shader_uniforms(bgfx_shader_handle_t _handle, bgfx_uniform_handle_t* _uniforms, uint16_t _max)
  2949. {
  2950. union { bgfx_shader_handle_t c; bgfx::ShaderHandle cpp; } handle = { _handle };
  2951. return bgfx::getShaderUniforms(handle.cpp, (bgfx::UniformHandle*)_uniforms, _max);
  2952. }
  2953. BGFX_C_API void bgfx_destroy_shader(bgfx_shader_handle_t _handle)
  2954. {
  2955. union { bgfx_shader_handle_t c; bgfx::ShaderHandle cpp; } handle = { _handle };
  2956. bgfx::destroyShader(handle.cpp);
  2957. }
  2958. BGFX_C_API bgfx_program_handle_t bgfx_create_program(bgfx_shader_handle_t _vsh, bgfx_shader_handle_t _fsh, bool _destroyShaders)
  2959. {
  2960. union { bgfx_shader_handle_t c; bgfx::ShaderHandle cpp; } vsh = { _vsh };
  2961. union { bgfx_shader_handle_t c; bgfx::ShaderHandle cpp; } fsh = { _fsh };
  2962. union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } handle;
  2963. handle.cpp = bgfx::createProgram(vsh.cpp, fsh.cpp, _destroyShaders);
  2964. return handle.c;
  2965. }
  2966. BGFX_C_API bgfx_program_handle_t bgfx_create_compute_program(bgfx_shader_handle_t _csh, bool _destroyShaders)
  2967. {
  2968. union { bgfx_shader_handle_t c; bgfx::ShaderHandle cpp; } csh = { _csh };
  2969. union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } handle;
  2970. handle.cpp = bgfx::createProgram(csh.cpp, _destroyShaders);
  2971. return handle.c;
  2972. }
  2973. BGFX_C_API void bgfx_destroy_program(bgfx_program_handle_t _handle)
  2974. {
  2975. union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } handle = { _handle };
  2976. bgfx::destroyProgram(handle.cpp);
  2977. }
  2978. BGFX_C_API void bgfx_calc_texture_size(bgfx_texture_info_t* _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, uint8_t _numMips, bgfx_texture_format_t _format)
  2979. {
  2980. bgfx::TextureInfo& info = *(bgfx::TextureInfo*)_info;
  2981. bgfx::calcTextureSize(info, _width, _height, _depth, _cubeMap, _numMips, bgfx::TextureFormat::Enum(_format) );
  2982. }
  2983. BGFX_C_API bgfx_texture_handle_t bgfx_create_texture(const bgfx_memory_t* _mem, uint32_t _flags, uint8_t _skip, bgfx_texture_info_t* _info)
  2984. {
  2985. union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle;
  2986. bgfx::TextureInfo* info = (bgfx::TextureInfo*)_info;
  2987. handle.cpp = bgfx::createTexture( (const bgfx::Memory*)_mem, _flags, _skip, info);
  2988. return handle.c;
  2989. }
  2990. BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_2d(uint16_t _width, uint16_t _height, uint8_t _numMips, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem)
  2991. {
  2992. union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle;
  2993. handle.cpp = bgfx::createTexture2D(_width, _height, _numMips, bgfx::TextureFormat::Enum(_format), _flags, (const bgfx::Memory*)_mem);
  2994. return handle.c;
  2995. }
  2996. BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_2d_scaled(bgfx_backbuffer_ratio_t _ratio, uint8_t _numMips, bgfx_texture_format_t _format, uint32_t _flags)
  2997. {
  2998. union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle;
  2999. handle.cpp = bgfx::createTexture2D(bgfx::BackbufferRatio::Enum(_ratio), _numMips, bgfx::TextureFormat::Enum(_format), _flags);
  3000. return handle.c;
  3001. }
  3002. BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_3d(uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem)
  3003. {
  3004. union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle;
  3005. handle.cpp = bgfx::createTexture3D(_width, _height, _depth, _numMips, bgfx::TextureFormat::Enum(_format), _flags, (const bgfx::Memory*)_mem);
  3006. return handle.c;
  3007. }
  3008. BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_cube(uint16_t _size, uint8_t _numMips, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem)
  3009. {
  3010. union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle;
  3011. handle.cpp = bgfx::createTextureCube(_size, _numMips, bgfx::TextureFormat::Enum(_format), _flags, (const bgfx::Memory*)_mem);
  3012. return handle.c;
  3013. }
  3014. BGFX_C_API void bgfx_update_texture_2d(bgfx_texture_handle_t _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch)
  3015. {
  3016. union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle };
  3017. bgfx::updateTexture2D(handle.cpp, _mip, _x, _y, _width, _height, (const bgfx::Memory*)_mem, _pitch);
  3018. }
  3019. BGFX_C_API void bgfx_update_texture_3d(bgfx_texture_handle_t _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _z, uint16_t _width, uint16_t _height, uint16_t _depth, const bgfx_memory_t* _mem)
  3020. {
  3021. union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle };
  3022. bgfx::updateTexture3D(handle.cpp, _mip, _x, _y, _z, _width, _height, _depth, (const bgfx::Memory*)_mem);
  3023. }
  3024. BGFX_C_API void bgfx_update_texture_cube(bgfx_texture_handle_t _handle, uint8_t _side, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch)
  3025. {
  3026. union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle };
  3027. bgfx::updateTextureCube(handle.cpp, _side, _mip, _x, _y, _width, _height, (const bgfx::Memory*)_mem, _pitch);
  3028. }
  3029. BGFX_C_API void bgfx_destroy_texture(bgfx_texture_handle_t _handle)
  3030. {
  3031. union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle };
  3032. bgfx::destroyTexture(handle.cpp);
  3033. }
  3034. BGFX_C_API bgfx_frame_buffer_handle_t bgfx_create_frame_buffer(uint16_t _width, uint16_t _height, bgfx_texture_format_t _format, uint32_t _textureFlags)
  3035. {
  3036. union { bgfx_frame_buffer_handle_t c; bgfx::FrameBufferHandle cpp; } handle;
  3037. handle.cpp = bgfx::createFrameBuffer(_width, _height, bgfx::TextureFormat::Enum(_format), _textureFlags);
  3038. return handle.c;
  3039. }
  3040. BGFX_C_API bgfx_frame_buffer_handle_t bgfx_create_frame_buffer_scaled(bgfx_backbuffer_ratio_t _ratio, bgfx_texture_format_t _format, uint32_t _textureFlags)
  3041. {
  3042. union { bgfx_frame_buffer_handle_t c; bgfx::FrameBufferHandle cpp; } handle;
  3043. handle.cpp = bgfx::createFrameBuffer(bgfx::BackbufferRatio::Enum(_ratio), bgfx::TextureFormat::Enum(_format), _textureFlags);
  3044. return handle.c;
  3045. }
  3046. BGFX_C_API bgfx_frame_buffer_handle_t bgfx_create_frame_buffer_from_handles(uint8_t _num, bgfx_texture_handle_t* _handles, bool _destroyTextures)
  3047. {
  3048. union { bgfx_frame_buffer_handle_t c; bgfx::FrameBufferHandle cpp; } handle;
  3049. handle.cpp = bgfx::createFrameBuffer(_num, (bgfx::TextureHandle*)_handles, _destroyTextures);
  3050. return handle.c;
  3051. }
  3052. BGFX_C_API bgfx_frame_buffer_handle_t bgfx_create_frame_buffer_from_nwh(void* _nwh, uint16_t _width, uint16_t _height, bgfx_texture_format_t _depthFormat)
  3053. {
  3054. union { bgfx_frame_buffer_handle_t c; bgfx::FrameBufferHandle cpp; } handle;
  3055. handle.cpp = bgfx::createFrameBuffer(_nwh, _width, _height, bgfx::TextureFormat::Enum(_depthFormat) );
  3056. return handle.c;
  3057. }
  3058. BGFX_C_API void bgfx_destroy_frame_buffer(bgfx_frame_buffer_handle_t _handle)
  3059. {
  3060. union { bgfx_frame_buffer_handle_t c; bgfx::FrameBufferHandle cpp; } handle = { _handle };
  3061. bgfx::destroyFrameBuffer(handle.cpp);
  3062. }
  3063. BGFX_C_API bgfx_uniform_handle_t bgfx_create_uniform(const char* _name, bgfx_uniform_type_t _type, uint16_t _num)
  3064. {
  3065. union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } handle;
  3066. handle.cpp = bgfx::createUniform(_name, bgfx::UniformType::Enum(_type), _num);
  3067. return handle.c;
  3068. }
  3069. BGFX_C_API void bgfx_destroy_uniform(bgfx_uniform_handle_t _handle)
  3070. {
  3071. union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } handle = { _handle };
  3072. bgfx::destroyUniform(handle.cpp);
  3073. }
  3074. BGFX_C_API void bgfx_set_clear_color(uint8_t _index, const float _rgba[4])
  3075. {
  3076. bgfx::setClearColor(_index, _rgba);
  3077. }
  3078. BGFX_C_API void bgfx_set_view_name(uint8_t _id, const char* _name)
  3079. {
  3080. bgfx::setViewName(_id, _name);
  3081. }
  3082. BGFX_C_API void bgfx_set_view_rect(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  3083. {
  3084. bgfx::setViewRect(_id, _x, _y, _width, _height);
  3085. }
  3086. BGFX_C_API void bgfx_set_view_scissor(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  3087. {
  3088. bgfx::setViewScissor(_id, _x, _y, _width, _height);
  3089. }
  3090. BGFX_C_API void bgfx_set_view_clear(uint8_t _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
  3091. {
  3092. bgfx::setViewClear(_id, _flags, _rgba, _depth, _stencil);
  3093. }
  3094. BGFX_C_API void bgfx_set_view_clear_mrt(uint8_t _id, uint16_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7)
  3095. {
  3096. bgfx::setViewClear(_id, _flags, _depth, _stencil, _0, _1, _2, _3, _4, _5, _6, _7);
  3097. }
  3098. BGFX_C_API void bgfx_set_view_seq(uint8_t _id, bool _enabled)
  3099. {
  3100. bgfx::setViewSeq(_id, _enabled);
  3101. }
  3102. BGFX_C_API void bgfx_set_view_frame_buffer(uint8_t _id, bgfx_frame_buffer_handle_t _handle)
  3103. {
  3104. union { bgfx_frame_buffer_handle_t c; bgfx::FrameBufferHandle cpp; } handle = { _handle };
  3105. bgfx::setViewFrameBuffer(_id, handle.cpp);
  3106. }
  3107. BGFX_C_API void bgfx_set_view_transform(uint8_t _id, const void* _view, const void* _proj)
  3108. {
  3109. bgfx::setViewTransform(_id, _view, _proj);
  3110. }
  3111. BGFX_C_API void bgfx_set_view_transform_stereo(uint8_t _id, const void* _view, const void* _projL, uint8_t _flags, const void* _projR)
  3112. {
  3113. bgfx::setViewTransform(_id, _view, _projL, _flags, _projR);
  3114. }
  3115. BGFX_C_API void bgfx_set_view_remap(uint8_t _id, uint8_t _num, const void* _remap)
  3116. {
  3117. bgfx::setViewRemap(_id, _num, _remap);
  3118. }
  3119. BGFX_C_API void bgfx_set_marker(const char* _marker)
  3120. {
  3121. bgfx::setMarker(_marker);
  3122. }
  3123. BGFX_C_API void bgfx_set_state(uint64_t _state, uint32_t _rgba)
  3124. {
  3125. bgfx::setState(_state, _rgba);
  3126. }
  3127. BGFX_C_API void bgfx_set_stencil(uint32_t _fstencil, uint32_t _bstencil)
  3128. {
  3129. bgfx::setStencil(_fstencil, _bstencil);
  3130. }
  3131. BGFX_C_API uint16_t bgfx_set_scissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  3132. {
  3133. return bgfx::setScissor(_x, _y, _width, _height);
  3134. }
  3135. BGFX_C_API void bgfx_set_scissor_cached(uint16_t _cache)
  3136. {
  3137. bgfx::setScissor(_cache);
  3138. }
  3139. BGFX_C_API uint32_t bgfx_set_transform(const void* _mtx, uint16_t _num)
  3140. {
  3141. return bgfx::setTransform(_mtx, _num);
  3142. }
  3143. BGFX_C_API uint32_t bgfx_alloc_transform(bgfx_transform_t* _transform, uint16_t _num)
  3144. {
  3145. return bgfx::allocTransform( (bgfx::Transform*)_transform, _num);
  3146. }
  3147. BGFX_C_API void bgfx_set_transform_cached(uint32_t _cache, uint16_t _num)
  3148. {
  3149. bgfx::setTransform(_cache, _num);
  3150. }
  3151. BGFX_C_API void bgfx_set_uniform(bgfx_uniform_handle_t _handle, const void* _value, uint16_t _num)
  3152. {
  3153. union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } handle = { _handle };
  3154. bgfx::setUniform(handle.cpp, _value, _num);
  3155. }
  3156. BGFX_C_API void bgfx_set_index_buffer(bgfx_index_buffer_handle_t _handle, uint32_t _firstIndex, uint32_t _numIndices)
  3157. {
  3158. union { bgfx_index_buffer_handle_t c; bgfx::IndexBufferHandle cpp; } handle = { _handle };
  3159. bgfx::setIndexBuffer(handle.cpp, _firstIndex, _numIndices);
  3160. }
  3161. BGFX_C_API void bgfx_set_dynamic_index_buffer(bgfx_dynamic_index_buffer_handle_t _handle, uint32_t _firstIndex, uint32_t _numIndices)
  3162. {
  3163. union { bgfx_dynamic_index_buffer_handle_t c; bgfx::DynamicIndexBufferHandle cpp; } handle = { _handle };
  3164. bgfx::setIndexBuffer(handle.cpp, _firstIndex, _numIndices);
  3165. }
  3166. BGFX_C_API void bgfx_set_transient_index_buffer(const bgfx_transient_index_buffer_t* _tib, uint32_t _firstIndex, uint32_t _numIndices)
  3167. {
  3168. bgfx::setIndexBuffer( (const bgfx::TransientIndexBuffer*)_tib, _firstIndex, _numIndices);
  3169. }
  3170. BGFX_C_API void bgfx_set_vertex_buffer(bgfx_vertex_buffer_handle_t _handle, uint32_t _startVertex, uint32_t _numVertices)
  3171. {
  3172. union { bgfx_vertex_buffer_handle_t c; bgfx::VertexBufferHandle cpp; } handle = { _handle };
  3173. bgfx::setVertexBuffer(handle.cpp, _startVertex, _numVertices);
  3174. }
  3175. BGFX_C_API void bgfx_set_dynamic_vertex_buffer(bgfx_dynamic_vertex_buffer_handle_t _handle, uint32_t _numVertices)
  3176. {
  3177. union { bgfx_dynamic_vertex_buffer_handle_t c; bgfx::DynamicVertexBufferHandle cpp; } handle = { _handle };
  3178. bgfx::setVertexBuffer(handle.cpp, _numVertices);
  3179. }
  3180. BGFX_C_API void bgfx_set_transient_vertex_buffer(const bgfx_transient_vertex_buffer_t* _tvb, uint32_t _startVertex, uint32_t _numVertices)
  3181. {
  3182. bgfx::setVertexBuffer( (const bgfx::TransientVertexBuffer*)_tvb, _startVertex, _numVertices);
  3183. }
  3184. BGFX_C_API void bgfx_set_instance_data_buffer(const bgfx_instance_data_buffer_t* _idb, uint32_t _num)
  3185. {
  3186. bgfx::setInstanceDataBuffer( (const bgfx::InstanceDataBuffer*)_idb, _num);
  3187. }
  3188. BGFX_C_API void bgfx_set_instance_data_from_vertex_buffer(bgfx_vertex_buffer_handle_t _handle, uint32_t _startVertex, uint32_t _num)
  3189. {
  3190. union { bgfx_vertex_buffer_handle_t c; bgfx::VertexBufferHandle cpp; } handle = { _handle };
  3191. bgfx::setInstanceDataBuffer(handle.cpp, _startVertex, _num);
  3192. }
  3193. BGFX_C_API void bgfx_set_instance_data_from_dynamic_vertex_buffer(bgfx_dynamic_vertex_buffer_handle_t _handle, uint32_t _startVertex, uint32_t _num)
  3194. {
  3195. union { bgfx_dynamic_vertex_buffer_handle_t c; bgfx::DynamicVertexBufferHandle cpp; } handle = { _handle };
  3196. bgfx::setInstanceDataBuffer(handle.cpp, _startVertex, _num);
  3197. }
  3198. BGFX_C_API void bgfx_set_texture(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint32_t _flags)
  3199. {
  3200. union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } sampler = { _sampler };
  3201. union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle };
  3202. bgfx::setTexture(_stage, sampler.cpp, handle.cpp, _flags);
  3203. }
  3204. BGFX_C_API void bgfx_set_texture_from_frame_buffer(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_frame_buffer_handle_t _handle, uint8_t _attachment, uint32_t _flags)
  3205. {
  3206. union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } sampler = { _sampler };
  3207. union { bgfx_frame_buffer_handle_t c; bgfx::FrameBufferHandle cpp; } handle = { _handle };
  3208. bgfx::setTexture(_stage, sampler.cpp, handle.cpp, _attachment, _flags);
  3209. }
  3210. BGFX_C_API uint32_t bgfx_touch(uint8_t _id)
  3211. {
  3212. return bgfx::touch(_id);
  3213. }
  3214. BGFX_C_API uint32_t bgfx_submit(uint8_t _id, bgfx_program_handle_t _handle, int32_t _depth)
  3215. {
  3216. union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } handle = { _handle };
  3217. return bgfx::submit(_id, handle.cpp, _depth);
  3218. }
  3219. BGFX_C_API uint32_t bgfx_submit_indirect(uint8_t _id, bgfx_program_handle_t _handle, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, int32_t _depth)
  3220. {
  3221. union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } handle = { _handle };
  3222. union { bgfx_indirect_buffer_handle_t c; bgfx::IndirectBufferHandle cpp; } indirectHandle = { _indirectHandle };
  3223. return bgfx::submit(_id, handle.cpp, indirectHandle.cpp, _start, _num, _depth);
  3224. }
  3225. BGFX_C_API void bgfx_set_image(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format)
  3226. {
  3227. union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } sampler = { _sampler };
  3228. union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle = { _handle };
  3229. bgfx::setImage(_stage, sampler.cpp, handle.cpp, _mip, bgfx::Access::Enum(_access), bgfx::TextureFormat::Enum(_format) );
  3230. }
  3231. BGFX_C_API void bgfx_set_image_from_frame_buffer(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_frame_buffer_handle_t _handle, uint8_t _attachment, bgfx_access_t _access, bgfx_texture_format_t _format)
  3232. {
  3233. union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } sampler = { _sampler };
  3234. union { bgfx_frame_buffer_handle_t c; bgfx::FrameBufferHandle cpp; } handle = { _handle };
  3235. bgfx::setImage(_stage, sampler.cpp, handle.cpp, _attachment, bgfx::Access::Enum(_access), bgfx::TextureFormat::Enum(_format) );
  3236. }
  3237. BGFX_C_API void bgfx_set_compute_index_buffer(uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access)
  3238. {
  3239. union { bgfx_index_buffer_handle_t c; bgfx::IndexBufferHandle cpp; } handle = { _handle };
  3240. bgfx::setBuffer(_stage, handle.cpp, bgfx::Access::Enum(_access) );
  3241. }
  3242. BGFX_C_API void bgfx_set_compute_vertex_buffer(uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access)
  3243. {
  3244. union { bgfx_vertex_buffer_handle_t c; bgfx::VertexBufferHandle cpp; } handle = { _handle };
  3245. bgfx::setBuffer(_stage, handle.cpp, bgfx::Access::Enum(_access) );
  3246. }
  3247. BGFX_C_API void bgfx_set_compute_dynamic_index_buffer(uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access)
  3248. {
  3249. union { bgfx_dynamic_index_buffer_handle_t c; bgfx::DynamicIndexBufferHandle cpp; } handle = { _handle };
  3250. bgfx::setBuffer(_stage, handle.cpp, bgfx::Access::Enum(_access) );
  3251. }
  3252. BGFX_C_API void bgfx_set_compute_dynamic_vertex_buffer(uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access)
  3253. {
  3254. union { bgfx_dynamic_vertex_buffer_handle_t c; bgfx::DynamicVertexBufferHandle cpp; } handle = { _handle };
  3255. bgfx::setBuffer(_stage, handle.cpp, bgfx::Access::Enum(_access) );
  3256. }
  3257. BGFX_C_API void bgfx_set_compute_indirect_buffer(uint8_t _stage, bgfx_indirect_buffer_handle_t _handle, bgfx_access_t _access)
  3258. {
  3259. union { bgfx_indirect_buffer_handle_t c; bgfx::IndirectBufferHandle cpp; } handle = { _handle };
  3260. bgfx::setBuffer(_stage, handle.cpp, bgfx::Access::Enum(_access) );
  3261. }
  3262. BGFX_C_API uint32_t bgfx_dispatch(uint8_t _id, bgfx_program_handle_t _handle, uint16_t _numX, uint16_t _numY, uint16_t _numZ, uint8_t _flags)
  3263. {
  3264. union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } handle = { _handle };
  3265. return bgfx::dispatch(_id, handle.cpp, _numX, _numY, _numZ, _flags);
  3266. }
  3267. BGFX_C_API uint32_t bgfx_dispatch_indirect(uint8_t _id, bgfx_program_handle_t _handle, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags)
  3268. {
  3269. union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } handle = { _handle };
  3270. union { bgfx_indirect_buffer_handle_t c; bgfx::IndirectBufferHandle cpp; } indirectHandle = { _indirectHandle };
  3271. return bgfx::dispatch(_id, handle.cpp, indirectHandle.cpp, _start, _num, _flags);
  3272. }
  3273. BGFX_C_API void bgfx_discard()
  3274. {
  3275. bgfx::discard();
  3276. }
  3277. BGFX_C_API void bgfx_save_screen_shot(const char* _filePath)
  3278. {
  3279. bgfx::saveScreenShot(_filePath);
  3280. }
  3281. BGFX_C_API bgfx_render_frame_t bgfx_render_frame()
  3282. {
  3283. return bgfx_render_frame_t(bgfx::renderFrame() );
  3284. }
  3285. BGFX_C_API void bgfx_set_platform_data(bgfx_platform_data_t* _pd)
  3286. {
  3287. bgfx::setPlatformData(*(bgfx::PlatformData*)_pd);
  3288. }