bgfx.cpp 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602
  1. /*
  2. * Copyright 2011-2014 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 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 BX_PLATFORM_ANDROID
  19. ::ANativeWindow* g_bgfxAndroidWindow = NULL;
  20. void androidSetWindow(::ANativeWindow* _window)
  21. {
  22. g_bgfxAndroidWindow = _window;
  23. }
  24. #elif BX_PLATFORM_IOS
  25. void* g_bgfxEaglLayer = NULL;
  26. void iosSetEaglLayer(void* _layer)
  27. {
  28. g_bgfxEaglLayer = _layer;
  29. }
  30. #elif BX_PLATFORM_OSX
  31. void* g_bgfxNSWindow = NULL;
  32. void osxSetNSWindow(void* _window)
  33. {
  34. g_bgfxNSWindow = _window;
  35. }
  36. #elif BX_PLATFORM_WINDOWS
  37. ::HWND g_bgfxHwnd = NULL;
  38. void winSetHwnd(::HWND _window)
  39. {
  40. g_bgfxHwnd = _window;
  41. }
  42. #endif // BX_PLATFORM_*
  43. #if BGFX_CONFIG_USE_TINYSTL
  44. void* TinyStlAllocator::static_allocate(size_t _bytes)
  45. {
  46. return BX_ALLOC(g_allocator, _bytes);
  47. }
  48. void TinyStlAllocator::static_deallocate(void* _ptr, size_t /*_bytes*/)
  49. {
  50. if (NULL != _ptr)
  51. {
  52. BX_FREE(g_allocator, _ptr);
  53. }
  54. }
  55. #endif // BGFX_CONFIG_USE_TINYSTL
  56. struct CallbackStub : public CallbackI
  57. {
  58. virtual ~CallbackStub()
  59. {
  60. }
  61. virtual void fatal(Fatal::Enum _code, const char* _str) BX_OVERRIDE
  62. {
  63. if (Fatal::DebugCheck == _code)
  64. {
  65. bx::debugBreak();
  66. }
  67. else
  68. {
  69. BX_TRACE("0x%08x: %s", _code, _str);
  70. BX_UNUSED(_code, _str);
  71. abort();
  72. }
  73. }
  74. virtual uint32_t cacheReadSize(uint64_t /*_id*/) BX_OVERRIDE
  75. {
  76. return 0;
  77. }
  78. virtual bool cacheRead(uint64_t /*_id*/, void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
  79. {
  80. return false;
  81. }
  82. virtual void cacheWrite(uint64_t /*_id*/, const void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
  83. {
  84. }
  85. 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
  86. {
  87. BX_UNUSED(_filePath, _width, _height, _pitch, _data, _size, _yflip);
  88. #if BX_CONFIG_CRT_FILE_READER_WRITER
  89. char* filePath = (char*)alloca(strlen(_filePath)+5);
  90. strcpy(filePath, _filePath);
  91. strcat(filePath, ".tga");
  92. bx::CrtFileWriter writer;
  93. if (0 == writer.open(filePath) )
  94. {
  95. imageWriteTga(&writer, _width, _height, _pitch, _data, false, _yflip);
  96. writer.close();
  97. }
  98. #endif // BX_CONFIG_CRT_FILE_READER_WRITER
  99. }
  100. virtual void captureBegin(uint32_t /*_width*/, uint32_t /*_height*/, uint32_t /*_pitch*/, TextureFormat::Enum /*_format*/, bool /*_yflip*/) BX_OVERRIDE
  101. {
  102. BX_TRACE("Warning: using capture without callback (a.k.a. pointless).");
  103. }
  104. virtual void captureEnd() BX_OVERRIDE
  105. {
  106. }
  107. virtual void captureFrame(const void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
  108. {
  109. }
  110. };
  111. #ifndef BGFX_CONFIG_MEMORY_TRACKING
  112. # define BGFX_CONFIG_MEMORY_TRACKING (BGFX_CONFIG_DEBUG && BX_CONFIG_SUPPORTED_THREADING)
  113. #endif // BGFX_CONFIG_MEMORY_TRACKING
  114. class AllocatorStub : public bx::ReallocatorI
  115. {
  116. public:
  117. AllocatorStub()
  118. #if BGFX_CONFIG_MEMORY_TRACKING
  119. : m_numBlocks(0)
  120. , m_maxBlocks(0)
  121. #endif // BGFX_CONFIG_MEMORY_TRACKING
  122. {
  123. }
  124. virtual void* alloc(size_t _size, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE
  125. {
  126. if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
  127. {
  128. #if BGFX_CONFIG_MEMORY_TRACKING
  129. {
  130. bx::LwMutexScope scope(m_mutex);
  131. ++m_numBlocks;
  132. m_maxBlocks = bx::uint32_max(m_maxBlocks, m_numBlocks);
  133. }
  134. #endif // BGFX_CONFIG_MEMORY_TRACKING
  135. return ::malloc(_size);
  136. }
  137. return bx::alignedAlloc(this, _size, _align, _file, _line);
  138. }
  139. virtual void free(void* _ptr, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE
  140. {
  141. if (NULL != _ptr)
  142. {
  143. if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
  144. {
  145. #if BGFX_CONFIG_MEMORY_TRACKING
  146. {
  147. bx::LwMutexScope scope(m_mutex);
  148. BX_CHECK(m_numBlocks > 0, "Number of blocks is 0. Possible alloc/free mismatch?");
  149. --m_numBlocks;
  150. }
  151. #endif // BGFX_CONFIG_MEMORY_TRACKING
  152. ::free(_ptr);
  153. }
  154. else
  155. {
  156. bx::alignedFree(this, _ptr, _align, _file, _line);
  157. }
  158. }
  159. }
  160. virtual void* realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) BX_OVERRIDE
  161. {
  162. if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align)
  163. {
  164. #if BGFX_CONFIG_MEMORY_TRACKING
  165. if (NULL == _ptr)
  166. {
  167. bx::LwMutexScope scope(m_mutex);
  168. ++m_numBlocks;
  169. m_maxBlocks = bx::uint32_max(m_maxBlocks, m_numBlocks);
  170. }
  171. #endif // BGFX_CONFIG_MEMORY_TRACKING
  172. return ::realloc(_ptr, _size);
  173. }
  174. return bx::alignedRealloc(this, _ptr, _size, _align, _file, _line);
  175. }
  176. void checkLeaks()
  177. {
  178. #if BGFX_CONFIG_MEMORY_TRACKING
  179. BX_WARN(0 == m_numBlocks, "MEMORY LEAK: %d (max: %d)", m_numBlocks, m_maxBlocks);
  180. #endif // BGFX_CONFIG_MEMORY_TRACKING
  181. }
  182. protected:
  183. #if BGFX_CONFIG_MEMORY_TRACKING
  184. bx::LwMutex m_mutex;
  185. uint32_t m_numBlocks;
  186. uint32_t m_maxBlocks;
  187. #endif // BGFX_CONFIG_MEMORY_TRACKING
  188. };
  189. static CallbackStub* s_callbackStub = NULL;
  190. static AllocatorStub* s_allocatorStub = NULL;
  191. static bool s_graphicsDebuggerPresent = false;
  192. CallbackI* g_callback = NULL;
  193. bx::ReallocatorI* g_allocator = NULL;
  194. Caps g_caps;
  195. static BX_THREAD uint32_t s_threadIndex = 0;
  196. static Context* s_ctx = NULL;
  197. static bool s_renderFrameCalled = false;
  198. void setGraphicsDebuggerPresent(bool _present)
  199. {
  200. BX_TRACE("Graphics debugger is %spresent.", _present ? "" : "not ");
  201. s_graphicsDebuggerPresent = _present;
  202. }
  203. bool isGraphicsDebuggerPresent()
  204. {
  205. return s_graphicsDebuggerPresent;
  206. }
  207. void fatal(Fatal::Enum _code, const char* _format, ...)
  208. {
  209. char temp[8192];
  210. va_list argList;
  211. va_start(argList, _format);
  212. bx::vsnprintf(temp, sizeof(temp), _format, argList);
  213. va_end(argList);
  214. temp[sizeof(temp)-1] = '\0';
  215. g_callback->fatal(_code, temp);
  216. }
  217. void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far)
  218. {
  219. const float aa = 2.0f/(_right - _left);
  220. const float bb = 2.0f/(_top - _bottom);
  221. const float cc = 1.0f/(_far - _near);
  222. const float dd = (_left + _right)/(_left - _right);
  223. const float ee = (_top + _bottom)/(_bottom - _top);
  224. const float ff = _near / (_near - _far);
  225. memset(_result, 0, sizeof(float)*16);
  226. _result[0] = aa;
  227. _result[5] = bb;
  228. _result[10] = cc;
  229. _result[12] = dd;
  230. _result[13] = ee;
  231. _result[14] = ff;
  232. _result[15] = 1.0f;
  233. }
  234. #include "charset.h"
  235. void charsetFillTexture(const uint8_t* _charset, uint8_t* _rgba, uint32_t _height, uint32_t _pitch, uint32_t _bpp)
  236. {
  237. for (uint32_t ii = 0; ii < 256; ++ii)
  238. {
  239. uint8_t* pix = &_rgba[ii*8*_bpp];
  240. for (uint32_t yy = 0; yy < _height; ++yy)
  241. {
  242. for (uint32_t xx = 0; xx < 8; ++xx)
  243. {
  244. uint8_t bit = 1<<(7-xx);
  245. memset(&pix[xx*_bpp], _charset[ii*_height+yy]&bit ? 255 : 0, _bpp);
  246. }
  247. pix += _pitch;
  248. }
  249. }
  250. }
  251. static const uint32_t numCharsPerBatch = 1024;
  252. static const uint32_t numBatchVertices = numCharsPerBatch*4;
  253. static const uint32_t numBatchIndices = numCharsPerBatch*6;
  254. void TextVideoMemBlitter::init()
  255. {
  256. BGFX_CHECK_MAIN_THREAD();
  257. m_decl
  258. .begin()
  259. .add(Attrib::Position, 3, AttribType::Float)
  260. .add(Attrib::Color0, 4, AttribType::Uint8, true)
  261. .add(Attrib::Color1, 4, AttribType::Uint8, true)
  262. .add(Attrib::TexCoord0, 2, AttribType::Float)
  263. .end();
  264. uint16_t width = 2048;
  265. uint16_t height = 24;
  266. uint8_t bpp = 1;
  267. uint32_t pitch = width*bpp;
  268. const Memory* mem;
  269. mem = alloc(pitch*height);
  270. uint8_t* rgba = mem->data;
  271. charsetFillTexture(vga8x8, rgba, 8, pitch, bpp);
  272. charsetFillTexture(vga8x16, &rgba[8*pitch], 16, pitch, bpp);
  273. m_texture = createTexture2D(width, height, 1, TextureFormat::R8
  274. , BGFX_TEXTURE_MIN_POINT
  275. | BGFX_TEXTURE_MAG_POINT
  276. | BGFX_TEXTURE_MIP_POINT
  277. | BGFX_TEXTURE_U_CLAMP
  278. | BGFX_TEXTURE_V_CLAMP
  279. , mem
  280. );
  281. switch (g_caps.rendererType)
  282. {
  283. case RendererType::Direct3D9:
  284. mem = makeRef(vs_debugfont_dx9, sizeof(vs_debugfont_dx9) );
  285. break;
  286. case RendererType::Direct3D11:
  287. mem = makeRef(vs_debugfont_dx11, sizeof(vs_debugfont_dx11) );
  288. break;
  289. default:
  290. mem = makeRef(vs_debugfont_glsl, sizeof(vs_debugfont_glsl) );
  291. break;
  292. }
  293. ShaderHandle vsh = createShader(mem);
  294. switch (g_caps.rendererType)
  295. {
  296. case RendererType::Direct3D9:
  297. mem = makeRef(fs_debugfont_dx9, sizeof(fs_debugfont_dx9) );
  298. break;
  299. case RendererType::Direct3D11:
  300. mem = makeRef(fs_debugfont_dx11, sizeof(fs_debugfont_dx11) );
  301. break;
  302. default:
  303. mem = makeRef(fs_debugfont_glsl, sizeof(fs_debugfont_glsl) );
  304. break;
  305. }
  306. ShaderHandle fsh = createShader(mem);
  307. m_program = createProgram(vsh, fsh, true);
  308. m_vb = s_ctx->createTransientVertexBuffer(numBatchVertices*m_decl.m_stride, &m_decl);
  309. m_ib = s_ctx->createTransientIndexBuffer(numBatchIndices*2);
  310. }
  311. void TextVideoMemBlitter::shutdown()
  312. {
  313. BGFX_CHECK_MAIN_THREAD();
  314. destroyProgram(m_program);
  315. destroyTexture(m_texture);
  316. s_ctx->destroyTransientVertexBuffer(m_vb);
  317. s_ctx->destroyTransientIndexBuffer(m_ib);
  318. }
  319. void blit(RendererContextI* _renderCtx, TextVideoMemBlitter& _blitter, const TextVideoMem& _mem)
  320. {
  321. BGFX_CHECK_RENDER_THREAD();
  322. struct Vertex
  323. {
  324. float m_x;
  325. float m_y;
  326. float m_z;
  327. uint32_t m_fg;
  328. uint32_t m_bg;
  329. float m_u;
  330. float m_v;
  331. };
  332. static uint32_t palette[16] =
  333. {
  334. 0x0,
  335. 0xff0000cc,
  336. 0xff069a4e,
  337. 0xff00a0c4,
  338. 0xffa46534,
  339. 0xff7b5075,
  340. 0xff9a9806,
  341. 0xffcfd7d3,
  342. 0xff535755,
  343. 0xff2929ef,
  344. 0xff34e28a,
  345. 0xff4fe9fc,
  346. 0xffcf9f72,
  347. 0xffa87fad,
  348. 0xffe2e234,
  349. 0xffeceeee,
  350. };
  351. uint32_t yy = 0;
  352. uint32_t xx = 0;
  353. const float texelWidth = 1.0f/2048.0f;
  354. const float texelWidthHalf = texelWidth*0.5f;
  355. const float texelHeight = 1.0f/24.0f;
  356. const float texelHeightHalf = RendererType::Direct3D9 == g_caps.rendererType ? texelHeight*0.5f : 0.0f;
  357. const float utop = (_mem.m_small ? 0.0f : 8.0f)*texelHeight + texelHeightHalf;
  358. const float ubottom = (_mem.m_small ? 8.0f : 24.0f)*texelHeight + texelHeightHalf;
  359. const float fontHeight = (_mem.m_small ? 8.0f : 16.0f);
  360. _renderCtx->blitSetup(_blitter);
  361. for (;yy < _mem.m_height;)
  362. {
  363. Vertex* vertex = (Vertex*)_blitter.m_vb->data;
  364. uint16_t* indices = (uint16_t*)_blitter.m_ib->data;
  365. uint32_t startVertex = 0;
  366. uint32_t numIndices = 0;
  367. for (; yy < _mem.m_height && numIndices < numBatchIndices; ++yy)
  368. {
  369. xx = xx < _mem.m_width ? xx : 0;
  370. const uint8_t* line = &_mem.m_mem[(yy*_mem.m_width+xx)*2];
  371. for (; xx < _mem.m_width && numIndices < numBatchIndices; ++xx)
  372. {
  373. uint8_t ch = line[0];
  374. uint8_t attr = line[1];
  375. if (0 != (ch|attr)
  376. && (' ' != ch || 0 != (attr&0xf0) ) )
  377. {
  378. uint32_t fg = palette[attr&0xf];
  379. uint32_t bg = palette[(attr>>4)&0xf];
  380. Vertex vert[4] =
  381. {
  382. { (xx )*8.0f, (yy )*fontHeight, 0.0f, fg, bg, (ch )*8.0f*texelWidth - texelWidthHalf, utop },
  383. { (xx+1)*8.0f, (yy )*fontHeight, 0.0f, fg, bg, (ch+1)*8.0f*texelWidth - texelWidthHalf, utop },
  384. { (xx+1)*8.0f, (yy+1)*fontHeight, 0.0f, fg, bg, (ch+1)*8.0f*texelWidth - texelWidthHalf, ubottom },
  385. { (xx )*8.0f, (yy+1)*fontHeight, 0.0f, fg, bg, (ch )*8.0f*texelWidth - texelWidthHalf, ubottom },
  386. };
  387. memcpy(vertex, vert, sizeof(vert) );
  388. vertex += 4;
  389. indices[0] = startVertex+0;
  390. indices[1] = startVertex+1;
  391. indices[2] = startVertex+2;
  392. indices[3] = startVertex+2;
  393. indices[4] = startVertex+3;
  394. indices[5] = startVertex+0;
  395. startVertex += 4;
  396. indices += 6;
  397. numIndices += 6;
  398. }
  399. line += 2;
  400. }
  401. if (numIndices >= numBatchIndices)
  402. {
  403. break;
  404. }
  405. }
  406. _renderCtx->blitRender(_blitter, numIndices);
  407. }
  408. }
  409. void ClearQuad::init()
  410. {
  411. BGFX_CHECK_MAIN_THREAD();
  412. if (BX_ENABLED(BGFX_CONFIG_CLEAR_QUAD)
  413. && RendererType::OpenGLES != g_caps.rendererType
  414. && RendererType::Direct3D9 != g_caps.rendererType
  415. && RendererType::Null != g_caps.rendererType)
  416. {
  417. m_decl
  418. .begin()
  419. .add(Attrib::Position, 3, AttribType::Float)
  420. .add(Attrib::Color0, 4, AttribType::Uint8, true)
  421. .end();
  422. ShaderHandle vsh = BGFX_INVALID_HANDLE;
  423. const Memory* fragMem[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  424. if (RendererType::Direct3D11 == g_caps.rendererType)
  425. {
  426. vsh = createShader(makeRef(vs_clear_dx11, sizeof(vs_clear_dx11) ) );
  427. fragMem[0] = makeRef(fs_clear0_dx11, sizeof(fs_clear0_dx11) );
  428. fragMem[1] = makeRef(fs_clear1_dx11, sizeof(fs_clear1_dx11) );
  429. fragMem[2] = makeRef(fs_clear2_dx11, sizeof(fs_clear2_dx11) );
  430. fragMem[3] = makeRef(fs_clear3_dx11, sizeof(fs_clear3_dx11) );
  431. }
  432. else if (RendererType::OpenGL == g_caps.rendererType)
  433. {
  434. vsh = createShader(makeRef(vs_clear_glsl, sizeof(vs_clear_glsl) ) );
  435. fragMem[0] = makeRef(fs_clear0_glsl, sizeof(fs_clear0_glsl) );
  436. fragMem[1] = makeRef(fs_clear1_glsl, sizeof(fs_clear1_glsl) );
  437. fragMem[2] = makeRef(fs_clear2_glsl, sizeof(fs_clear2_glsl) );
  438. fragMem[3] = makeRef(fs_clear3_glsl, sizeof(fs_clear3_glsl) );
  439. }
  440. for (uint32_t ii = 0, num = g_caps.maxFBAttachments; ii < num; ++ii)
  441. {
  442. ShaderHandle fsh = createShader(fragMem[ii]);
  443. m_program[ii] = createProgram(vsh, fsh);
  444. destroyShader(fsh);
  445. }
  446. destroyShader(vsh);
  447. m_vb = s_ctx->createTransientVertexBuffer(4*m_decl.m_stride, &m_decl);
  448. const Memory* mem = alloc(6*sizeof(uint16_t) );
  449. uint16_t* indices = (uint16_t*)mem->data;
  450. indices[0] = 0;
  451. indices[1] = 1;
  452. indices[2] = 2;
  453. indices[3] = 2;
  454. indices[4] = 3;
  455. indices[5] = 0;
  456. m_ib = s_ctx->createIndexBuffer(mem);
  457. }
  458. }
  459. void ClearQuad::shutdown()
  460. {
  461. BGFX_CHECK_MAIN_THREAD();
  462. if (BX_ENABLED(BGFX_CONFIG_CLEAR_QUAD)
  463. && RendererType::OpenGLES != g_caps.rendererType
  464. && RendererType::Direct3D9 != g_caps.rendererType
  465. && RendererType::Null != g_caps.rendererType)
  466. {
  467. for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS; ++ii)
  468. {
  469. if (isValid(m_program[ii]) )
  470. {
  471. destroyProgram(m_program[ii]);
  472. m_program[ii].idx = invalidHandle;
  473. }
  474. }
  475. destroyIndexBuffer(m_ib);
  476. s_ctx->destroyTransientVertexBuffer(m_vb);
  477. }
  478. }
  479. const char* s_uniformTypeName[UniformType::Count] =
  480. {
  481. "int",
  482. "float",
  483. NULL,
  484. "int",
  485. "float",
  486. "vec2",
  487. "vec3",
  488. "vec4",
  489. "mat3",
  490. "mat4",
  491. };
  492. const char* getUniformTypeName(UniformType::Enum _enum)
  493. {
  494. return s_uniformTypeName[_enum];
  495. }
  496. UniformType::Enum nameToUniformTypeEnum(const char* _name)
  497. {
  498. for (uint32_t ii = 0; ii < UniformType::Count; ++ii)
  499. {
  500. if (NULL != s_uniformTypeName[ii]
  501. && 0 == strcmp(_name, s_uniformTypeName[ii]) )
  502. {
  503. return UniformType::Enum(ii);
  504. }
  505. }
  506. return UniformType::Count;
  507. }
  508. static const char* s_predefinedName[PredefinedUniform::Count] =
  509. {
  510. "u_viewRect",
  511. "u_viewTexel",
  512. "u_view",
  513. "u_invView",
  514. "u_proj",
  515. "u_invProj",
  516. "u_viewProj",
  517. "u_invViewProj",
  518. "u_viewProjX",
  519. "u_model",
  520. "u_modelView",
  521. "u_modelViewProj",
  522. "u_modelViewProjX",
  523. "u_alphaRef",
  524. };
  525. const char* getPredefinedUniformName(PredefinedUniform::Enum _enum)
  526. {
  527. return s_predefinedName[_enum];
  528. }
  529. PredefinedUniform::Enum nameToPredefinedUniformEnum(const char* _name)
  530. {
  531. for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
  532. {
  533. if (0 == strcmp(_name, s_predefinedName[ii]) )
  534. {
  535. return PredefinedUniform::Enum(ii);
  536. }
  537. }
  538. return PredefinedUniform::Count;
  539. }
  540. uint32_t Frame::submit(uint8_t _id, int32_t _depth)
  541. {
  542. if (m_discard)
  543. {
  544. discard();
  545. return m_num;
  546. }
  547. if (BGFX_CONFIG_MAX_DRAW_CALLS-1 <= m_num
  548. || (0 == m_state.m_numVertices && 0 == m_state.m_numIndices) )
  549. {
  550. ++m_numDropped;
  551. return m_num;
  552. }
  553. BX_WARN(invalidHandle != m_key.m_program, "Program with invalid handle");
  554. if (invalidHandle != m_key.m_program)
  555. {
  556. m_key.m_depth = _depth;
  557. m_key.m_view = _id;
  558. m_key.m_seq = s_ctx->m_seq[_id] & s_ctx->m_seqMask[_id];
  559. s_ctx->m_seq[_id]++;
  560. uint64_t key = m_key.encode();
  561. m_sortKeys[m_num] = key;
  562. m_sortValues[m_num] = m_numRenderStates;
  563. ++m_num;
  564. m_state.m_constEnd = m_constantBuffer->getPos();
  565. m_state.m_flags |= m_flags;
  566. m_renderState[m_numRenderStates] = m_state;
  567. ++m_numRenderStates;
  568. }
  569. m_state.clear();
  570. m_flags = BGFX_STATE_NONE;
  571. return m_num;
  572. }
  573. uint32_t Frame::submitMask(uint32_t _viewMask, int32_t _depth)
  574. {
  575. if (m_discard)
  576. {
  577. discard();
  578. return m_num;
  579. }
  580. if (BGFX_CONFIG_MAX_DRAW_CALLS-1 <= m_num
  581. || (0 == m_state.m_numVertices && 0 == m_state.m_numIndices) )
  582. {
  583. m_numDropped += bx::uint32_cntbits(_viewMask);
  584. return m_num;
  585. }
  586. BX_WARN(invalidHandle != m_key.m_program, "Program with invalid handle");
  587. if (invalidHandle != m_key.m_program)
  588. {
  589. m_key.m_depth = _depth;
  590. for (uint32_t id = 0, viewMask = _viewMask, ntz = bx::uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, id += 1, ntz = bx::uint32_cnttz(viewMask) )
  591. {
  592. viewMask >>= ntz;
  593. id += ntz;
  594. m_key.m_view = id;
  595. m_key.m_seq = s_ctx->m_seq[id] & s_ctx->m_seqMask[id];
  596. s_ctx->m_seq[id]++;
  597. uint64_t key = m_key.encode();
  598. m_sortKeys[m_num] = key;
  599. m_sortValues[m_num] = m_numRenderStates;
  600. ++m_num;
  601. }
  602. m_state.m_constEnd = m_constantBuffer->getPos();
  603. m_state.m_flags |= m_flags;
  604. m_renderState[m_numRenderStates] = m_state;
  605. ++m_numRenderStates;
  606. }
  607. m_state.clear();
  608. m_flags = BGFX_STATE_NONE;
  609. return m_num;
  610. }
  611. void Frame::sort()
  612. {
  613. bx::radixSort64(m_sortKeys, s_ctx->m_tempKeys, m_sortValues, s_ctx->m_tempValues, m_num);
  614. }
  615. RenderFrame::Enum renderFrame()
  616. {
  617. if (NULL == s_ctx)
  618. {
  619. s_renderFrameCalled = true;
  620. return RenderFrame::NoContext;
  621. }
  622. BGFX_CHECK_RENDER_THREAD();
  623. if (s_ctx->renderFrame() )
  624. {
  625. return RenderFrame::Exiting;
  626. }
  627. return RenderFrame::Render;
  628. }
  629. const uint32_t g_uniformTypeSize[UniformType::Count+1] =
  630. {
  631. sizeof(int32_t),
  632. sizeof(float),
  633. 0,
  634. 1*sizeof(int32_t),
  635. 1*sizeof(float),
  636. 2*sizeof(float),
  637. 3*sizeof(float),
  638. 4*sizeof(float),
  639. 3*3*sizeof(float),
  640. 4*4*sizeof(float),
  641. 1,
  642. };
  643. void ConstantBuffer::writeUniform(UniformType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num)
  644. {
  645. uint32_t opcode = encodeOpcode(_type, _loc, _num, true);
  646. write(opcode);
  647. write(_value, g_uniformTypeSize[_type]*_num);
  648. }
  649. void ConstantBuffer::writeUniformHandle(UniformType::Enum _type, uint16_t _loc, UniformHandle _handle, uint16_t _num)
  650. {
  651. uint32_t opcode = encodeOpcode(_type, _loc, _num, false);
  652. write(opcode);
  653. write(&_handle, sizeof(UniformHandle) );
  654. }
  655. void ConstantBuffer::writeMarker(const char* _marker)
  656. {
  657. uint16_t num = (uint16_t)strlen(_marker)+1;
  658. uint32_t opcode = encodeOpcode(bgfx::UniformType::Count, 0, num, true);
  659. write(opcode);
  660. write(_marker, num);
  661. }
  662. struct CapsFlags
  663. {
  664. uint64_t m_flag;
  665. const char* m_str;
  666. };
  667. static const CapsFlags s_capsFlags[] =
  668. {
  669. #define CAPS_FLAGS(_x) { _x, #_x }
  670. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_BC1),
  671. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_BC2),
  672. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_BC3),
  673. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_BC4),
  674. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_BC5),
  675. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_ETC1),
  676. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_ETC2),
  677. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_ETC2A),
  678. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_ETC2A1),
  679. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_PTC12),
  680. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_PTC14),
  681. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_PTC14A),
  682. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_PTC12A),
  683. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_PTC22),
  684. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_PTC24),
  685. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_D16),
  686. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_D24),
  687. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_D24S8),
  688. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_D32),
  689. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_D16F),
  690. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_D24F),
  691. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_D32F),
  692. CAPS_FLAGS(BGFX_CAPS_TEXTURE_FORMAT_D0S8),
  693. CAPS_FLAGS(BGFX_CAPS_TEXTURE_COMPARE_LEQUAL),
  694. CAPS_FLAGS(BGFX_CAPS_TEXTURE_COMPARE_ALL),
  695. CAPS_FLAGS(BGFX_CAPS_TEXTURE_3D),
  696. CAPS_FLAGS(BGFX_CAPS_VERTEX_ATTRIB_HALF),
  697. CAPS_FLAGS(BGFX_CAPS_INSTANCING),
  698. CAPS_FLAGS(BGFX_CAPS_RENDERER_MULTITHREADED),
  699. CAPS_FLAGS(BGFX_CAPS_FRAGMENT_DEPTH),
  700. CAPS_FLAGS(BGFX_CAPS_BLEND_INDEPENDENT),
  701. #undef CAPS_FLAGS
  702. };
  703. static void dumpCaps()
  704. {
  705. BX_TRACE("Supported capabilities (%s):", s_ctx->m_renderCtx->getRendererName() );
  706. for (uint32_t ii = 0; ii < BX_COUNTOF(s_capsFlags); ++ii)
  707. {
  708. if (0 != (g_caps.supported & s_capsFlags[ii].m_flag) )
  709. {
  710. BX_TRACE("\t%s", s_capsFlags[ii].m_str);
  711. }
  712. }
  713. BX_TRACE("Emulated capabilities:");
  714. for (uint32_t ii = 0; ii < BX_COUNTOF(s_capsFlags); ++ii)
  715. {
  716. if (0 != (g_caps.emulated & s_capsFlags[ii].m_flag) )
  717. {
  718. BX_TRACE("\t%s", s_capsFlags[ii].m_str);
  719. }
  720. }
  721. BX_TRACE("Max FB attachments: %d", g_caps.maxFBAttachments);
  722. }
  723. void Context::init(RendererType::Enum _type)
  724. {
  725. BX_CHECK(!m_rendererInitialized, "Already initialized?");
  726. m_exit = false;
  727. m_frames = 0;
  728. m_render = &m_frame[0];
  729. m_submit = &m_frame[1];
  730. m_debug = BGFX_DEBUG_NONE;
  731. m_submit->create();
  732. m_render->create();
  733. #if BGFX_CONFIG_MULTITHREADED
  734. if (s_renderFrameCalled)
  735. {
  736. // When bgfx::renderFrame is called before init render thread
  737. // should not be created.
  738. BX_TRACE("Application called bgfx::renderFrame directly, not creating render thread.");
  739. }
  740. else
  741. {
  742. BX_TRACE("Creating rendering thread.");
  743. m_thread.init(renderThread, this);
  744. }
  745. #else
  746. BX_TRACE("Multithreaded renderer is disabled.");
  747. #endif // BGFX_CONFIG_MULTITHREADED
  748. memset(m_fb, 0xff, sizeof(m_fb) );
  749. memset(m_clear, 0, sizeof(m_clear) );
  750. memset(m_rect, 0, sizeof(m_rect) );
  751. memset(m_scissor, 0, sizeof(m_scissor) );
  752. memset(m_seq, 0, sizeof(m_seq) );
  753. memset(m_seqMask, 0, sizeof(m_seqMask) );
  754. for (uint32_t ii = 0; ii < BX_COUNTOF(m_rect); ++ii)
  755. {
  756. m_rect[ii].m_width = 1;
  757. m_rect[ii].m_height = 1;
  758. }
  759. m_declRef.init();
  760. CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::RendererInit);
  761. cmdbuf.write(_type);
  762. frameNoRenderWait();
  763. // Make sure renderer init is called from render thread.
  764. // g_caps is initialized and available after this point.
  765. frame();
  766. const uint64_t emulatedCaps = 0
  767. | BGFX_CAPS_TEXTURE_FORMAT_BC1
  768. | BGFX_CAPS_TEXTURE_FORMAT_BC2
  769. | BGFX_CAPS_TEXTURE_FORMAT_BC3
  770. | BGFX_CAPS_TEXTURE_FORMAT_BC4
  771. | BGFX_CAPS_TEXTURE_FORMAT_BC5
  772. | BGFX_CAPS_TEXTURE_FORMAT_ETC1
  773. | BGFX_CAPS_TEXTURE_FORMAT_ETC2
  774. | BGFX_CAPS_TEXTURE_FORMAT_ETC2A
  775. | BGFX_CAPS_TEXTURE_FORMAT_ETC2A1
  776. ;
  777. g_caps.emulated |= emulatedCaps ^ (g_caps.supported & emulatedCaps);
  778. g_caps.rendererType = m_renderCtx->getRendererType();
  779. initAttribTypeSizeTable(g_caps.rendererType);
  780. dumpCaps();
  781. m_textVideoMemBlitter.init();
  782. m_clearQuad.init();
  783. m_submit->m_transientVb = createTransientVertexBuffer(BGFX_CONFIG_TRANSIENT_VERTEX_BUFFER_SIZE);
  784. m_submit->m_transientIb = createTransientIndexBuffer(BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE);
  785. frame();
  786. m_submit->m_transientVb = createTransientVertexBuffer(BGFX_CONFIG_TRANSIENT_VERTEX_BUFFER_SIZE);
  787. m_submit->m_transientIb = createTransientIndexBuffer(BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE);
  788. frame();
  789. for (uint8_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
  790. {
  791. char name[256];
  792. bx::snprintf(name, sizeof(name), "%02d view", ii);
  793. setViewName(ii, name);
  794. }
  795. }
  796. void Context::shutdown()
  797. {
  798. getCommandBuffer(CommandBuffer::RendererShutdownBegin);
  799. frame();
  800. destroyTransientVertexBuffer(m_submit->m_transientVb);
  801. destroyTransientIndexBuffer(m_submit->m_transientIb);
  802. m_textVideoMemBlitter.shutdown();
  803. m_clearQuad.shutdown();
  804. frame();
  805. destroyTransientVertexBuffer(m_submit->m_transientVb);
  806. destroyTransientIndexBuffer(m_submit->m_transientIb);
  807. frame();
  808. frame(); // If any VertexDecls needs to be destroyed.
  809. getCommandBuffer(CommandBuffer::RendererShutdownEnd);
  810. frame();
  811. m_declRef.shutdown(m_vertexDeclHandle);
  812. #if BGFX_CONFIG_MULTITHREADED
  813. if (m_thread.isRunning() )
  814. {
  815. m_thread.shutdown();
  816. }
  817. #endif // BGFX_CONFIG_MULTITHREADED
  818. s_ctx = NULL; // Can't be used by renderFrame at this point.
  819. renderSemWait();
  820. m_submit->destroy();
  821. m_render->destroy();
  822. if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
  823. {
  824. #define CHECK_HANDLE_LEAK(_handleAlloc) \
  825. do { \
  826. BX_WARN(0 == _handleAlloc.getNumHandles() \
  827. , "LEAK: " #_handleAlloc " %d (max: %d)" \
  828. , _handleAlloc.getNumHandles() \
  829. , _handleAlloc.getMaxHandles() \
  830. ); \
  831. } while (0)
  832. CHECK_HANDLE_LEAK(m_dynamicIndexBufferHandle);
  833. CHECK_HANDLE_LEAK(m_dynamicVertexBufferHandle);
  834. CHECK_HANDLE_LEAK(m_indexBufferHandle);
  835. CHECK_HANDLE_LEAK(m_vertexDeclHandle);
  836. CHECK_HANDLE_LEAK(m_vertexBufferHandle);
  837. CHECK_HANDLE_LEAK(m_shaderHandle);
  838. CHECK_HANDLE_LEAK(m_programHandle);
  839. CHECK_HANDLE_LEAK(m_textureHandle);
  840. CHECK_HANDLE_LEAK(m_frameBufferHandle);
  841. CHECK_HANDLE_LEAK(m_uniformHandle);
  842. #undef CHECK_HANDLE_LEAK
  843. }
  844. }
  845. void Context::freeDynamicBuffers()
  846. {
  847. for (uint16_t ii = 0, num = m_numFreeDynamicIndexBufferHandles; ii < num; ++ii)
  848. {
  849. destroyDynamicIndexBufferInternal(m_freeDynamicIndexBufferHandle[ii]);
  850. }
  851. m_numFreeDynamicIndexBufferHandles = 0;
  852. for (uint16_t ii = 0, num = m_numFreeDynamicVertexBufferHandles; ii < num; ++ii)
  853. {
  854. destroyDynamicVertexBufferInternal(m_freeDynamicVertexBufferHandle[ii]);
  855. }
  856. m_numFreeDynamicVertexBufferHandles = 0;
  857. }
  858. void Context::freeAllHandles(Frame* _frame)
  859. {
  860. for (uint16_t ii = 0, num = _frame->m_numFreeIndexBufferHandles; ii < num; ++ii)
  861. {
  862. m_indexBufferHandle.free(_frame->m_freeIndexBufferHandle[ii].idx);
  863. }
  864. for (uint16_t ii = 0, num = _frame->m_numFreeVertexDeclHandles; ii < num; ++ii)
  865. {
  866. m_vertexDeclHandle.free(_frame->m_freeVertexDeclHandle[ii].idx);
  867. }
  868. for (uint16_t ii = 0, num = _frame->m_numFreeVertexBufferHandles; ii < num; ++ii)
  869. {
  870. destroyVertexBufferInternal(_frame->m_freeVertexBufferHandle[ii]);
  871. }
  872. for (uint16_t ii = 0, num = _frame->m_numFreeShaderHandles; ii < num; ++ii)
  873. {
  874. m_shaderHandle.free(_frame->m_freeShaderHandle[ii].idx);
  875. }
  876. for (uint16_t ii = 0, num = _frame->m_numFreeProgramHandles; ii < num; ++ii)
  877. {
  878. m_programHandle.free(_frame->m_freeProgramHandle[ii].idx);
  879. }
  880. for (uint16_t ii = 0, num = _frame->m_numFreeTextureHandles; ii < num; ++ii)
  881. {
  882. m_textureHandle.free(_frame->m_freeTextureHandle[ii].idx);
  883. }
  884. for (uint16_t ii = 0, num = _frame->m_numFreeFrameBufferHandles; ii < num; ++ii)
  885. {
  886. m_frameBufferHandle.free(_frame->m_freeFrameBufferHandle[ii].idx);
  887. }
  888. for (uint16_t ii = 0, num = _frame->m_numFreeUniformHandles; ii < num; ++ii)
  889. {
  890. m_uniformHandle.free(_frame->m_freeUniformHandle[ii].idx);
  891. }
  892. }
  893. uint32_t Context::frame()
  894. {
  895. BX_CHECK(0 == m_instBufferCount, "Instance buffer allocated, but not used. This is incorrect, and causes memory leak.");
  896. // wait for render thread to finish
  897. renderSemWait();
  898. frameNoRenderWait();
  899. return m_frames;
  900. }
  901. void Context::frameNoRenderWait()
  902. {
  903. swap();
  904. // release render thread
  905. gameSemPost();
  906. #if !BGFX_CONFIG_MULTITHREADED
  907. renderFrame();
  908. #endif // BGFX_CONFIG_MULTITHREADED
  909. }
  910. void Context::swap()
  911. {
  912. freeDynamicBuffers();
  913. m_submit->m_resolution = m_resolution;
  914. m_submit->m_debug = m_debug;
  915. memcpy(m_submit->m_fb, m_fb, sizeof(m_fb) );
  916. memcpy(m_submit->m_clear, m_clear, sizeof(m_clear) );
  917. memcpy(m_submit->m_rect, m_rect, sizeof(m_rect) );
  918. memcpy(m_submit->m_scissor, m_scissor, sizeof(m_scissor) );
  919. memcpy(m_submit->m_view, m_view, sizeof(m_view) );
  920. memcpy(m_submit->m_proj, m_proj, sizeof(m_proj) );
  921. memcpy(m_submit->m_other, m_other, sizeof(m_other) );
  922. m_submit->finish();
  923. Frame* temp = m_render;
  924. m_render = m_submit;
  925. m_submit = temp;
  926. m_frames++;
  927. m_submit->start();
  928. memset(m_seq, 0, sizeof(m_seq) );
  929. freeAllHandles(m_submit);
  930. m_submit->resetFreeHandles();
  931. m_submit->m_textVideoMem->resize(m_render->m_textVideoMem->m_small, m_resolution.m_width, m_resolution.m_height);
  932. }
  933. bool Context::renderFrame()
  934. {
  935. if (m_rendererInitialized)
  936. {
  937. m_renderCtx->flip();
  938. }
  939. gameSemWait();
  940. rendererExecCommands(m_render->m_cmdPre);
  941. if (m_rendererInitialized)
  942. {
  943. m_renderCtx->submit(m_render, m_clearQuad, m_textVideoMemBlitter);
  944. }
  945. rendererExecCommands(m_render->m_cmdPost);
  946. renderSemPost();
  947. return m_exit;
  948. }
  949. void rendererUpdateUniforms(RendererContextI* _renderCtx, ConstantBuffer* _constantBuffer, uint32_t _begin, uint32_t _end)
  950. {
  951. _constantBuffer->reset(_begin);
  952. while (_constantBuffer->getPos() < _end)
  953. {
  954. uint32_t opcode = _constantBuffer->read();
  955. if (UniformType::End == opcode)
  956. {
  957. break;
  958. }
  959. UniformType::Enum type;
  960. uint16_t loc;
  961. uint16_t num;
  962. uint16_t copy;
  963. ConstantBuffer::decodeOpcode(opcode, type, loc, num, copy);
  964. uint32_t size = g_uniformTypeSize[type]*num;
  965. const char* data = _constantBuffer->read(size);
  966. if (UniformType::Count > type)
  967. {
  968. if (copy)
  969. {
  970. _renderCtx->updateUniform(loc, data, size);
  971. }
  972. else
  973. {
  974. _renderCtx->updateUniform(loc, *(const char**)(data), size);
  975. }
  976. }
  977. else
  978. {
  979. _renderCtx->setMarker(data, size);
  980. }
  981. }
  982. }
  983. void Context::flushTextureUpdateBatch(CommandBuffer& _cmdbuf)
  984. {
  985. if (m_textureUpdateBatch.sort() )
  986. {
  987. const uint32_t pos = _cmdbuf.m_pos;
  988. uint32_t currentKey = UINT32_MAX;
  989. for (uint32_t ii = 0, num = m_textureUpdateBatch.m_num; ii < num; ++ii)
  990. {
  991. _cmdbuf.m_pos = m_textureUpdateBatch.m_values[ii];
  992. TextureHandle handle;
  993. _cmdbuf.read(handle);
  994. uint8_t side;
  995. _cmdbuf.read(side);
  996. uint8_t mip;
  997. _cmdbuf.read(mip);
  998. Rect rect;
  999. _cmdbuf.read(rect);
  1000. uint16_t zz;
  1001. _cmdbuf.read(zz);
  1002. uint16_t depth;
  1003. _cmdbuf.read(depth);
  1004. uint16_t pitch;
  1005. _cmdbuf.read(pitch);
  1006. Memory* mem;
  1007. _cmdbuf.read(mem);
  1008. uint32_t key = m_textureUpdateBatch.m_keys[ii];
  1009. if (key != currentKey)
  1010. {
  1011. if (currentKey != UINT32_MAX)
  1012. {
  1013. m_renderCtx->updateTextureEnd();
  1014. }
  1015. currentKey = key;
  1016. m_renderCtx->updateTextureBegin(handle, side, mip);
  1017. }
  1018. m_renderCtx->updateTexture(handle, side, mip, rect, zz, depth, pitch, mem);
  1019. release(mem);
  1020. }
  1021. if (currentKey != UINT32_MAX)
  1022. {
  1023. m_renderCtx->updateTextureEnd();
  1024. }
  1025. m_textureUpdateBatch.reset();
  1026. _cmdbuf.m_pos = pos;
  1027. }
  1028. }
  1029. typedef RendererContextI* (*RendererCreateFn)();
  1030. typedef void (*RendererDestroyFn)();
  1031. extern RendererContextI* rendererCreateNULL();
  1032. extern void rendererDestroyNULL();
  1033. extern RendererContextI* rendererCreateGL();
  1034. extern void rendererDestroyGL();
  1035. extern RendererContextI* rendererCreateD3D9();
  1036. extern void rendererDestroyD3D9();
  1037. extern RendererContextI* rendererCreateD3D11();
  1038. extern void rendererDestroyD3D11();
  1039. struct RendererCreator
  1040. {
  1041. RendererCreateFn createFn;
  1042. RendererDestroyFn destroyFn;
  1043. const char* name;
  1044. bool supported;
  1045. };
  1046. static const RendererCreator s_rendererCreator[RendererType::Count] =
  1047. {
  1048. { rendererCreateNULL, rendererDestroyNULL, BGFX_RENDERER_NULL_NAME, !!BGFX_CONFIG_RENDERER_NULL }, // Null
  1049. { rendererCreateD3D9, rendererDestroyD3D9, BGFX_RENDERER_DIRECT3D9_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D9 }, // Direct3D9
  1050. { rendererCreateD3D11, rendererDestroyD3D11, BGFX_RENDERER_DIRECT3D11_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D11 }, // Direct3D11
  1051. { rendererCreateGL, rendererDestroyGL, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGLES }, // OpenGLES
  1052. { rendererCreateGL, rendererDestroyGL, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGL }, // OpenGL
  1053. };
  1054. uint32_t getWindowsVersion()
  1055. {
  1056. #if BX_PLATFORM_WINDOWS
  1057. OSVERSIONINFOEXA ovi = {};
  1058. ovi.dwOSVersionInfoSize = sizeof(ovi);
  1059. if (!GetVersionExA( (LPOSVERSIONINFOA)&ovi) )
  1060. {
  1061. return 0x0501; // _WIN32_WINNT_WINXP
  1062. }
  1063. // _WIN32_WINNT_WINBLUE 0x0602
  1064. // _WIN32_WINNT_WIN8 0x0602
  1065. // _WIN32_WINNT_WIN7 0x0601
  1066. // _WIN32_WINNT_VISTA 0x0600
  1067. return (ovi.dwMajorVersion<<8)
  1068. | ovi.dwMinorVersion
  1069. ;
  1070. #else
  1071. return 0;
  1072. #endif // BX_PLATFORM_WINDOWS
  1073. }
  1074. RendererContextI* rendererCreate(RendererType::Enum _type)
  1075. {
  1076. if (RendererType::Count == _type)
  1077. {
  1078. again:
  1079. if (BX_ENABLED(BX_PLATFORM_WINDOWS) )
  1080. {
  1081. RendererType::Enum first = RendererType::Direct3D9;
  1082. RendererType::Enum second = RendererType::Direct3D11;
  1083. if (0x602 == getWindowsVersion() )
  1084. {
  1085. first = RendererType::Direct3D11;
  1086. second = RendererType::Direct3D9;
  1087. }
  1088. if (s_rendererCreator[first].supported)
  1089. {
  1090. _type = first;
  1091. }
  1092. else if (s_rendererCreator[second].supported)
  1093. {
  1094. _type = second;
  1095. }
  1096. else if (s_rendererCreator[RendererType::OpenGL].supported)
  1097. {
  1098. _type = RendererType::OpenGL;
  1099. }
  1100. else if (s_rendererCreator[RendererType::OpenGLES].supported)
  1101. {
  1102. _type = RendererType::OpenGLES;
  1103. }
  1104. }
  1105. else if (BX_ENABLED(0
  1106. || BX_PLATFORM_ANDROID
  1107. || BX_PLATFORM_EMSCRIPTEN
  1108. || BX_PLATFORM_IOS
  1109. || BX_PLATFORM_NACL
  1110. ) )
  1111. {
  1112. _type = RendererType::OpenGLES;
  1113. }
  1114. else
  1115. {
  1116. _type = RendererType::OpenGL;
  1117. }
  1118. if (!s_rendererCreator[_type].supported)
  1119. {
  1120. _type = RendererType::Null;
  1121. }
  1122. }
  1123. RendererContextI* renderCtx = s_rendererCreator[_type].createFn();
  1124. if (NULL == renderCtx)
  1125. {
  1126. goto again;
  1127. }
  1128. return renderCtx;
  1129. }
  1130. void rendererDestroy()
  1131. {
  1132. const RendererType::Enum type = getRendererType();
  1133. s_rendererCreator[type].destroyFn();
  1134. }
  1135. void Context::rendererExecCommands(CommandBuffer& _cmdbuf)
  1136. {
  1137. _cmdbuf.reset();
  1138. bool end = false;
  1139. do
  1140. {
  1141. uint8_t command;
  1142. _cmdbuf.read(command);
  1143. switch (command)
  1144. {
  1145. case CommandBuffer::RendererInit:
  1146. {
  1147. BX_CHECK(!m_rendererInitialized, "This shouldn't happen! Bad synchronization?");
  1148. RendererType::Enum type;
  1149. _cmdbuf.read(type);
  1150. m_renderCtx = rendererCreate(type);
  1151. m_rendererInitialized = true;
  1152. }
  1153. break;
  1154. case CommandBuffer::RendererShutdownBegin:
  1155. {
  1156. BX_CHECK(m_rendererInitialized, "This shouldn't happen! Bad synchronization?");
  1157. m_rendererInitialized = false;
  1158. }
  1159. break;
  1160. case CommandBuffer::RendererShutdownEnd:
  1161. {
  1162. BX_CHECK(!m_rendererInitialized && !m_exit, "This shouldn't happen! Bad synchronization?");
  1163. rendererDestroy();
  1164. m_renderCtx = NULL;
  1165. m_exit = true;
  1166. }
  1167. break;
  1168. case CommandBuffer::CreateIndexBuffer:
  1169. {
  1170. IndexBufferHandle handle;
  1171. _cmdbuf.read(handle);
  1172. Memory* mem;
  1173. _cmdbuf.read(mem);
  1174. m_renderCtx->createIndexBuffer(handle, mem);
  1175. release(mem);
  1176. }
  1177. break;
  1178. case CommandBuffer::DestroyIndexBuffer:
  1179. {
  1180. IndexBufferHandle handle;
  1181. _cmdbuf.read(handle);
  1182. m_renderCtx->destroyIndexBuffer(handle);
  1183. }
  1184. break;
  1185. case CommandBuffer::CreateVertexDecl:
  1186. {
  1187. VertexDeclHandle handle;
  1188. _cmdbuf.read(handle);
  1189. VertexDecl decl;
  1190. _cmdbuf.read(decl);
  1191. m_renderCtx->createVertexDecl(handle, decl);
  1192. }
  1193. break;
  1194. case CommandBuffer::DestroyVertexDecl:
  1195. {
  1196. VertexDeclHandle handle;
  1197. _cmdbuf.read(handle);
  1198. m_renderCtx->destroyVertexDecl(handle);
  1199. }
  1200. break;
  1201. case CommandBuffer::CreateVertexBuffer:
  1202. {
  1203. VertexBufferHandle handle;
  1204. _cmdbuf.read(handle);
  1205. Memory* mem;
  1206. _cmdbuf.read(mem);
  1207. VertexDeclHandle declHandle;
  1208. _cmdbuf.read(declHandle);
  1209. m_renderCtx->createVertexBuffer(handle, mem, declHandle);
  1210. release(mem);
  1211. }
  1212. break;
  1213. case CommandBuffer::DestroyVertexBuffer:
  1214. {
  1215. VertexBufferHandle handle;
  1216. _cmdbuf.read(handle);
  1217. m_renderCtx->destroyVertexBuffer(handle);
  1218. }
  1219. break;
  1220. case CommandBuffer::CreateDynamicIndexBuffer:
  1221. {
  1222. IndexBufferHandle handle;
  1223. _cmdbuf.read(handle);
  1224. uint32_t size;
  1225. _cmdbuf.read(size);
  1226. m_renderCtx->createDynamicIndexBuffer(handle, size);
  1227. }
  1228. break;
  1229. case CommandBuffer::UpdateDynamicIndexBuffer:
  1230. {
  1231. IndexBufferHandle handle;
  1232. _cmdbuf.read(handle);
  1233. uint32_t offset;
  1234. _cmdbuf.read(offset);
  1235. uint32_t size;
  1236. _cmdbuf.read(size);
  1237. Memory* mem;
  1238. _cmdbuf.read(mem);
  1239. m_renderCtx->updateDynamicIndexBuffer(handle, offset, size, mem);
  1240. release(mem);
  1241. }
  1242. break;
  1243. case CommandBuffer::DestroyDynamicIndexBuffer:
  1244. {
  1245. IndexBufferHandle handle;
  1246. _cmdbuf.read(handle);
  1247. m_renderCtx->destroyDynamicIndexBuffer(handle);
  1248. }
  1249. break;
  1250. case CommandBuffer::CreateDynamicVertexBuffer:
  1251. {
  1252. VertexBufferHandle handle;
  1253. _cmdbuf.read(handle);
  1254. uint32_t size;
  1255. _cmdbuf.read(size);
  1256. m_renderCtx->createDynamicVertexBuffer(handle, size);
  1257. }
  1258. break;
  1259. case CommandBuffer::UpdateDynamicVertexBuffer:
  1260. {
  1261. VertexBufferHandle handle;
  1262. _cmdbuf.read(handle);
  1263. uint32_t offset;
  1264. _cmdbuf.read(offset);
  1265. uint32_t size;
  1266. _cmdbuf.read(size);
  1267. Memory* mem;
  1268. _cmdbuf.read(mem);
  1269. m_renderCtx->updateDynamicVertexBuffer(handle, offset, size, mem);
  1270. release(mem);
  1271. }
  1272. break;
  1273. case CommandBuffer::DestroyDynamicVertexBuffer:
  1274. {
  1275. VertexBufferHandle handle;
  1276. _cmdbuf.read(handle);
  1277. m_renderCtx->destroyDynamicVertexBuffer(handle);
  1278. }
  1279. break;
  1280. case CommandBuffer::CreateShader:
  1281. {
  1282. ShaderHandle handle;
  1283. _cmdbuf.read(handle);
  1284. Memory* mem;
  1285. _cmdbuf.read(mem);
  1286. m_renderCtx->createShader(handle, mem);
  1287. release(mem);
  1288. }
  1289. break;
  1290. case CommandBuffer::DestroyShader:
  1291. {
  1292. ShaderHandle handle;
  1293. _cmdbuf.read(handle);
  1294. m_renderCtx->destroyShader(handle);
  1295. }
  1296. break;
  1297. case CommandBuffer::CreateProgram:
  1298. {
  1299. ProgramHandle handle;
  1300. _cmdbuf.read(handle);
  1301. ShaderHandle vsh;
  1302. _cmdbuf.read(vsh);
  1303. ShaderHandle fsh;
  1304. _cmdbuf.read(fsh);
  1305. m_renderCtx->createProgram(handle, vsh, fsh);
  1306. }
  1307. break;
  1308. case CommandBuffer::DestroyProgram:
  1309. {
  1310. ProgramHandle handle;
  1311. _cmdbuf.read(handle);
  1312. m_renderCtx->destroyProgram(handle);
  1313. }
  1314. break;
  1315. case CommandBuffer::CreateTexture:
  1316. {
  1317. TextureHandle handle;
  1318. _cmdbuf.read(handle);
  1319. Memory* mem;
  1320. _cmdbuf.read(mem);
  1321. uint32_t flags;
  1322. _cmdbuf.read(flags);
  1323. uint8_t skip;
  1324. _cmdbuf.read(skip);
  1325. m_renderCtx->createTexture(handle, mem, flags, skip);
  1326. bx::MemoryReader reader(mem->data, mem->size);
  1327. uint32_t magic;
  1328. bx::read(&reader, magic);
  1329. if (BGFX_CHUNK_MAGIC_TEX == magic)
  1330. {
  1331. TextureCreate tc;
  1332. bx::read(&reader, tc);
  1333. if (NULL != tc.m_mem)
  1334. {
  1335. release(tc.m_mem);
  1336. }
  1337. }
  1338. release(mem);
  1339. }
  1340. break;
  1341. case CommandBuffer::UpdateTexture:
  1342. {
  1343. if (m_textureUpdateBatch.isFull() )
  1344. {
  1345. flushTextureUpdateBatch(_cmdbuf);
  1346. }
  1347. uint32_t value = _cmdbuf.m_pos;
  1348. TextureHandle handle;
  1349. _cmdbuf.read(handle);
  1350. uint8_t side;
  1351. _cmdbuf.read(side);
  1352. uint8_t mip;
  1353. _cmdbuf.read(mip);
  1354. _cmdbuf.skip<Rect>();
  1355. _cmdbuf.skip<uint16_t>();
  1356. _cmdbuf.skip<uint16_t>();
  1357. _cmdbuf.skip<uint16_t>();
  1358. _cmdbuf.skip<Memory*>();
  1359. uint32_t key = (handle.idx<<16)
  1360. | (side<<8)
  1361. | mip
  1362. ;
  1363. m_textureUpdateBatch.add(key, value);
  1364. }
  1365. break;
  1366. case CommandBuffer::DestroyTexture:
  1367. {
  1368. TextureHandle handle;
  1369. _cmdbuf.read(handle);
  1370. m_renderCtx->destroyTexture(handle);
  1371. }
  1372. break;
  1373. case CommandBuffer::CreateFrameBuffer:
  1374. {
  1375. FrameBufferHandle handle;
  1376. _cmdbuf.read(handle);
  1377. uint8_t num;
  1378. _cmdbuf.read(num);
  1379. TextureHandle textureHandles[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  1380. for (uint32_t ii = 0; ii < num; ++ii)
  1381. {
  1382. _cmdbuf.read(textureHandles[ii]);
  1383. }
  1384. m_renderCtx->createFrameBuffer(handle, num, textureHandles);
  1385. }
  1386. break;
  1387. case CommandBuffer::DestroyFrameBuffer:
  1388. {
  1389. FrameBufferHandle handle;
  1390. _cmdbuf.read(handle);
  1391. m_renderCtx->destroyFrameBuffer(handle);
  1392. }
  1393. break;
  1394. case CommandBuffer::CreateUniform:
  1395. {
  1396. UniformHandle handle;
  1397. _cmdbuf.read(handle);
  1398. UniformType::Enum type;
  1399. _cmdbuf.read(type);
  1400. uint16_t num;
  1401. _cmdbuf.read(num);
  1402. uint8_t len;
  1403. _cmdbuf.read(len);
  1404. const char* name = (const char*)_cmdbuf.skip(len);
  1405. m_renderCtx->createUniform(handle, type, num, name);
  1406. }
  1407. break;
  1408. case CommandBuffer::DestroyUniform:
  1409. {
  1410. UniformHandle handle;
  1411. _cmdbuf.read(handle);
  1412. m_renderCtx->destroyUniform(handle);
  1413. }
  1414. break;
  1415. case CommandBuffer::SaveScreenShot:
  1416. {
  1417. uint16_t len;
  1418. _cmdbuf.read(len);
  1419. const char* filePath = (const char*)_cmdbuf.skip(len);
  1420. m_renderCtx->saveScreenShot(filePath);
  1421. }
  1422. break;
  1423. case CommandBuffer::UpdateViewName:
  1424. {
  1425. uint8_t id;
  1426. _cmdbuf.read(id);
  1427. uint16_t len;
  1428. _cmdbuf.read(len);
  1429. const char* name = (const char*)_cmdbuf.skip(len);
  1430. m_renderCtx->updateViewName(id, name);
  1431. }
  1432. break;
  1433. case CommandBuffer::End:
  1434. end = true;
  1435. break;
  1436. default:
  1437. BX_CHECK(false, "Invalid command: %d", command);
  1438. break;
  1439. }
  1440. } while (!end);
  1441. flushTextureUpdateBatch(_cmdbuf);
  1442. }
  1443. uint8_t getSupportedRenderers(RendererType::Enum _enum[RendererType::Count])
  1444. {
  1445. uint8_t num = 0;
  1446. for (uint8_t ii = 0; ii < uint8_t(RendererType::Count); ++ii)
  1447. {
  1448. if (s_rendererCreator[ii].supported)
  1449. {
  1450. _enum[num++] = RendererType::Enum(ii);
  1451. }
  1452. }
  1453. return num;
  1454. }
  1455. const char* getRendererName(RendererType::Enum _type)
  1456. {
  1457. BX_CHECK(_type < RendererType::Count, "Invalid renderer type %d.", _type);
  1458. return s_rendererCreator[_type].name;
  1459. }
  1460. void init(RendererType::Enum _type, CallbackI* _callback, bx::ReallocatorI* _allocator)
  1461. {
  1462. BX_TRACE("Init...");
  1463. memset(&g_caps, 0, sizeof(g_caps) );
  1464. g_caps.supported = 0
  1465. | (BGFX_CONFIG_MULTITHREADED ? BGFX_CAPS_RENDERER_MULTITHREADED : 0)
  1466. ;
  1467. g_caps.emulated = 0;
  1468. g_caps.maxDrawCalls = BGFX_CONFIG_MAX_DRAW_CALLS;
  1469. g_caps.maxFBAttachments = 1;
  1470. if (NULL != _allocator)
  1471. {
  1472. g_allocator = _allocator;
  1473. }
  1474. else
  1475. {
  1476. bx::CrtAllocator allocator;
  1477. g_allocator =
  1478. s_allocatorStub = BX_NEW(&allocator, AllocatorStub);
  1479. }
  1480. if (NULL != _callback)
  1481. {
  1482. g_callback = _callback;
  1483. }
  1484. else
  1485. {
  1486. g_callback =
  1487. s_callbackStub = BX_NEW(g_allocator, CallbackStub);
  1488. }
  1489. s_threadIndex = BGFX_MAIN_THREAD_MAGIC;
  1490. s_ctx = BX_ALIGNED_NEW(g_allocator, Context, 16);
  1491. s_ctx->init(_type);
  1492. BX_TRACE("Init complete.");
  1493. }
  1494. void shutdown()
  1495. {
  1496. BX_TRACE("Shutdown...");
  1497. BGFX_CHECK_MAIN_THREAD();
  1498. Context* ctx = s_ctx; // it's going to be NULLd inside shutdown.
  1499. ctx->shutdown();
  1500. BX_ALIGNED_DELETE(g_allocator, ctx, 16);
  1501. if (NULL != s_callbackStub)
  1502. {
  1503. BX_DELETE(g_allocator, s_callbackStub);
  1504. s_callbackStub = NULL;
  1505. }
  1506. if (NULL != s_allocatorStub)
  1507. {
  1508. s_allocatorStub->checkLeaks();
  1509. bx::CrtAllocator allocator;
  1510. BX_DELETE(&allocator, s_allocatorStub);
  1511. s_allocatorStub = NULL;
  1512. }
  1513. s_threadIndex = 0;
  1514. g_callback = NULL;
  1515. g_allocator = NULL;
  1516. BX_TRACE("Shutdown complete.");
  1517. }
  1518. void reset(uint32_t _width, uint32_t _height, uint32_t _flags)
  1519. {
  1520. BGFX_CHECK_MAIN_THREAD();
  1521. s_ctx->reset(_width, _height, _flags);
  1522. }
  1523. uint32_t frame()
  1524. {
  1525. BGFX_CHECK_MAIN_THREAD();
  1526. return s_ctx->frame();
  1527. }
  1528. const Caps* getCaps()
  1529. {
  1530. return &g_caps;
  1531. }
  1532. RendererType::Enum getRendererType()
  1533. {
  1534. return g_caps.rendererType;
  1535. }
  1536. const Memory* alloc(uint32_t _size)
  1537. {
  1538. Memory* mem = (Memory*)BX_ALLOC(g_allocator, sizeof(Memory) + _size);
  1539. mem->size = _size;
  1540. mem->data = (uint8_t*)mem + sizeof(Memory);
  1541. return mem;
  1542. }
  1543. const Memory* copy(const void* _data, uint32_t _size)
  1544. {
  1545. const Memory* mem = alloc(_size);
  1546. memcpy(mem->data, _data, _size);
  1547. return mem;
  1548. }
  1549. const Memory* makeRef(const void* _data, uint32_t _size)
  1550. {
  1551. Memory* mem = (Memory*)BX_ALLOC(g_allocator, sizeof(Memory) );
  1552. mem->size = _size;
  1553. mem->data = (uint8_t*)_data;
  1554. return mem;
  1555. }
  1556. void release(const Memory* _mem)
  1557. {
  1558. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1559. BX_FREE(g_allocator, const_cast<Memory*>(_mem) );
  1560. }
  1561. void setDebug(uint32_t _debug)
  1562. {
  1563. BGFX_CHECK_MAIN_THREAD();
  1564. s_ctx->setDebug(_debug);
  1565. }
  1566. void dbgTextClear(uint8_t _attr, bool _small)
  1567. {
  1568. BGFX_CHECK_MAIN_THREAD();
  1569. s_ctx->dbgTextClear(_attr, _small);
  1570. }
  1571. void dbgTextPrintf(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, ...)
  1572. {
  1573. BGFX_CHECK_MAIN_THREAD();
  1574. va_list argList;
  1575. va_start(argList, _format);
  1576. s_ctx->dbgTextPrintfVargs(_x, _y, _attr, _format, argList);
  1577. va_end(argList);
  1578. }
  1579. IndexBufferHandle createIndexBuffer(const Memory* _mem)
  1580. {
  1581. BGFX_CHECK_MAIN_THREAD();
  1582. return s_ctx->createIndexBuffer(_mem);
  1583. }
  1584. void destroyIndexBuffer(IndexBufferHandle _handle)
  1585. {
  1586. BGFX_CHECK_MAIN_THREAD();
  1587. s_ctx->destroyIndexBuffer(_handle);
  1588. }
  1589. VertexBufferHandle createVertexBuffer(const Memory* _mem, const VertexDecl& _decl)
  1590. {
  1591. BGFX_CHECK_MAIN_THREAD();
  1592. BX_CHECK(0 != _decl.m_stride, "Invalid VertexDecl.");
  1593. return s_ctx->createVertexBuffer(_mem, _decl);
  1594. }
  1595. void destroyVertexBuffer(VertexBufferHandle _handle)
  1596. {
  1597. BGFX_CHECK_MAIN_THREAD();
  1598. s_ctx->destroyVertexBuffer(_handle);
  1599. }
  1600. DynamicIndexBufferHandle createDynamicIndexBuffer(uint32_t _num)
  1601. {
  1602. BGFX_CHECK_MAIN_THREAD();
  1603. return s_ctx->createDynamicIndexBuffer(_num);
  1604. }
  1605. DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem)
  1606. {
  1607. BGFX_CHECK_MAIN_THREAD();
  1608. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1609. return s_ctx->createDynamicIndexBuffer(_mem);
  1610. }
  1611. void updateDynamicIndexBuffer(DynamicIndexBufferHandle _handle, const Memory* _mem)
  1612. {
  1613. BGFX_CHECK_MAIN_THREAD();
  1614. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1615. s_ctx->updateDynamicIndexBuffer(_handle, _mem);
  1616. }
  1617. void destroyDynamicIndexBuffer(DynamicIndexBufferHandle _handle)
  1618. {
  1619. BGFX_CHECK_MAIN_THREAD();
  1620. s_ctx->destroyDynamicIndexBuffer(_handle);
  1621. }
  1622. DynamicVertexBufferHandle createDynamicVertexBuffer(uint16_t _num, const VertexDecl& _decl)
  1623. {
  1624. BGFX_CHECK_MAIN_THREAD();
  1625. BX_CHECK(0 != _decl.m_stride, "Invalid VertexDecl.");
  1626. return s_ctx->createDynamicVertexBuffer(_num, _decl);
  1627. }
  1628. DynamicVertexBufferHandle createDynamicVertexBuffer(const Memory* _mem, const VertexDecl& _decl)
  1629. {
  1630. BGFX_CHECK_MAIN_THREAD();
  1631. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1632. BX_CHECK(0 != _decl.m_stride, "Invalid VertexDecl.");
  1633. return s_ctx->createDynamicVertexBuffer(_mem, _decl);
  1634. }
  1635. void updateDynamicVertexBuffer(DynamicVertexBufferHandle _handle, const Memory* _mem)
  1636. {
  1637. BGFX_CHECK_MAIN_THREAD();
  1638. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1639. s_ctx->updateDynamicVertexBuffer(_handle, _mem);
  1640. }
  1641. void destroyDynamicVertexBuffer(DynamicVertexBufferHandle _handle)
  1642. {
  1643. BGFX_CHECK_MAIN_THREAD();
  1644. s_ctx->destroyDynamicVertexBuffer(_handle);
  1645. }
  1646. bool checkAvailTransientIndexBuffer(uint32_t _num)
  1647. {
  1648. BGFX_CHECK_MAIN_THREAD();
  1649. BX_CHECK(0 < _num, "Requesting 0 indices.");
  1650. return s_ctx->checkAvailTransientIndexBuffer(_num);
  1651. }
  1652. bool checkAvailTransientVertexBuffer(uint32_t _num, const VertexDecl& _decl)
  1653. {
  1654. BGFX_CHECK_MAIN_THREAD();
  1655. BX_CHECK(0 < _num, "Requesting 0 vertices.");
  1656. BX_CHECK(0 != _decl.m_stride, "Invalid VertexDecl.");
  1657. return s_ctx->checkAvailTransientVertexBuffer(_num, _decl.m_stride);
  1658. }
  1659. bool checkAvailInstanceDataBuffer(uint32_t _num, uint16_t _stride)
  1660. {
  1661. BGFX_CHECK_MAIN_THREAD();
  1662. BX_CHECK(0 < _num, "Requesting 0 instances.");
  1663. return s_ctx->checkAvailTransientVertexBuffer(_num, _stride);
  1664. }
  1665. bool checkAvailTransientBuffers(uint32_t _numVertices, const VertexDecl& _decl, uint32_t _numIndices)
  1666. {
  1667. BX_CHECK(0 != _decl.m_stride, "Invalid VertexDecl.");
  1668. return checkAvailTransientVertexBuffer(_numVertices, _decl)
  1669. && checkAvailTransientIndexBuffer(_numIndices)
  1670. ;
  1671. }
  1672. void allocTransientIndexBuffer(TransientIndexBuffer* _tib, uint32_t _num)
  1673. {
  1674. BGFX_CHECK_MAIN_THREAD();
  1675. BX_CHECK(NULL != _tib, "_tib can't be NULL");
  1676. BX_CHECK(0 < _num, "Requesting 0 indices.");
  1677. return s_ctx->allocTransientIndexBuffer(_tib, _num);
  1678. }
  1679. void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint32_t _num, const VertexDecl& _decl)
  1680. {
  1681. BGFX_CHECK_MAIN_THREAD();
  1682. BX_CHECK(NULL != _tvb, "_tvb can't be NULL");
  1683. BX_CHECK(0 < _num, "Requesting 0 vertices.");
  1684. BX_CHECK(UINT16_MAX >= _num, "Requesting %d vertices (max: %d).", _num, UINT16_MAX);
  1685. BX_CHECK(0 != _decl.m_stride, "Invalid VertexDecl.");
  1686. return s_ctx->allocTransientVertexBuffer(_tvb, _num, _decl);
  1687. }
  1688. bool allocTransientBuffers(bgfx::TransientVertexBuffer* _tvb, const bgfx::VertexDecl& _decl, uint16_t _numVertices, bgfx::TransientIndexBuffer* _tib, uint16_t _numIndices)
  1689. {
  1690. if (checkAvailTransientBuffers(_numVertices, _decl, _numIndices) )
  1691. {
  1692. allocTransientVertexBuffer(_tvb, _numVertices, _decl);
  1693. allocTransientIndexBuffer(_tib, _numIndices);
  1694. return true;
  1695. }
  1696. return false;
  1697. }
  1698. const InstanceDataBuffer* allocInstanceDataBuffer(uint32_t _num, uint16_t _stride)
  1699. {
  1700. BGFX_CHECK_MAIN_THREAD();
  1701. BX_CHECK(0 != (g_caps.supported & BGFX_CAPS_INSTANCING), "Instancing is not supported! Use bgfx::getCaps to check backend renderer capabilities.");
  1702. BX_CHECK(0 < _num, "Requesting 0 instanced data vertices.");
  1703. return s_ctx->allocInstanceDataBuffer(_num, _stride);
  1704. }
  1705. ShaderHandle createShader(const Memory* _mem)
  1706. {
  1707. BGFX_CHECK_MAIN_THREAD();
  1708. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1709. return s_ctx->createShader(_mem);
  1710. }
  1711. uint16_t getShaderUniforms(ShaderHandle _handle, UniformHandle* _uniforms, uint16_t _max)
  1712. {
  1713. BGFX_CHECK_MAIN_THREAD();
  1714. return s_ctx->getShaderUniforms(_handle, _uniforms, _max);
  1715. }
  1716. void destroyShader(ShaderHandle _handle)
  1717. {
  1718. BGFX_CHECK_MAIN_THREAD();
  1719. s_ctx->destroyShader(_handle);
  1720. }
  1721. ProgramHandle createProgram(ShaderHandle _vsh, ShaderHandle _fsh, bool _destroyShaders)
  1722. {
  1723. BGFX_CHECK_MAIN_THREAD();
  1724. ProgramHandle handle = s_ctx->createProgram(_vsh, _fsh);
  1725. if (_destroyShaders)
  1726. {
  1727. destroyShader(_vsh);
  1728. destroyShader(_fsh);
  1729. }
  1730. return handle;
  1731. }
  1732. void destroyProgram(ProgramHandle _handle)
  1733. {
  1734. BGFX_CHECK_MAIN_THREAD();
  1735. s_ctx->destroyProgram(_handle);
  1736. }
  1737. void calcTextureSize(TextureInfo& _info, uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, TextureFormat::Enum _format)
  1738. {
  1739. _width = bx::uint32_max(1, _width);
  1740. _height = bx::uint32_max(1, _height);
  1741. _depth = bx::uint32_max(1, _depth);
  1742. uint32_t width = _width;
  1743. uint32_t height = _height;
  1744. uint32_t depth = _depth;
  1745. uint32_t bpp = getBitsPerPixel(_format);
  1746. uint32_t size = 0;
  1747. for (uint32_t lod = 0; lod < _numMips; ++lod)
  1748. {
  1749. width = bx::uint32_max(1, width);
  1750. height = bx::uint32_max(1, height);
  1751. depth = bx::uint32_max(1, depth);
  1752. size += width*height*depth*bpp/8;
  1753. width >>= 1;
  1754. height >>= 1;
  1755. depth >>= 1;
  1756. }
  1757. _info.format = _format;
  1758. _info.storageSize = size;
  1759. _info.width = _width;
  1760. _info.height = _height;
  1761. _info.depth = _depth;
  1762. _info.numMips = _numMips;
  1763. _info.bitsPerPixel = bpp;
  1764. }
  1765. TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint8_t _skip, TextureInfo* _info)
  1766. {
  1767. BGFX_CHECK_MAIN_THREAD();
  1768. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1769. return s_ctx->createTexture(_mem, _flags, _skip, _info);
  1770. }
  1771. TextureHandle createTexture2D(uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
  1772. {
  1773. BGFX_CHECK_MAIN_THREAD();
  1774. _numMips = bx::uint32_max(1, _numMips);
  1775. if (BX_ENABLED(BGFX_CONFIG_DEBUG)
  1776. && NULL != _mem)
  1777. {
  1778. TextureInfo ti;
  1779. calcTextureSize(ti, _width, _height, 1, _numMips, _format);
  1780. BX_CHECK(ti.storageSize == _mem->size
  1781. , "createTexture2D: Texture storage size doesn't match passed memory size (storage size: %d, memory size: %d)"
  1782. , ti.storageSize
  1783. , _mem->size
  1784. );
  1785. }
  1786. uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
  1787. const Memory* mem = alloc(size);
  1788. bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
  1789. uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
  1790. bx::write(&writer, magic);
  1791. TextureCreate tc;
  1792. tc.m_flags = _flags;
  1793. tc.m_width = _width;
  1794. tc.m_height = _height;
  1795. tc.m_sides = 0;
  1796. tc.m_depth = 0;
  1797. tc.m_numMips = _numMips;
  1798. tc.m_format = uint8_t(_format);
  1799. tc.m_cubeMap = false;
  1800. tc.m_mem = _mem;
  1801. bx::write(&writer, tc);
  1802. return s_ctx->createTexture(mem, _flags, 0, NULL);
  1803. }
  1804. TextureHandle createTexture3D(uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
  1805. {
  1806. BGFX_CHECK_MAIN_THREAD();
  1807. BX_CHECK(0 != (g_caps.supported & BGFX_CAPS_TEXTURE_3D), "Texture3D is not supported! Use bgfx::getCaps to check backend renderer capabilities.");
  1808. _numMips = bx::uint32_max(1, _numMips);
  1809. if (BX_ENABLED(BGFX_CONFIG_DEBUG)
  1810. && NULL != _mem)
  1811. {
  1812. TextureInfo ti;
  1813. calcTextureSize(ti, _width, _height, _depth, _numMips, _format);
  1814. BX_CHECK(ti.storageSize == _mem->size
  1815. , "createTexture3D: Texture storage size doesn't match passed memory size (storage size: %d, memory size: %d)"
  1816. , ti.storageSize
  1817. , _mem->size
  1818. );
  1819. }
  1820. uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
  1821. const Memory* mem = alloc(size);
  1822. bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
  1823. uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
  1824. bx::write(&writer, magic);
  1825. TextureCreate tc;
  1826. tc.m_flags = _flags;
  1827. tc.m_width = _width;
  1828. tc.m_height = _height;
  1829. tc.m_sides = 0;
  1830. tc.m_depth = _depth;
  1831. tc.m_numMips = _numMips;
  1832. tc.m_format = uint8_t(_format);
  1833. tc.m_cubeMap = false;
  1834. tc.m_mem = _mem;
  1835. bx::write(&writer, tc);
  1836. return s_ctx->createTexture(mem, _flags, 0, NULL);
  1837. }
  1838. TextureHandle createTextureCube(uint16_t _size, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
  1839. {
  1840. BGFX_CHECK_MAIN_THREAD();
  1841. _numMips = bx::uint32_max(1, _numMips);
  1842. if (BX_ENABLED(BGFX_CONFIG_DEBUG)
  1843. && NULL != _mem)
  1844. {
  1845. TextureInfo ti;
  1846. calcTextureSize(ti, _size, _size, 1, _numMips, _format);
  1847. BX_CHECK(ti.storageSize*6 == _mem->size
  1848. , "createTextureCube: Texture storage size doesn't match passed memory size (storage size: %d, memory size: %d)"
  1849. , ti.storageSize*6
  1850. , _mem->size
  1851. );
  1852. }
  1853. uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
  1854. const Memory* mem = alloc(size);
  1855. bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
  1856. uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
  1857. bx::write(&writer, magic);
  1858. TextureCreate tc;
  1859. tc.m_flags = _flags;
  1860. tc.m_width = _size;
  1861. tc.m_height = _size;
  1862. tc.m_sides = 6;
  1863. tc.m_depth = 0;
  1864. tc.m_numMips = _numMips;
  1865. tc.m_format = uint8_t(_format);
  1866. tc.m_cubeMap = true;
  1867. tc.m_mem = _mem;
  1868. bx::write(&writer, tc);
  1869. return s_ctx->createTexture(mem, _flags, 0, NULL);
  1870. }
  1871. void destroyTexture(TextureHandle _handle)
  1872. {
  1873. BGFX_CHECK_MAIN_THREAD();
  1874. s_ctx->destroyTexture(_handle);
  1875. }
  1876. 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)
  1877. {
  1878. BGFX_CHECK_MAIN_THREAD();
  1879. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1880. if (_width == 0
  1881. || _height == 0)
  1882. {
  1883. release(_mem);
  1884. }
  1885. else
  1886. {
  1887. s_ctx->updateTexture(_handle, 0, _mip, _x, _y, 0, _width, _height, 1, _pitch, _mem);
  1888. }
  1889. }
  1890. 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)
  1891. {
  1892. BGFX_CHECK_MAIN_THREAD();
  1893. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1894. if (_width == 0
  1895. || _height == 0
  1896. || _depth == 0)
  1897. {
  1898. release(_mem);
  1899. }
  1900. else
  1901. {
  1902. s_ctx->updateTexture(_handle, 0, _mip, _x, _y, _z, _width, _height, _depth, UINT16_MAX, _mem);
  1903. }
  1904. }
  1905. 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)
  1906. {
  1907. BGFX_CHECK_MAIN_THREAD();
  1908. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1909. BX_CHECK(_side <= 5, "Invalid side %d.", _side);
  1910. if (_width == 0
  1911. || _height == 0)
  1912. {
  1913. release(_mem);
  1914. }
  1915. else
  1916. {
  1917. s_ctx->updateTexture(_handle, _side, _mip, _x, _y, 0, _width, _height, 1, _pitch, _mem);
  1918. }
  1919. }
  1920. FrameBufferHandle createFrameBuffer(uint16_t _width, uint16_t _height, TextureFormat::Enum _format, uint32_t _textureFlags)
  1921. {
  1922. _textureFlags |= _textureFlags&BGFX_TEXTURE_RT_MSAA_MASK ? 0 : BGFX_TEXTURE_RT;
  1923. TextureHandle th = createTexture2D(_width, _height, 1, _format, _textureFlags);
  1924. return createFrameBuffer(1, &th, true);
  1925. }
  1926. FrameBufferHandle createFrameBuffer(uint8_t _num, TextureHandle* _handles, bool _destroyTextures)
  1927. {
  1928. BGFX_CHECK_MAIN_THREAD();
  1929. BX_CHECK(NULL != _handles, "_handles can't be NULL");
  1930. FrameBufferHandle handle = s_ctx->createFrameBuffer(_num, _handles);
  1931. if (_destroyTextures)
  1932. {
  1933. for (uint32_t ii = 0; ii < _num; ++ii)
  1934. {
  1935. destroyTexture(_handles[ii]);
  1936. }
  1937. }
  1938. return handle;
  1939. }
  1940. void destroyFrameBuffer(FrameBufferHandle _handle)
  1941. {
  1942. BGFX_CHECK_MAIN_THREAD();
  1943. s_ctx->destroyFrameBuffer(_handle);
  1944. }
  1945. UniformHandle createUniform(const char* _name, UniformType::Enum _type, uint16_t _num)
  1946. {
  1947. BGFX_CHECK_MAIN_THREAD();
  1948. return s_ctx->createUniform(_name, _type, _num);
  1949. }
  1950. void destroyUniform(UniformHandle _handle)
  1951. {
  1952. BGFX_CHECK_MAIN_THREAD();
  1953. s_ctx->destroyUniform(_handle);
  1954. }
  1955. void setViewName(uint8_t _id, const char* _name)
  1956. {
  1957. BGFX_CHECK_MAIN_THREAD();
  1958. s_ctx->setViewName(_id, _name);
  1959. }
  1960. void setViewRect(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  1961. {
  1962. BGFX_CHECK_MAIN_THREAD();
  1963. s_ctx->setViewRect(_id, _x, _y, _width, _height);
  1964. }
  1965. void setViewRectMask(uint32_t _viewMask, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  1966. {
  1967. BGFX_CHECK_MAIN_THREAD();
  1968. s_ctx->setViewRectMask(_viewMask, _x, _y, _width, _height);
  1969. }
  1970. void setViewScissor(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  1971. {
  1972. BGFX_CHECK_MAIN_THREAD();
  1973. s_ctx->setViewScissor(_id, _x, _y, _width, _height);
  1974. }
  1975. void setViewScissorMask(uint32_t _viewMask, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  1976. {
  1977. BGFX_CHECK_MAIN_THREAD();
  1978. s_ctx->setViewScissorMask(_viewMask, _x, _y, _width, _height);
  1979. }
  1980. void setViewClear(uint8_t _id, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
  1981. {
  1982. BGFX_CHECK_MAIN_THREAD();
  1983. s_ctx->setViewClear(_id, _flags, _rgba, _depth, _stencil);
  1984. }
  1985. void setViewClearMask(uint32_t _viewMask, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
  1986. {
  1987. BGFX_CHECK_MAIN_THREAD();
  1988. s_ctx->setViewClearMask(_viewMask, _flags, _rgba, _depth, _stencil);
  1989. }
  1990. void setViewSeq(uint8_t _id, bool _enabled)
  1991. {
  1992. BGFX_CHECK_MAIN_THREAD();
  1993. s_ctx->setViewSeq(_id, _enabled);
  1994. }
  1995. void setViewSeqMask(uint32_t _viewMask, bool _enabled)
  1996. {
  1997. BGFX_CHECK_MAIN_THREAD();
  1998. s_ctx->setViewSeqMask(_viewMask, _enabled);
  1999. }
  2000. void setViewFrameBuffer(uint8_t _id, FrameBufferHandle _handle)
  2001. {
  2002. BGFX_CHECK_MAIN_THREAD();
  2003. s_ctx->setViewFrameBuffer(_id, _handle);
  2004. }
  2005. void setViewFrameBufferMask(uint32_t _mask, FrameBufferHandle _handle)
  2006. {
  2007. BGFX_CHECK_MAIN_THREAD();
  2008. s_ctx->setViewFrameBufferMask(_mask, _handle);
  2009. }
  2010. void setViewTransform(uint8_t _id, const void* _view, const void* _proj, uint8_t _other)
  2011. {
  2012. BGFX_CHECK_MAIN_THREAD();
  2013. s_ctx->setViewTransform(_id, _view, _proj, _other);
  2014. }
  2015. void setViewTransformMask(uint32_t _viewMask, const void* _view, const void* _proj, uint8_t _other)
  2016. {
  2017. BGFX_CHECK_MAIN_THREAD();
  2018. s_ctx->setViewTransformMask(_viewMask, _view, _proj, _other);
  2019. }
  2020. void setMarker(const char* _marker)
  2021. {
  2022. BGFX_CHECK_MAIN_THREAD();
  2023. s_ctx->setMarker(_marker);
  2024. }
  2025. void setState(uint64_t _state, uint32_t _rgba)
  2026. {
  2027. BGFX_CHECK_MAIN_THREAD();
  2028. s_ctx->setState(_state, _rgba);
  2029. }
  2030. void setStencil(uint32_t _fstencil, uint32_t _bstencil)
  2031. {
  2032. BGFX_CHECK_MAIN_THREAD();
  2033. s_ctx->setStencil(_fstencil, _bstencil);
  2034. }
  2035. uint16_t setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  2036. {
  2037. BGFX_CHECK_MAIN_THREAD();
  2038. return s_ctx->setScissor(_x, _y, _width, _height);
  2039. }
  2040. void setScissor(uint16_t _cache)
  2041. {
  2042. BGFX_CHECK_MAIN_THREAD();
  2043. s_ctx->setScissor(_cache);
  2044. }
  2045. uint32_t setTransform(const void* _mtx, uint16_t _num)
  2046. {
  2047. BGFX_CHECK_MAIN_THREAD();
  2048. return s_ctx->setTransform(_mtx, _num);
  2049. }
  2050. void setTransform(uint32_t _cache, uint16_t _num)
  2051. {
  2052. BGFX_CHECK_MAIN_THREAD();
  2053. s_ctx->setTransform(_cache, _num);
  2054. }
  2055. void setUniform(UniformHandle _handle, const void* _value, uint16_t _num)
  2056. {
  2057. BGFX_CHECK_MAIN_THREAD();
  2058. s_ctx->setUniform(_handle, _value, _num);
  2059. }
  2060. void setIndexBuffer(IndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices)
  2061. {
  2062. BGFX_CHECK_MAIN_THREAD();
  2063. s_ctx->setIndexBuffer(_handle, _firstIndex, _numIndices);
  2064. }
  2065. void setIndexBuffer(DynamicIndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices)
  2066. {
  2067. BGFX_CHECK_MAIN_THREAD();
  2068. s_ctx->setIndexBuffer(_handle, _firstIndex, _numIndices);
  2069. }
  2070. void setIndexBuffer(const TransientIndexBuffer* _tib)
  2071. {
  2072. setIndexBuffer(_tib, 0, UINT32_MAX);
  2073. }
  2074. void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _firstIndex, uint32_t _numIndices)
  2075. {
  2076. BGFX_CHECK_MAIN_THREAD();
  2077. BX_CHECK(NULL != _tib, "_tib can't be NULL");
  2078. uint32_t numIndices = bx::uint32_min(_numIndices, _tib->size/2);
  2079. s_ctx->setIndexBuffer(_tib, _tib->startIndex + _firstIndex, numIndices);
  2080. }
  2081. void setVertexBuffer(VertexBufferHandle _handle)
  2082. {
  2083. setVertexBuffer(_handle, 0, UINT32_MAX);
  2084. }
  2085. void setVertexBuffer(VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _numVertices)
  2086. {
  2087. BGFX_CHECK_MAIN_THREAD();
  2088. s_ctx->setVertexBuffer(_handle, _startVertex, _numVertices);
  2089. }
  2090. void setVertexBuffer(DynamicVertexBufferHandle _handle, uint32_t _numVertices)
  2091. {
  2092. BGFX_CHECK_MAIN_THREAD();
  2093. s_ctx->setVertexBuffer(_handle, _numVertices);
  2094. }
  2095. void setVertexBuffer(const TransientVertexBuffer* _tvb)
  2096. {
  2097. setVertexBuffer(_tvb, 0, UINT32_MAX);
  2098. }
  2099. void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _startVertex, uint32_t _numVertices)
  2100. {
  2101. BGFX_CHECK_MAIN_THREAD();
  2102. BX_CHECK(NULL != _tvb, "_tvb can't be NULL");
  2103. s_ctx->setVertexBuffer(_tvb, _tvb->startVertex + _startVertex, _numVertices);
  2104. }
  2105. void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint16_t _num)
  2106. {
  2107. BGFX_CHECK_MAIN_THREAD();
  2108. s_ctx->setInstanceDataBuffer(_idb, _num);
  2109. }
  2110. void setProgram(ProgramHandle _handle)
  2111. {
  2112. BGFX_CHECK_MAIN_THREAD();
  2113. s_ctx->setProgram(_handle);
  2114. }
  2115. void setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint32_t _flags)
  2116. {
  2117. BGFX_CHECK_MAIN_THREAD();
  2118. s_ctx->setTexture(_stage, _sampler, _handle, _flags);
  2119. }
  2120. void setTexture(uint8_t _stage, UniformHandle _sampler, FrameBufferHandle _handle, uint8_t _attachment, uint32_t _flags)
  2121. {
  2122. BGFX_CHECK_MAIN_THREAD();
  2123. s_ctx->setTexture(_stage, _sampler, _handle, _attachment, _flags);
  2124. }
  2125. uint32_t submit(uint8_t _id, int32_t _depth)
  2126. {
  2127. BGFX_CHECK_MAIN_THREAD();
  2128. return s_ctx->submit(_id, _depth);
  2129. }
  2130. uint32_t submitMask(uint32_t _viewMask, int32_t _depth)
  2131. {
  2132. BGFX_CHECK_MAIN_THREAD();
  2133. return s_ctx->submitMask(_viewMask, _depth);
  2134. }
  2135. void discard()
  2136. {
  2137. BGFX_CHECK_MAIN_THREAD();
  2138. s_ctx->discard();
  2139. }
  2140. void saveScreenShot(const char* _filePath)
  2141. {
  2142. BGFX_CHECK_MAIN_THREAD();
  2143. s_ctx->saveScreenShot(_filePath);
  2144. }
  2145. }