bgfx.cpp 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510
  1. /*
  2. * Copyright 2011-2013 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include "bgfx_p.h"
  6. #if BGFX_CONFIG_USE_TINYSTL
  7. namespace tinystl
  8. {
  9. void* bgfx_allocator::static_allocate(size_t _bytes)
  10. {
  11. return bgfx::g_realloc(NULL, _bytes);
  12. }
  13. void bgfx_allocator::static_deallocate(void* _ptr, size_t /*_bytes*/)
  14. {
  15. bgfx::g_free(_ptr);
  16. }
  17. } // namespace tinystl
  18. #endif // BGFX_CONFIG_USE_TINYSTL
  19. namespace bgfx
  20. {
  21. #define BGFX_MAIN_THREAD_MAGIC 0x78666762
  22. #if BGFX_CONFIG_MULTITHREADED && !BX_PLATFORM_OSX && !BX_PLATFORM_IOS
  23. # define BGFX_CHECK_MAIN_THREAD() BX_CHECK(BGFX_MAIN_THREAD_MAGIC == s_threadIndex, "Must be called from main thread.")
  24. # define BGFX_CHECK_RENDER_THREAD() BX_CHECK(BGFX_MAIN_THREAD_MAGIC != s_threadIndex, "Must be called from render thread.")
  25. #else
  26. # define BGFX_CHECK_MAIN_THREAD()
  27. # define BGFX_CHECK_RENDER_THREAD()
  28. #endif // BGFX_CONFIG_MULTITHREADED && !BX_PLATFORM_OSX && !BX_PLATFORM_IOS
  29. #if BX_PLATFORM_ANDROID
  30. ::ANativeWindow* g_bgfxAndroidWindow = NULL;
  31. void androidSetWindow(::ANativeWindow* _window)
  32. {
  33. g_bgfxAndroidWindow = _window;
  34. }
  35. #elif BX_PLATFORM_IOS
  36. void* g_bgfxEaglLayer = NULL;
  37. void iosSetEaglLayer(void* _layer)
  38. {
  39. g_bgfxEaglLayer = _layer;
  40. }
  41. #elif BX_PLATFORM_OSX
  42. void* g_bgfxNSWindow = NULL;
  43. void osxSetNSWindow(void* _window)
  44. {
  45. g_bgfxNSWindow = _window;
  46. }
  47. #elif BX_PLATFORM_WINDOWS
  48. ::HWND g_bgfxHwnd = NULL;
  49. void winSetHwnd(::HWND _window)
  50. {
  51. g_bgfxHwnd = _window;
  52. }
  53. #endif // BX_PLATFORM_*
  54. struct CallbackStub : public CallbackI
  55. {
  56. virtual ~CallbackStub()
  57. {
  58. }
  59. virtual void fatal(Fatal::Enum _code, const char* _str) BX_OVERRIDE
  60. {
  61. if (Fatal::DebugCheck == _code)
  62. {
  63. bx::debugBreak();
  64. }
  65. else
  66. {
  67. BX_TRACE("0x%08x: %s", _code, _str);
  68. BX_UNUSED(_code, _str);
  69. abort();
  70. }
  71. }
  72. virtual uint32_t cacheReadSize(uint64_t /*_id*/) BX_OVERRIDE
  73. {
  74. return 0;
  75. }
  76. virtual bool cacheRead(uint64_t /*_id*/, void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
  77. {
  78. return false;
  79. }
  80. virtual void cacheWrite(uint64_t /*_id*/, const void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
  81. {
  82. }
  83. 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
  84. {
  85. saveTga(_filePath, _width, _height, _pitch, _data, false, _yflip);
  86. }
  87. virtual void captureBegin(uint32_t /*_width*/, uint32_t /*_height*/, uint32_t /*_pitch*/, TextureFormat::Enum /*_format*/, bool /*_yflip*/) BX_OVERRIDE
  88. {
  89. BX_TRACE("Warning: using capture without callback (a.k.a. pointless).");
  90. }
  91. virtual void captureEnd() BX_OVERRIDE
  92. {
  93. }
  94. virtual void captureFrame(const void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
  95. {
  96. }
  97. };
  98. static CallbackStub s_callbackStub;
  99. static void* reallocStub(void* _ptr, size_t _size)
  100. {
  101. void* ptr = ::realloc(_ptr, _size);
  102. BX_CHECK(NULL != ptr, "Out of memory!");
  103. // BX_TRACE("alloc %d, %p", _size, ptr);
  104. return ptr;
  105. }
  106. static void freeStub(void* _ptr)
  107. {
  108. // BX_TRACE("free %p", _ptr);
  109. ::free(_ptr);
  110. }
  111. CallbackI* g_callback = &s_callbackStub;
  112. ReallocFn g_realloc = reallocStub;
  113. FreeFn g_free = freeStub;
  114. static BX_THREAD uint32_t s_threadIndex = 0;
  115. static Context s_ctx;
  116. void fatal(Fatal::Enum _code, const char* _format, ...)
  117. {
  118. char temp[8192];
  119. va_list argList;
  120. va_start(argList, _format);
  121. bx::vsnprintf(temp, sizeof(temp), _format, argList);
  122. va_end(argList);
  123. temp[sizeof(temp)-1] = '\0';
  124. g_callback->fatal(_code, temp);
  125. }
  126. inline void vec4MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat)
  127. {
  128. _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _vec[3] * _mat[12];
  129. _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _vec[3] * _mat[13];
  130. _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _vec[3] * _mat[14];
  131. _result[3] = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _vec[3] * _mat[15];
  132. }
  133. void mtxMul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
  134. {
  135. vec4MulMtx(&_result[ 0], &_a[ 0], _b);
  136. vec4MulMtx(&_result[ 4], &_a[ 4], _b);
  137. vec4MulMtx(&_result[ 8], &_a[ 8], _b);
  138. vec4MulMtx(&_result[12], &_a[12], _b);
  139. }
  140. void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far)
  141. {
  142. const float aa = 2.0f/(_right - _left);
  143. const float bb = 2.0f/(_top - _bottom);
  144. const float cc = 1.0f/(_far - _near);
  145. const float dd = (_left + _right)/(_left - _right);
  146. const float ee = (_top + _bottom)/(_bottom - _top);
  147. const float ff = _near / (_near - _far);
  148. memset(_result, 0, sizeof(float)*16);
  149. _result[0] = aa;
  150. _result[5] = bb;
  151. _result[10] = cc;
  152. _result[12] = dd;
  153. _result[13] = ee;
  154. _result[14] = ff;
  155. _result[15] = 1.0f;
  156. }
  157. void saveTga(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, bool _grayscale, bool _yflip)
  158. {
  159. FILE* file = fopen(_filePath, "wb");
  160. if ( NULL != file )
  161. {
  162. uint8_t type = _grayscale ? 3 : 2;
  163. uint8_t bpp = _grayscale ? 8 : 32;
  164. putc(0, file);
  165. putc(0, file);
  166. putc(type, file);
  167. putc(0, file);
  168. putc(0, file);
  169. putc(0, file);
  170. putc(0, file);
  171. putc(0, file);
  172. putc(0, file);
  173. putc(0, file);
  174. putc(0, file);
  175. putc(0, file);
  176. putc(_width&0xff, file);
  177. putc( (_width>>8)&0xff, file);
  178. putc(_height&0xff, file);
  179. putc( (_height>>8)&0xff, file);
  180. putc(bpp, file);
  181. putc(32, file);
  182. uint32_t dstPitch = _width*bpp/8;
  183. if (_yflip)
  184. {
  185. uint8_t* data = (uint8_t*)_src + _srcPitch*_height - _srcPitch;
  186. for (uint32_t yy = 0; yy < _height; ++yy)
  187. {
  188. fwrite(data, dstPitch, 1, file);
  189. data -= _srcPitch;
  190. }
  191. }
  192. else
  193. {
  194. uint8_t* data = (uint8_t*)_src;
  195. for (uint32_t yy = 0; yy < _height; ++yy)
  196. {
  197. fwrite(data, dstPitch, 1, file);
  198. data += _srcPitch;
  199. }
  200. }
  201. fclose(file);
  202. }
  203. }
  204. #include "charset.h"
  205. void charsetFillTexture(const uint8_t* _charset, uint8_t* _rgba, uint32_t _height, uint32_t _pitch, uint32_t _bpp)
  206. {
  207. for (uint32_t ii = 0; ii < 256; ++ii)
  208. {
  209. uint8_t* pix = &_rgba[ii*8*_bpp];
  210. for (uint32_t yy = 0; yy < _height; ++yy)
  211. {
  212. for (uint32_t xx = 0; xx < 8; ++xx)
  213. {
  214. uint8_t bit = 1<<(7-xx);
  215. memset(&pix[xx*_bpp], _charset[ii*_height+yy]&bit ? 255 : 0, _bpp);
  216. }
  217. pix += _pitch;
  218. }
  219. }
  220. }
  221. static const uint32_t numCharsPerBatch = 1024;
  222. static const uint32_t numBatchVertices = numCharsPerBatch*4;
  223. static const uint32_t numBatchIndices = numCharsPerBatch*6;
  224. void TextVideoMemBlitter::init()
  225. {
  226. BGFX_CHECK_MAIN_THREAD();
  227. m_decl.begin();
  228. m_decl.add(Attrib::Position, 3, AttribType::Float);
  229. m_decl.add(Attrib::Color0, 4, AttribType::Uint8, true);
  230. m_decl.add(Attrib::Color1, 4, AttribType::Uint8, true);
  231. m_decl.add(Attrib::TexCoord0, 2, AttribType::Float);
  232. m_decl.end();
  233. uint16_t width = 2048;
  234. uint16_t height = 24;
  235. uint8_t bpp = 1;
  236. uint32_t pitch = width*bpp;
  237. const Memory* mem;
  238. mem = alloc(pitch*height);
  239. uint8_t* rgba = mem->data;
  240. charsetFillTexture(vga8x8, rgba, 8, pitch, bpp);
  241. charsetFillTexture(vga8x16, &rgba[8*pitch], 16, pitch, bpp);
  242. m_texture = createTexture2D(width, height, 1, TextureFormat::L8
  243. , BGFX_TEXTURE_MIN_POINT
  244. | BGFX_TEXTURE_MAG_POINT
  245. | BGFX_TEXTURE_MIP_POINT
  246. | BGFX_TEXTURE_U_CLAMP
  247. | BGFX_TEXTURE_V_CLAMP
  248. , mem
  249. );
  250. #if BGFX_CONFIG_RENDERER_DIRECT3D9
  251. mem = makeRef(vs_debugfont_dx9, sizeof(vs_debugfont_dx9) );
  252. #elif BGFX_CONFIG_RENDERER_DIRECT3D11
  253. mem = makeRef(vs_debugfont_dx11, sizeof(vs_debugfont_dx11) );
  254. #else
  255. mem = makeRef(vs_debugfont_glsl, sizeof(vs_debugfont_glsl) );
  256. #endif // BGFX_CONFIG_RENDERER_
  257. VertexShaderHandle vsh = createVertexShader(mem);
  258. #if BGFX_CONFIG_RENDERER_DIRECT3D9
  259. mem = makeRef(fs_debugfont_dx9, sizeof(fs_debugfont_dx9) );
  260. #elif BGFX_CONFIG_RENDERER_DIRECT3D11
  261. mem = makeRef(fs_debugfont_dx11, sizeof(fs_debugfont_dx11) );
  262. #else
  263. mem = makeRef(fs_debugfont_glsl, sizeof(fs_debugfont_glsl) );
  264. #endif // BGFX_CONFIG_RENDERER_
  265. FragmentShaderHandle fsh = createFragmentShader(mem);
  266. m_program = createProgram(vsh, fsh);
  267. destroyVertexShader(vsh);
  268. destroyFragmentShader(fsh);
  269. m_vb = s_ctx.createTransientVertexBuffer(numBatchVertices*m_decl.m_stride, &m_decl);
  270. m_ib = s_ctx.createTransientIndexBuffer(numBatchIndices*2);
  271. }
  272. void TextVideoMemBlitter::shutdown()
  273. {
  274. BGFX_CHECK_MAIN_THREAD();
  275. destroyProgram(m_program);
  276. destroyTexture(m_texture);
  277. s_ctx.destroyTransientVertexBuffer(m_vb);
  278. s_ctx.destroyTransientIndexBuffer(m_ib);
  279. }
  280. void TextVideoMemBlitter::blit(const TextVideoMem& _mem)
  281. {
  282. BGFX_CHECK_RENDER_THREAD();
  283. struct Vertex
  284. {
  285. float m_x;
  286. float m_y;
  287. float m_z;
  288. uint32_t m_fg;
  289. uint32_t m_bg;
  290. float m_u;
  291. float m_v;
  292. };
  293. static uint32_t palette[16] =
  294. {
  295. 0x0,
  296. 0xff0000cc,
  297. 0xff069a4e,
  298. 0xff00a0c4,
  299. 0xffa46534,
  300. 0xff7b5075,
  301. 0xff9a9806,
  302. 0xffcfd7d3,
  303. 0xff535755,
  304. 0xff2929ef,
  305. 0xff34e28a,
  306. 0xff4fe9fc,
  307. 0xffcf9f72,
  308. 0xffa87fad,
  309. 0xffe2e234,
  310. 0xffeceeee,
  311. };
  312. uint32_t yy = 0;
  313. uint32_t xx = 0;
  314. const float texelWidth = 1.0f/2048.0f;
  315. const float texelWidthHalf = texelWidth*0.5f;
  316. const float texelHeight = 1.0f/24.0f;
  317. #if BGFX_CONFIG_RENDERER_DIRECT3D9
  318. const float texelHeightHalf = texelHeight*0.5f;
  319. #else
  320. const float texelHeightHalf = 0.0f;
  321. #endif // BGFX_CONFIG_RENDERER_
  322. const float utop = (_mem.m_small ? 0.0f : 8.0f)*texelHeight + texelHeightHalf;
  323. const float ubottom = (_mem.m_small ? 8.0f : 24.0f)*texelHeight + texelHeightHalf;
  324. const float fontHeight = (_mem.m_small ? 8.0f : 16.0f);
  325. setup();
  326. for (;yy < _mem.m_height;)
  327. {
  328. Vertex* vertex = (Vertex*)m_vb->data;
  329. uint16_t* indices = (uint16_t*)m_ib->data;
  330. uint32_t startVertex = 0;
  331. uint32_t numIndices = 0;
  332. for (; yy < _mem.m_height && numIndices < numBatchIndices; ++yy)
  333. {
  334. xx = xx < _mem.m_width ? xx : 0;
  335. const uint8_t* line = &_mem.m_mem[(yy*_mem.m_width+xx)*2];
  336. for (; xx < _mem.m_width && numIndices < numBatchIndices; ++xx)
  337. {
  338. uint8_t ch = line[0];
  339. uint8_t attr = line[1];
  340. if (0 != (ch|attr)
  341. && (' ' != ch || 0 != (attr&0xf0) ) )
  342. {
  343. uint32_t fg = palette[attr&0xf];
  344. uint32_t bg = palette[(attr>>4)&0xf];
  345. Vertex vert[4] =
  346. {
  347. { (xx )*8.0f, (yy )*fontHeight, 0.0f, fg, bg, (ch )*8.0f*texelWidth - texelWidthHalf, utop },
  348. { (xx+1)*8.0f, (yy )*fontHeight, 0.0f, fg, bg, (ch+1)*8.0f*texelWidth - texelWidthHalf, utop },
  349. { (xx+1)*8.0f, (yy+1)*fontHeight, 0.0f, fg, bg, (ch+1)*8.0f*texelWidth - texelWidthHalf, ubottom },
  350. { (xx )*8.0f, (yy+1)*fontHeight, 0.0f, fg, bg, (ch )*8.0f*texelWidth - texelWidthHalf, ubottom },
  351. };
  352. memcpy(vertex, vert, sizeof(vert) );
  353. vertex += 4;
  354. indices[0] = startVertex+0;
  355. indices[1] = startVertex+1;
  356. indices[2] = startVertex+2;
  357. indices[3] = startVertex+2;
  358. indices[4] = startVertex+3;
  359. indices[5] = startVertex+0;
  360. startVertex += 4;
  361. indices += 6;
  362. numIndices += 6;
  363. }
  364. line += 2;
  365. }
  366. if (numIndices >= numBatchIndices)
  367. {
  368. break;
  369. }
  370. }
  371. render(numIndices);
  372. }
  373. }
  374. void ClearQuad::init()
  375. {
  376. BGFX_CHECK_MAIN_THREAD();
  377. #if BGFX_CONFIG_CLEAR_QUAD
  378. m_decl.begin();
  379. m_decl.add(Attrib::Position, 3, AttribType::Float);
  380. m_decl.add(Attrib::Color0, 4, AttribType::Uint8, true);
  381. m_decl.end();
  382. const Memory* mem;
  383. # if BGFX_CONFIG_RENDERER_DIRECT3D11
  384. mem = makeRef(vs_clear_dx11, sizeof(vs_clear_dx11) );
  385. # elif BGFX_CONFIG_RENDERER_OPENGL
  386. mem = makeRef(vs_clear_glsl, sizeof(vs_clear_glsl) );
  387. # endif // BGFX_CONFIG_RENDERER_*
  388. VertexShaderHandle vsh = createVertexShader(mem);
  389. # if BGFX_CONFIG_RENDERER_DIRECT3D11
  390. mem = makeRef(fs_clear_dx11, sizeof(fs_clear_dx11) );
  391. # elif BGFX_CONFIG_RENDERER_OPENGL
  392. mem = makeRef(fs_clear_glsl, sizeof(fs_clear_glsl) );
  393. # endif // BGFX_CONFIG_RENDERER_*
  394. FragmentShaderHandle fsh = createFragmentShader(mem);
  395. m_program = createProgram(vsh, fsh);
  396. destroyVertexShader(vsh);
  397. destroyFragmentShader(fsh);
  398. m_vb = s_ctx.createTransientVertexBuffer(4*m_decl.m_stride, &m_decl);
  399. mem = alloc(6*sizeof(uint16_t) );
  400. uint16_t* indices = (uint16_t*)mem->data;
  401. indices[0] = 0;
  402. indices[1] = 1;
  403. indices[2] = 2;
  404. indices[3] = 2;
  405. indices[4] = 3;
  406. indices[5] = 0;
  407. m_ib = s_ctx.createIndexBuffer(mem);
  408. #endif // BGFX_CONFIG_CLEAR_QUAD
  409. }
  410. void ClearQuad::shutdown()
  411. {
  412. BGFX_CHECK_MAIN_THREAD();
  413. #if BGFX_CONFIG_CLEAR_QUAD
  414. destroyProgram(m_program);
  415. destroyIndexBuffer(m_ib);
  416. s_ctx.destroyTransientVertexBuffer(m_vb);
  417. #endif // BGFX_CONFIG_CLEAR_QUAD
  418. }
  419. static const char* s_predefinedName[PredefinedUniform::Count] =
  420. {
  421. "u_viewRect",
  422. "u_viewTexel",
  423. "u_view",
  424. "u_viewProj",
  425. "u_viewProjX",
  426. "u_model",
  427. "u_modelView",
  428. "u_modelViewProj",
  429. "u_modelViewProjX",
  430. "u_alphaRef",
  431. };
  432. const char* getPredefinedUniformName(PredefinedUniform::Enum _enum)
  433. {
  434. return s_predefinedName[_enum];
  435. }
  436. PredefinedUniform::Enum nameToPredefinedUniformEnum(const char* _name)
  437. {
  438. for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
  439. {
  440. if (0 == strcmp(_name, s_predefinedName[ii]) )
  441. {
  442. return PredefinedUniform::Enum(ii);
  443. }
  444. }
  445. return PredefinedUniform::Count;
  446. }
  447. void Frame::submit(uint8_t _id, int32_t _depth)
  448. {
  449. if (m_discard)
  450. {
  451. discard();
  452. return;
  453. }
  454. if (BGFX_CONFIG_MAX_DRAW_CALLS-1 <= m_num
  455. || (0 == m_state.m_numVertices && 0 == m_state.m_numIndices) )
  456. {
  457. ++m_numDropped;
  458. return;
  459. }
  460. BX_WARN(invalidHandle != m_key.m_program, "Program with invalid handle");
  461. if (invalidHandle != m_key.m_program)
  462. {
  463. m_key.m_depth = _depth;
  464. m_key.m_view = _id;
  465. m_key.m_seq = s_ctx.m_seq[_id] & s_ctx.m_seqMask[_id];
  466. s_ctx.m_seq[_id]++;
  467. uint64_t key = m_key.encode();
  468. m_sortKeys[m_num] = key;
  469. m_sortValues[m_num] = m_numRenderStates;
  470. ++m_num;
  471. m_state.m_constEnd = m_constantBuffer->getPos();
  472. m_state.m_flags |= m_flags;
  473. m_renderState[m_numRenderStates] = m_state;
  474. ++m_numRenderStates;
  475. }
  476. m_state.clear();
  477. m_flags = BGFX_STATE_NONE;
  478. }
  479. void Frame::submitMask(uint32_t _viewMask, int32_t _depth)
  480. {
  481. if (m_discard)
  482. {
  483. discard();
  484. return;
  485. }
  486. if (BGFX_CONFIG_MAX_DRAW_CALLS-1 <= m_num
  487. || (0 == m_state.m_numVertices && 0 == m_state.m_numIndices) )
  488. {
  489. m_numDropped += uint32_cntbits(_viewMask);
  490. return;
  491. }
  492. BX_WARN(invalidHandle != m_key.m_program, "Program with invalid handle");
  493. if (invalidHandle != m_key.m_program)
  494. {
  495. m_key.m_depth = _depth;
  496. for (uint32_t id = 0, viewMask = _viewMask, ntz = uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, id += 1, ntz = uint32_cnttz(viewMask) )
  497. {
  498. viewMask >>= ntz;
  499. id += ntz;
  500. m_key.m_view = id;
  501. m_key.m_seq = s_ctx.m_seq[id] & s_ctx.m_seqMask[id];
  502. s_ctx.m_seq[id]++;
  503. uint64_t key = m_key.encode();
  504. m_sortKeys[m_num] = key;
  505. m_sortValues[m_num] = m_numRenderStates;
  506. ++m_num;
  507. }
  508. m_state.m_constEnd = m_constantBuffer->getPos();
  509. m_state.m_flags |= m_flags;
  510. m_renderState[m_numRenderStates] = m_state;
  511. ++m_numRenderStates;
  512. }
  513. m_state.clear();
  514. m_flags = BGFX_STATE_NONE;
  515. }
  516. void Frame::sort()
  517. {
  518. bx::radixSort64(m_sortKeys, s_ctx.m_tempKeys, m_sortValues, s_ctx.m_tempValues, m_num);
  519. }
  520. RendererType::Enum getRendererType()
  521. {
  522. #if BGFX_CONFIG_RENDERER_DIRECT3D9
  523. return RendererType::Direct3D9;
  524. #elif BGFX_CONFIG_RENDERER_DIRECT3D11
  525. return RendererType::Direct3D11;
  526. #elif BGFX_CONFIG_RENDERER_OPENGL
  527. return RendererType::OpenGL;
  528. #elif BGFX_CONFIG_RENDERER_OPENGLES2
  529. return RendererType::OpenGLES2;
  530. #elif BGFX_CONFIG_RENDERER_OPENGLES3
  531. return RendererType::OpenGLES3;
  532. #else
  533. return RendererType::Null;
  534. #endif // BGFX_CONFIG_RENDERER_
  535. }
  536. void init(CallbackI* _callback, ReallocFn _realloc, FreeFn _free)
  537. {
  538. if (NULL != _callback)
  539. {
  540. g_callback = _callback;
  541. }
  542. if (NULL != _realloc
  543. && NULL != _free)
  544. {
  545. g_realloc = _realloc;
  546. g_free = _free;
  547. }
  548. s_threadIndex = BGFX_MAIN_THREAD_MAGIC;
  549. // On NaCl renderer is on the main thread.
  550. s_ctx.init(!BX_PLATFORM_NACL && !BX_PLATFORM_IOS);
  551. }
  552. void shutdown()
  553. {
  554. BGFX_CHECK_MAIN_THREAD();
  555. s_ctx.shutdown();
  556. s_threadIndex = 0;
  557. g_callback = &s_callbackStub;
  558. g_realloc = reallocStub;
  559. g_free = freeStub;
  560. }
  561. void reset(uint32_t _width, uint32_t _height, uint32_t _flags)
  562. {
  563. BGFX_CHECK_MAIN_THREAD();
  564. s_ctx.reset(_width, _height, _flags);
  565. }
  566. void frame()
  567. {
  568. BGFX_CHECK_MAIN_THREAD();
  569. s_ctx.frame();
  570. }
  571. bool renderFrame()
  572. {
  573. BGFX_CHECK_RENDER_THREAD();
  574. return s_ctx.renderFrame();
  575. }
  576. const uint32_t g_uniformTypeSize[UniformType::Count+1] =
  577. {
  578. sizeof(int32_t),
  579. sizeof(float),
  580. 0,
  581. 1*sizeof(int32_t),
  582. 1*sizeof(float),
  583. 2*sizeof(float),
  584. 3*sizeof(float),
  585. 4*sizeof(float),
  586. 3*3*sizeof(float),
  587. 4*4*sizeof(float),
  588. 1,
  589. };
  590. void ConstantBuffer::writeUniform(UniformType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num)
  591. {
  592. uint32_t opcode = encodeOpcode(_type, _loc, _num, true);
  593. write(opcode);
  594. write(_value, g_uniformTypeSize[_type]*_num);
  595. }
  596. void ConstantBuffer::writeUniformRef(UniformType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num)
  597. {
  598. uint32_t opcode = encodeOpcode(_type, _loc, _num, false);
  599. write(opcode);
  600. write(&_value, sizeof(void*) );
  601. }
  602. void ConstantBuffer::writeMarker(const char* _marker)
  603. {
  604. uint16_t num = (uint16_t)strlen(_marker)+1;
  605. uint32_t opcode = encodeOpcode(bgfx::UniformType::Count, 0, num, true);
  606. write(opcode);
  607. write(_marker, num);
  608. }
  609. void Context::init(bool _createRenderThread)
  610. {
  611. BX_CHECK(!m_rendererInitialized, "Already initialized?");
  612. BX_TRACE("init");
  613. m_exit = false;
  614. m_frames = 0;
  615. m_render = &m_frame[0];
  616. m_submit = &m_frame[1];
  617. m_debug = BGFX_DEBUG_NONE;
  618. m_submit->create();
  619. m_render->create();
  620. #if BGFX_CONFIG_MULTITHREADED
  621. if (_createRenderThread)
  622. {
  623. m_thread.init(renderThread, this);
  624. }
  625. #else
  626. BX_UNUSED(_createRenderThread);
  627. #endif // BGFX_CONFIG_MULTITHREADED
  628. memset(m_rt, 0xff, sizeof(m_rt) );
  629. memset(m_clear, 0, sizeof(m_clear) );
  630. memset(m_rect, 0, sizeof(m_rect) );
  631. memset(m_scissor, 0, sizeof(m_scissor) );
  632. memset(m_seq, 0, sizeof(m_seq) );
  633. memset(m_seqMask, 0, sizeof(m_seqMask) );
  634. for (uint32_t ii = 0; ii < countof(m_rect); ++ii)
  635. {
  636. m_rect[ii].m_width = 1;
  637. m_rect[ii].m_height = 1;
  638. }
  639. m_declRef.init();
  640. frameNoRenderWait();
  641. getCommandBuffer(CommandBuffer::RendererInit);
  642. m_textVideoMemBlitter.init();
  643. m_clearQuad.init();
  644. m_submit->m_transientVb = createTransientVertexBuffer(BGFX_CONFIG_TRANSIENT_VERTEX_BUFFER_SIZE);
  645. m_submit->m_transientIb = createTransientIndexBuffer(BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE);
  646. frame();
  647. m_submit->m_transientVb = createTransientVertexBuffer(BGFX_CONFIG_TRANSIENT_VERTEX_BUFFER_SIZE);
  648. m_submit->m_transientIb = createTransientIndexBuffer(BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE);
  649. frame();
  650. for (uint8_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
  651. {
  652. char name[256];
  653. bx::snprintf(name, sizeof(name), "%02d view", ii);
  654. setViewName(ii, name);
  655. }
  656. }
  657. void Context::shutdown()
  658. {
  659. BX_TRACE("shutdown");
  660. getCommandBuffer(CommandBuffer::RendererShutdownBegin);
  661. frame();
  662. destroyTransientVertexBuffer(m_submit->m_transientVb);
  663. destroyTransientIndexBuffer(m_submit->m_transientIb);
  664. m_textVideoMemBlitter.shutdown();
  665. m_clearQuad.shutdown();
  666. frame();
  667. destroyTransientVertexBuffer(m_submit->m_transientVb);
  668. destroyTransientIndexBuffer(m_submit->m_transientIb);
  669. frame();
  670. getCommandBuffer(CommandBuffer::RendererShutdownEnd);
  671. frame();
  672. m_declRef.shutdown(m_vertexDeclHandle);
  673. #if BGFX_CONFIG_MULTITHREADED
  674. if (m_thread.isRunning() )
  675. {
  676. m_thread.shutdown();
  677. }
  678. #endif // BGFX_CONFIG_MULTITHREADED
  679. renderSemWait();
  680. m_submit->destroy();
  681. m_render->destroy();
  682. #if BGFX_CONFIG_DEBUG
  683. # define CHECK_HANDLE_LEAK(_handleAlloc) \
  684. do { \
  685. BX_WARN(0 == _handleAlloc.getNumHandles(), "LEAK: " #_handleAlloc " %d (max: %d)", _handleAlloc.getNumHandles(), _handleAlloc.getMaxHandles() ); \
  686. } while (0)
  687. CHECK_HANDLE_LEAK(m_dynamicIndexBufferHandle);
  688. CHECK_HANDLE_LEAK(m_dynamicVertexBufferHandle);
  689. CHECK_HANDLE_LEAK(m_indexBufferHandle);
  690. CHECK_HANDLE_LEAK(m_vertexDeclHandle);
  691. CHECK_HANDLE_LEAK(m_vertexBufferHandle);
  692. CHECK_HANDLE_LEAK(m_vertexShaderHandle);
  693. CHECK_HANDLE_LEAK(m_fragmentShaderHandle);
  694. CHECK_HANDLE_LEAK(m_programHandle);
  695. CHECK_HANDLE_LEAK(m_textureHandle);
  696. CHECK_HANDLE_LEAK(m_renderTargetHandle);
  697. CHECK_HANDLE_LEAK(m_uniformHandle);
  698. # undef CHECK_HANDLE_LEAK
  699. #endif // BGFX_CONFIG_DEBUG
  700. }
  701. const Memory* alloc(uint32_t _size)
  702. {
  703. Memory* mem = (Memory*)g_realloc(NULL, sizeof(Memory) + _size);
  704. mem->size = _size;
  705. mem->data = (uint8_t*)mem + sizeof(Memory);
  706. return mem;
  707. }
  708. const Memory* makeRef(const void* _data, uint32_t _size)
  709. {
  710. Memory* mem = (Memory*)g_realloc(NULL, sizeof(Memory) );
  711. mem->size = _size;
  712. mem->data = (uint8_t*)_data;
  713. return mem;
  714. }
  715. void release(const Memory* _mem)
  716. {
  717. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  718. g_free(const_cast<Memory*>(_mem) );
  719. }
  720. void setDebug(uint32_t _debug)
  721. {
  722. BGFX_CHECK_MAIN_THREAD();
  723. s_ctx.m_debug = _debug;
  724. }
  725. void dbgTextClear(uint8_t _attr, bool _small)
  726. {
  727. BGFX_CHECK_MAIN_THREAD();
  728. s_ctx.dbgTextClear(_attr, _small);
  729. }
  730. void dbgTextPrintf(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, ...)
  731. {
  732. BGFX_CHECK_MAIN_THREAD();
  733. va_list argList;
  734. va_start(argList, _format);
  735. s_ctx.dbgTextPrintfVargs(_x, _y, _attr, _format, argList);
  736. va_end(argList);
  737. }
  738. IndexBufferHandle createIndexBuffer(const Memory* _mem)
  739. {
  740. BGFX_CHECK_MAIN_THREAD();
  741. return s_ctx.createIndexBuffer(_mem);
  742. }
  743. void destroyIndexBuffer(IndexBufferHandle _handle)
  744. {
  745. BGFX_CHECK_MAIN_THREAD();
  746. s_ctx.destroyIndexBuffer(_handle);
  747. }
  748. VertexBufferHandle createVertexBuffer(const Memory* _mem, const VertexDecl& _decl)
  749. {
  750. return s_ctx.createVertexBuffer(_mem, _decl);
  751. }
  752. void destroyVertexBuffer(VertexBufferHandle _handle)
  753. {
  754. BGFX_CHECK_MAIN_THREAD();
  755. s_ctx.destroyVertexBuffer(_handle);
  756. }
  757. DynamicIndexBufferHandle createDynamicIndexBuffer(uint16_t _num)
  758. {
  759. BGFX_CHECK_MAIN_THREAD();
  760. return s_ctx.createDynamicIndexBuffer(_num);
  761. }
  762. DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem)
  763. {
  764. BGFX_CHECK_MAIN_THREAD();
  765. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  766. return s_ctx.createDynamicIndexBuffer(_mem);
  767. }
  768. void updateDynamicIndexBuffer(DynamicIndexBufferHandle _handle, const Memory* _mem)
  769. {
  770. BGFX_CHECK_MAIN_THREAD();
  771. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  772. s_ctx.updateDynamicIndexBuffer(_handle, _mem);
  773. }
  774. void destroyDynamicIndexBuffer(DynamicIndexBufferHandle _handle)
  775. {
  776. BGFX_CHECK_MAIN_THREAD();
  777. s_ctx.destroyDynamicIndexBuffer(_handle);
  778. }
  779. DynamicVertexBufferHandle createDynamicVertexBuffer(uint16_t _num, const VertexDecl& _decl)
  780. {
  781. BGFX_CHECK_MAIN_THREAD();
  782. return s_ctx.createDynamicVertexBuffer(_num, _decl);
  783. }
  784. DynamicVertexBufferHandle createDynamicVertexBuffer(const Memory* _mem, const VertexDecl& _decl)
  785. {
  786. BGFX_CHECK_MAIN_THREAD();
  787. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  788. return s_ctx.createDynamicVertexBuffer(_mem, _decl);
  789. }
  790. void updateDynamicVertexBuffer(DynamicVertexBufferHandle _handle, const Memory* _mem)
  791. {
  792. BGFX_CHECK_MAIN_THREAD();
  793. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  794. s_ctx.updateDynamicVertexBuffer(_handle, _mem);
  795. }
  796. void destroyDynamicVertexBuffer(DynamicVertexBufferHandle _handle)
  797. {
  798. BGFX_CHECK_MAIN_THREAD();
  799. s_ctx.destroyDynamicVertexBuffer(_handle);
  800. }
  801. bool checkAvailTransientIndexBuffer(uint32_t _num)
  802. {
  803. BGFX_CHECK_MAIN_THREAD();
  804. BX_CHECK(0 < _num, "Requesting 0 indices.");
  805. return s_ctx.m_submit->checkAvailTransientIndexBuffer(_num);
  806. }
  807. bool checkAvailTransientVertexBuffer(uint32_t _num, const VertexDecl& _decl)
  808. {
  809. BGFX_CHECK_MAIN_THREAD();
  810. BX_CHECK(0 < _num, "Requesting 0 vertices.");
  811. return s_ctx.m_submit->checkAvailTransientVertexBuffer(_num, _decl.m_stride);
  812. }
  813. bool checkAvailInstanceDataBuffer(uint32_t _num, uint16_t _stride)
  814. {
  815. BGFX_CHECK_MAIN_THREAD();
  816. BX_CHECK(0 < _num, "Requesting 0 instances.");
  817. return s_ctx.m_submit->checkAvailTransientVertexBuffer(_num, _stride);
  818. }
  819. bool checkAvailTransientBuffers(uint32_t _numVertices, const VertexDecl& _decl, uint32_t _numIndices)
  820. {
  821. return checkAvailTransientVertexBuffer(_numVertices, _decl)
  822. && checkAvailTransientIndexBuffer(_numIndices)
  823. ;
  824. }
  825. void allocTransientIndexBuffer(TransientIndexBuffer* _tib, uint32_t _num)
  826. {
  827. BGFX_CHECK_MAIN_THREAD();
  828. BX_CHECK(NULL != _tib, "_tib can't be NULL");
  829. BX_CHECK(0 < _num, "Requesting 0 indices.");
  830. return s_ctx.allocTransientIndexBuffer(_tib, _num);
  831. }
  832. void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint32_t _num, const VertexDecl& _decl)
  833. {
  834. BGFX_CHECK_MAIN_THREAD();
  835. BX_CHECK(NULL != _tvb, "_tvb can't be NULL");
  836. BX_CHECK(0 < _num, "Requesting 0 vertices.");
  837. BX_CHECK(UINT16_MAX >= _num, "Requesting %d vertices (max: %d).", _num, UINT16_MAX);
  838. return s_ctx.allocTransientVertexBuffer(_tvb, _num, _decl);
  839. }
  840. const InstanceDataBuffer* allocInstanceDataBuffer(uint32_t _num, uint16_t _stride)
  841. {
  842. BGFX_CHECK_MAIN_THREAD();
  843. BX_CHECK(0 < _num, "Requesting 0 instanced data vertices.");
  844. return s_ctx.allocInstanceDataBuffer(_num, _stride);
  845. }
  846. VertexShaderHandle createVertexShader(const Memory* _mem)
  847. {
  848. BGFX_CHECK_MAIN_THREAD();
  849. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  850. return s_ctx.createVertexShader(_mem);
  851. }
  852. void destroyVertexShader(VertexShaderHandle _handle)
  853. {
  854. BGFX_CHECK_MAIN_THREAD();
  855. s_ctx.destroyVertexShader(_handle);
  856. }
  857. FragmentShaderHandle createFragmentShader(const Memory* _mem)
  858. {
  859. BGFX_CHECK_MAIN_THREAD();
  860. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  861. return s_ctx.createFragmentShader(_mem);
  862. }
  863. void destroyFragmentShader(FragmentShaderHandle _handle)
  864. {
  865. BGFX_CHECK_MAIN_THREAD();
  866. s_ctx.destroyFragmentShader(_handle);
  867. }
  868. ProgramHandle createProgram(VertexShaderHandle _vsh, FragmentShaderHandle _fsh)
  869. {
  870. BGFX_CHECK_MAIN_THREAD();
  871. return s_ctx.createProgram(_vsh, _fsh);
  872. }
  873. void destroyProgram(ProgramHandle _handle)
  874. {
  875. BGFX_CHECK_MAIN_THREAD();
  876. s_ctx.destroyProgram(_handle);
  877. }
  878. static const uint32_t s_bitsPerPixel[TextureFormat::Count] =
  879. {
  880. 4, // BC1
  881. 8, // BC2
  882. 8, // BC3
  883. 4, // BC4
  884. 8, // BC5
  885. 0, // Unknown
  886. 8, // L8
  887. 32, // BGRX8
  888. 32, // BGRA8
  889. 64, // RGBA16
  890. 64, // RGBA16F
  891. 16, // R5G6B5
  892. 16, // RGBA4
  893. 16, // RGB5A1
  894. 32, // RGB10A2
  895. };
  896. void calcTextureSize(TextureInfo& _info, uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, TextureFormat::Enum _format)
  897. {
  898. _width = uint32_max(1, _width);
  899. _height = uint32_max(1, _height);
  900. _depth = uint32_max(1, _depth);
  901. _numMips = uint32_max(1, _numMips);
  902. uint32_t width = _width;
  903. uint32_t height = _height;
  904. uint32_t depth = _depth;
  905. uint32_t bpp = s_bitsPerPixel[_format];
  906. uint32_t size = 0;
  907. for (uint32_t lod = 0; lod < _numMips; ++lod)
  908. {
  909. width = uint32_max(1, width);
  910. height = uint32_max(1, height);
  911. depth = uint32_max(1, depth);
  912. size += _width*_height*depth*bpp/8;
  913. width >>= 1;
  914. height >>= 1;
  915. depth >>= 1;
  916. }
  917. _info.format = _format;
  918. _info.storageSize = size;
  919. _info.width = _width;
  920. _info.height = _height;
  921. _info.depth = _depth;
  922. _info.numMips = _numMips;
  923. _info.bitsPerPixel = bpp;
  924. }
  925. TextureHandle createTexture(const Memory* _mem, uint32_t _flags, TextureInfo* _info)
  926. {
  927. BGFX_CHECK_MAIN_THREAD();
  928. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  929. return s_ctx.createTexture(_mem, _flags, _info);
  930. }
  931. TextureHandle createTexture2D(uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
  932. {
  933. BGFX_CHECK_MAIN_THREAD();
  934. #if BGFX_CONFIG_DEBUG
  935. if (NULL != _mem)
  936. {
  937. TextureInfo ti;
  938. calcTextureSize(ti, _width, _height, 1, _numMips, _format);
  939. BX_CHECK(ti.storageSize == _mem->size
  940. , "createTexture2D: Texture storage size doesn't match passed memory size (storage size: %d, memory size: %d)"
  941. , ti.storageSize
  942. , _mem->size
  943. );
  944. }
  945. #endif // BGFX_CONFIG_DEBUG
  946. uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
  947. const Memory* mem = alloc(size);
  948. bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
  949. uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
  950. bx::write(&writer, magic);
  951. TextureCreate tc;
  952. tc.m_flags = _flags;
  953. tc.m_width = _width;
  954. tc.m_height = _height;
  955. tc.m_sides = 0;
  956. tc.m_depth = 0;
  957. tc.m_numMips = _numMips;
  958. tc.m_format = uint8_t(_format);
  959. tc.m_cubeMap = false;
  960. tc.m_mem = _mem;
  961. bx::write(&writer, tc);
  962. return s_ctx.createTexture(mem, _flags, NULL);
  963. }
  964. TextureHandle createTexture3D(uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
  965. {
  966. BGFX_CHECK_MAIN_THREAD();
  967. #if BGFX_CONFIG_DEBUG
  968. if (NULL != _mem)
  969. {
  970. TextureInfo ti;
  971. calcTextureSize(ti, _width, _height, _depth, _numMips, _format);
  972. BX_CHECK(ti.storageSize == _mem->size
  973. , "createTexture3D: Texture storage size doesn't match passed memory size (storage size: %d, memory size: %d)"
  974. , ti.storageSize
  975. , _mem->size
  976. );
  977. }
  978. #endif // BGFX_CONFIG_DEBUG
  979. uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
  980. const Memory* mem = alloc(size);
  981. bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
  982. uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
  983. bx::write(&writer, magic);
  984. TextureCreate tc;
  985. tc.m_flags = _flags;
  986. tc.m_width = _width;
  987. tc.m_height = _height;
  988. tc.m_sides = 0;
  989. tc.m_depth = _depth;
  990. tc.m_numMips = _numMips;
  991. tc.m_format = uint8_t(_format);
  992. tc.m_cubeMap = false;
  993. tc.m_mem = _mem;
  994. bx::write(&writer, tc);
  995. return s_ctx.createTexture(mem, _flags, NULL);
  996. }
  997. TextureHandle createTextureCube(uint16_t _sides, uint16_t _width, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
  998. {
  999. BGFX_CHECK_MAIN_THREAD();
  1000. #if BGFX_CONFIG_DEBUG
  1001. if (NULL != _mem)
  1002. {
  1003. TextureInfo ti;
  1004. calcTextureSize(ti, _width, _width, 1, _numMips, _format);
  1005. BX_CHECK(ti.storageSize*_sides == _mem->size
  1006. , "createTextureCube: Texture storage size doesn't match passed memory size (storage size: %d, memory size: %d)"
  1007. , ti.storageSize*_sides
  1008. , _mem->size
  1009. );
  1010. }
  1011. #endif // BGFX_CONFIG_DEBUG
  1012. uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
  1013. const Memory* mem = alloc(size);
  1014. bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
  1015. uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
  1016. bx::write(&writer, magic);
  1017. TextureCreate tc;
  1018. tc.m_flags = _flags;
  1019. tc.m_width = _width;
  1020. tc.m_height = _width;
  1021. tc.m_sides = _sides;
  1022. tc.m_depth = 0;
  1023. tc.m_numMips = _numMips;
  1024. tc.m_format = uint8_t(_format);
  1025. tc.m_cubeMap = true;
  1026. tc.m_mem = _mem;
  1027. bx::write(&writer, tc);
  1028. return s_ctx.createTexture(mem, _flags, NULL);
  1029. }
  1030. void destroyTexture(TextureHandle _handle)
  1031. {
  1032. BGFX_CHECK_MAIN_THREAD();
  1033. s_ctx.destroyTexture(_handle);
  1034. }
  1035. void updateTexture2D(TextureHandle _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const Memory* _mem)
  1036. {
  1037. BGFX_CHECK_MAIN_THREAD();
  1038. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1039. if (_width == 0
  1040. || _height == 0)
  1041. {
  1042. release(_mem);
  1043. }
  1044. else
  1045. {
  1046. s_ctx.updateTexture(_handle, 0, _mip, _x, _y, 0, _width, _height, 1, _mem);
  1047. }
  1048. }
  1049. 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)
  1050. {
  1051. BGFX_CHECK_MAIN_THREAD();
  1052. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1053. if (_width == 0
  1054. || _height == 0
  1055. || _depth == 0)
  1056. {
  1057. release(_mem);
  1058. }
  1059. else
  1060. {
  1061. s_ctx.updateTexture(_handle, 0, _mip, _x, _y, _z, _width, _height, _depth, _mem);
  1062. }
  1063. }
  1064. 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)
  1065. {
  1066. BGFX_CHECK_MAIN_THREAD();
  1067. BX_CHECK(NULL != _mem, "_mem can't be NULL");
  1068. BX_CHECK(_side <= 5, "Invalid side %d.", _side);
  1069. if (_width == 0
  1070. || _height == 0)
  1071. {
  1072. release(_mem);
  1073. }
  1074. else
  1075. {
  1076. s_ctx.updateTexture(_handle, _side, _mip, _x, _y, 0, _width, _height, 1, _mem);
  1077. }
  1078. }
  1079. RenderTargetHandle createRenderTarget(uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
  1080. {
  1081. BGFX_CHECK_MAIN_THREAD();
  1082. BX_WARN(0 != _width && 0 != _height, "Render target resolution width or height cannot be 0 (width %d, height %d).", _width, _height);
  1083. return s_ctx.createRenderTarget(uint16_max(1, _width), uint16_max(1, _height), _flags, _textureFlags);
  1084. }
  1085. void destroyRenderTarget(RenderTargetHandle _handle)
  1086. {
  1087. BGFX_CHECK_MAIN_THREAD();
  1088. s_ctx.destroyRenderTarget(_handle);
  1089. }
  1090. UniformHandle createUniform(const char* _name, UniformType::Enum _type, uint16_t _num)
  1091. {
  1092. BGFX_CHECK_MAIN_THREAD();
  1093. return s_ctx.createUniform(_name, _type, _num);
  1094. }
  1095. void destroyUniform(UniformHandle _handle)
  1096. {
  1097. BGFX_CHECK_MAIN_THREAD();
  1098. s_ctx.destroyUniform(_handle);
  1099. }
  1100. void setViewName(uint8_t _id, const char* _name)
  1101. {
  1102. BGFX_CHECK_MAIN_THREAD();
  1103. s_ctx.setViewName(_id, _name);
  1104. }
  1105. void setViewRect(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  1106. {
  1107. BGFX_CHECK_MAIN_THREAD();
  1108. s_ctx.setViewRect(_id, _x, _y, _width, _height);
  1109. }
  1110. void setViewRectMask(uint32_t _viewMask, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  1111. {
  1112. BGFX_CHECK_MAIN_THREAD();
  1113. s_ctx.setViewRectMask(_viewMask, _x, _y, _width, _height);
  1114. }
  1115. void setViewScissor(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  1116. {
  1117. BGFX_CHECK_MAIN_THREAD();
  1118. s_ctx.setViewScissor(_id, _x, _y, _width, _height);
  1119. }
  1120. void setViewScissorMask(uint32_t _viewMask, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  1121. {
  1122. BGFX_CHECK_MAIN_THREAD();
  1123. s_ctx.setViewScissorMask(_viewMask, _x, _y, _width, _height);
  1124. }
  1125. void setViewClear(uint8_t _id, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
  1126. {
  1127. BGFX_CHECK_MAIN_THREAD();
  1128. s_ctx.setViewClear(_id, _flags, _rgba, _depth, _stencil);
  1129. }
  1130. void setViewClearMask(uint32_t _viewMask, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
  1131. {
  1132. BGFX_CHECK_MAIN_THREAD();
  1133. s_ctx.setViewClearMask(_viewMask, _flags, _rgba, _depth, _stencil);
  1134. }
  1135. void setViewSeq(uint8_t _id, bool _enabled)
  1136. {
  1137. BGFX_CHECK_MAIN_THREAD();
  1138. s_ctx.setViewSeq(_id, _enabled);
  1139. }
  1140. void setViewSeqMask(uint32_t _viewMask, bool _enabled)
  1141. {
  1142. BGFX_CHECK_MAIN_THREAD();
  1143. s_ctx.setViewSeqMask(_viewMask, _enabled);
  1144. }
  1145. void setViewRenderTarget(uint8_t _id, RenderTargetHandle _handle)
  1146. {
  1147. BGFX_CHECK_MAIN_THREAD();
  1148. s_ctx.setViewRenderTarget(_id, _handle);
  1149. }
  1150. void setViewRenderTargetMask(uint32_t _mask, RenderTargetHandle _handle)
  1151. {
  1152. BGFX_CHECK_MAIN_THREAD();
  1153. s_ctx.setViewRenderTargetMask(_mask, _handle);
  1154. }
  1155. void setViewTransform(uint8_t _id, const void* _view, const void* _proj, uint8_t _other)
  1156. {
  1157. BGFX_CHECK_MAIN_THREAD();
  1158. s_ctx.setViewTransform(_id, _view, _proj, _other);
  1159. }
  1160. void setViewTransformMask(uint32_t _viewMask, const void* _view, const void* _proj, uint8_t _other)
  1161. {
  1162. BGFX_CHECK_MAIN_THREAD();
  1163. s_ctx.setViewTransformMask(_viewMask, _view, _proj, _other);
  1164. }
  1165. void setMarker(const char* _marker)
  1166. {
  1167. BGFX_CHECK_MAIN_THREAD();
  1168. s_ctx.m_submit->setMarker(_marker);
  1169. }
  1170. void setState(uint64_t _state, uint32_t _rgba)
  1171. {
  1172. BGFX_CHECK_MAIN_THREAD();
  1173. s_ctx.m_submit->setState(_state, _rgba);
  1174. }
  1175. void setStencil(uint32_t _fstencil, uint32_t _bstencil)
  1176. {
  1177. BGFX_CHECK_MAIN_THREAD();
  1178. s_ctx.m_submit->setStencil(_fstencil, _bstencil);
  1179. }
  1180. uint16_t setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  1181. {
  1182. BGFX_CHECK_MAIN_THREAD();
  1183. return s_ctx.m_submit->setScissor(_x, _y, _width, _height);
  1184. }
  1185. void setScissor(uint16_t _cache)
  1186. {
  1187. BGFX_CHECK_MAIN_THREAD();
  1188. s_ctx.m_submit->setScissor(_cache);
  1189. }
  1190. uint32_t setTransform(const void* _mtx, uint16_t _num)
  1191. {
  1192. BGFX_CHECK_MAIN_THREAD();
  1193. return s_ctx.m_submit->setTransform(_mtx, _num);
  1194. }
  1195. void setTransform(uint32_t _cache, uint16_t _num)
  1196. {
  1197. BGFX_CHECK_MAIN_THREAD();
  1198. s_ctx.m_submit->setTransform(_cache, _num);
  1199. }
  1200. void setUniform(UniformHandle _handle, const void* _value, uint16_t _num)
  1201. {
  1202. BGFX_CHECK_MAIN_THREAD();
  1203. s_ctx.setUniform(_handle, _value, _num);
  1204. }
  1205. void setIndexBuffer(IndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices)
  1206. {
  1207. BGFX_CHECK_MAIN_THREAD();
  1208. s_ctx.m_submit->setIndexBuffer(_handle, _firstIndex, _numIndices);
  1209. }
  1210. void setIndexBuffer(DynamicIndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices)
  1211. {
  1212. BGFX_CHECK_MAIN_THREAD();
  1213. s_ctx.m_submit->setIndexBuffer(s_ctx.m_dynamicIndexBuffers[_handle.idx].m_handle, _firstIndex, _numIndices);
  1214. }
  1215. void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _numIndices)
  1216. {
  1217. BGFX_CHECK_MAIN_THREAD();
  1218. BX_CHECK(NULL != _tib, "_tib can't be NULL");
  1219. uint32_t numIndices = uint32_min(_numIndices, _tib->size/2);
  1220. s_ctx.m_submit->setIndexBuffer(_tib, numIndices);
  1221. }
  1222. void setVertexBuffer(VertexBufferHandle _handle, uint32_t _numVertices)
  1223. {
  1224. BGFX_CHECK_MAIN_THREAD();
  1225. s_ctx.m_submit->setVertexBuffer(_handle, _numVertices);
  1226. }
  1227. void setVertexBuffer(DynamicVertexBufferHandle _handle, uint32_t _numVertices)
  1228. {
  1229. BGFX_CHECK_MAIN_THREAD();
  1230. s_ctx.m_submit->setVertexBuffer(s_ctx.m_dynamicVertexBuffers[_handle.idx], _numVertices);
  1231. }
  1232. void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _numVertices)
  1233. {
  1234. BGFX_CHECK_MAIN_THREAD();
  1235. BX_CHECK(NULL != _tvb, "_tvb can't be NULL");
  1236. s_ctx.m_submit->setVertexBuffer(_tvb, _numVertices);
  1237. }
  1238. void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint16_t _num)
  1239. {
  1240. BGFX_CHECK_MAIN_THREAD();
  1241. s_ctx.m_submit->setInstanceDataBuffer(_idb, _num);
  1242. }
  1243. void setProgram(ProgramHandle _handle)
  1244. {
  1245. BGFX_CHECK_MAIN_THREAD();
  1246. s_ctx.m_submit->setProgram(_handle);
  1247. }
  1248. void setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint32_t _flags)
  1249. {
  1250. BGFX_CHECK_MAIN_THREAD();
  1251. s_ctx.m_submit->setTexture(_stage, _sampler, _handle, _flags);
  1252. }
  1253. void setTexture(uint8_t _stage, UniformHandle _sampler, RenderTargetHandle _handle, bool _depth, uint32_t _flags)
  1254. {
  1255. BGFX_CHECK_MAIN_THREAD();
  1256. s_ctx.m_submit->setTexture(_stage, _sampler, _handle, _depth, _flags);
  1257. }
  1258. void submit(uint8_t _id, int32_t _depth)
  1259. {
  1260. BGFX_CHECK_MAIN_THREAD();
  1261. s_ctx.m_submit->submit(_id, _depth);
  1262. }
  1263. void submitMask(uint32_t _viewMask, int32_t _depth)
  1264. {
  1265. BGFX_CHECK_MAIN_THREAD();
  1266. s_ctx.m_submit->submitMask(_viewMask, _depth);
  1267. }
  1268. void discard()
  1269. {
  1270. BGFX_CHECK_MAIN_THREAD();
  1271. s_ctx.m_submit->discard();
  1272. }
  1273. void saveScreenShot(const char* _filePath)
  1274. {
  1275. BGFX_CHECK_MAIN_THREAD();
  1276. s_ctx.saveScreenShot(_filePath);
  1277. }
  1278. }