renderer.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. /*
  2. * Copyright 2011-2020 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  4. */
  5. #ifndef BGFX_RENDERER_H_HEADER_GUARD
  6. #define BGFX_RENDERER_H_HEADER_GUARD
  7. #include "bgfx_p.h"
  8. namespace bgfx
  9. {
  10. inline constexpr uint32_t toAbgr8(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a = 0xff)
  11. {
  12. return 0
  13. | (uint32_t(_r)<<24)
  14. | (uint32_t(_g)<<16)
  15. | (uint32_t(_b)<< 8)
  16. | (uint32_t(_a) )
  17. ;
  18. }
  19. constexpr uint32_t kColorFrame = toAbgr8(0xff, 0xd7, 0xc9);
  20. constexpr uint32_t kColorView = toAbgr8(0xe4, 0xb4, 0x8e);
  21. constexpr uint32_t kColorDraw = toAbgr8(0xc6, 0xe5, 0xb9);
  22. constexpr uint32_t kColorCompute = toAbgr8(0xa7, 0xdb, 0xd8);
  23. constexpr uint32_t kColorMarker = toAbgr8(0xff, 0x00, 0x00);
  24. constexpr uint32_t kColorResource = toAbgr8(0xff, 0x40, 0x20);
  25. struct BlitState
  26. {
  27. BlitState(const Frame* _frame)
  28. : m_frame(_frame)
  29. , m_item(0)
  30. {
  31. m_key.decode(_frame->m_blitKeys[0]);
  32. }
  33. bool hasItem(uint16_t _view) const
  34. {
  35. return m_item < m_frame->m_numBlitItems
  36. && m_key.m_view <= _view
  37. ;
  38. }
  39. const BlitItem& advance()
  40. {
  41. const BlitItem& bi = m_frame->m_blitItem[m_key.m_item];
  42. ++m_item;
  43. m_key.decode(m_frame->m_blitKeys[m_item]);
  44. return bi;
  45. }
  46. const Frame* m_frame;
  47. BlitKey m_key;
  48. uint16_t m_item;
  49. };
  50. struct ViewState
  51. {
  52. ViewState()
  53. {
  54. }
  55. ViewState(Frame* _frame)
  56. {
  57. reset(_frame);
  58. }
  59. void reset(Frame* _frame)
  60. {
  61. m_alphaRef = 0.0f;
  62. m_invViewCached = UINT16_MAX;
  63. m_invProjCached = UINT16_MAX;
  64. m_invViewProjCached = UINT16_MAX;
  65. m_view = m_viewTmp;
  66. for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
  67. {
  68. bx::memCopy(&m_view[ii].un.f4x4, &_frame->m_view[ii].m_view.un.f4x4, sizeof(Matrix4) );
  69. }
  70. for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
  71. {
  72. bx::float4x4_mul(&m_viewProj[ii].un.f4x4
  73. , &m_view[ii].un.f4x4
  74. , &_frame->m_view[ii].m_proj.un.f4x4
  75. );
  76. }
  77. }
  78. template<uint16_t mtxRegs, typename RendererContext, typename Program, typename Draw>
  79. void setPredefined(RendererContext* _renderer, uint16_t _view, const Program& _program, const Frame* _frame, const Draw& _draw)
  80. {
  81. const FrameCache& frameCache = _frame->m_frameCache;
  82. for (uint32_t ii = 0, num = _program.m_numPredefined; ii < num; ++ii)
  83. {
  84. const PredefinedUniform& predefined = _program.m_predefined[ii];
  85. uint8_t flags = predefined.m_type&BGFX_UNIFORM_FRAGMENTBIT;
  86. switch (predefined.m_type&(~BGFX_UNIFORM_FRAGMENTBIT) )
  87. {
  88. case PredefinedUniform::ViewRect:
  89. {
  90. float frect[4];
  91. frect[0] = m_rect.m_x;
  92. frect[1] = m_rect.m_y;
  93. frect[2] = m_rect.m_width;
  94. frect[3] = m_rect.m_height;
  95. _renderer->setShaderUniform4f(flags
  96. , predefined.m_loc
  97. , &frect[0]
  98. , 1
  99. );
  100. }
  101. break;
  102. case PredefinedUniform::ViewTexel:
  103. {
  104. float frect[4];
  105. frect[0] = 1.0f/float(m_rect.m_width);
  106. frect[1] = 1.0f/float(m_rect.m_height);
  107. _renderer->setShaderUniform4f(flags
  108. , predefined.m_loc
  109. , &frect[0]
  110. , 1
  111. );
  112. }
  113. break;
  114. case PredefinedUniform::View:
  115. {
  116. _renderer->setShaderUniform4x4f(flags
  117. , predefined.m_loc
  118. , m_view[_view].un.val
  119. , bx::uint32_min(mtxRegs, predefined.m_count)
  120. );
  121. }
  122. break;
  123. case PredefinedUniform::InvView:
  124. {
  125. if (_view != m_invViewCached)
  126. {
  127. m_invViewCached = _view;
  128. bx::float4x4_inverse(&m_invView.un.f4x4
  129. , &m_view[_view].un.f4x4
  130. );
  131. }
  132. _renderer->setShaderUniform4x4f(flags
  133. , predefined.m_loc
  134. , m_invView.un.val
  135. , bx::uint32_min(mtxRegs, predefined.m_count)
  136. );
  137. }
  138. break;
  139. case PredefinedUniform::Proj:
  140. {
  141. _renderer->setShaderUniform4x4f(flags
  142. , predefined.m_loc
  143. , _frame->m_view[_view].m_proj.un.val
  144. , bx::uint32_min(mtxRegs, predefined.m_count)
  145. );
  146. }
  147. break;
  148. case PredefinedUniform::InvProj:
  149. {
  150. if (_view != m_invProjCached)
  151. {
  152. m_invProjCached = _view;
  153. bx::float4x4_inverse(&m_invProj.un.f4x4
  154. , &_frame->m_view[_view].m_proj.un.f4x4
  155. );
  156. }
  157. _renderer->setShaderUniform4x4f(flags
  158. , predefined.m_loc
  159. , m_invProj.un.val
  160. , bx::uint32_min(mtxRegs, predefined.m_count)
  161. );
  162. }
  163. break;
  164. case PredefinedUniform::ViewProj:
  165. {
  166. _renderer->setShaderUniform4x4f(flags
  167. , predefined.m_loc
  168. , m_viewProj[_view].un.val
  169. , bx::uint32_min(mtxRegs, predefined.m_count)
  170. );
  171. }
  172. break;
  173. case PredefinedUniform::InvViewProj:
  174. {
  175. if (_view != m_invViewProjCached)
  176. {
  177. m_invViewProjCached = _view;
  178. bx::float4x4_inverse(&m_invViewProj.un.f4x4
  179. , &m_viewProj[_view].un.f4x4
  180. );
  181. }
  182. _renderer->setShaderUniform4x4f(flags
  183. , predefined.m_loc
  184. , m_invViewProj.un.val
  185. , bx::uint32_min(mtxRegs, predefined.m_count)
  186. );
  187. }
  188. break;
  189. case PredefinedUniform::Model:
  190. {
  191. const Matrix4& model = frameCache.m_matrixCache.m_cache[_draw.m_startMatrix];
  192. _renderer->setShaderUniform4x4f(flags
  193. , predefined.m_loc
  194. , model.un.val
  195. , bx::uint32_min(_draw.m_numMatrices*mtxRegs, predefined.m_count)
  196. );
  197. }
  198. break;
  199. case PredefinedUniform::ModelView:
  200. {
  201. Matrix4 modelView;
  202. const Matrix4& model = frameCache.m_matrixCache.m_cache[_draw.m_startMatrix];
  203. bx::model4x4_mul(&modelView.un.f4x4
  204. , &model.un.f4x4
  205. , &m_view[_view].un.f4x4
  206. );
  207. _renderer->setShaderUniform4x4f(flags
  208. , predefined.m_loc
  209. , modelView.un.val
  210. , bx::uint32_min(mtxRegs, predefined.m_count)
  211. );
  212. }
  213. break;
  214. case PredefinedUniform::ModelViewProj:
  215. {
  216. Matrix4 modelViewProj;
  217. const Matrix4& model = frameCache.m_matrixCache.m_cache[_draw.m_startMatrix];
  218. bx::model4x4_mul_viewproj4x4(&modelViewProj.un.f4x4
  219. , &model.un.f4x4
  220. , &m_viewProj[_view].un.f4x4
  221. );
  222. _renderer->setShaderUniform4x4f(flags
  223. , predefined.m_loc
  224. , modelViewProj.un.val
  225. , bx::uint32_min(mtxRegs, predefined.m_count)
  226. );
  227. }
  228. break;
  229. case PredefinedUniform::AlphaRef:
  230. {
  231. _renderer->setShaderUniform4f(flags
  232. , predefined.m_loc
  233. , &m_alphaRef
  234. , 1
  235. );
  236. }
  237. break;
  238. default:
  239. BX_CHECK(false, "predefined %d not handled", predefined.m_type);
  240. break;
  241. }
  242. }
  243. }
  244. Matrix4 m_viewTmp[BGFX_CONFIG_MAX_VIEWS];
  245. Matrix4 m_viewProj[BGFX_CONFIG_MAX_VIEWS];
  246. Matrix4* m_view;
  247. Rect m_rect;
  248. Matrix4 m_invView;
  249. Matrix4 m_invProj;
  250. Matrix4 m_invViewProj;
  251. float m_alphaRef;
  252. uint16_t m_invViewCached;
  253. uint16_t m_invProjCached;
  254. uint16_t m_invViewProjCached;
  255. };
  256. template <typename Ty, uint16_t MaxHandleT>
  257. class StateCacheLru
  258. {
  259. public:
  260. Ty* add(uint64_t _key, const Ty& _value, uint16_t _parent)
  261. {
  262. uint16_t handle = m_alloc.alloc();
  263. if (UINT16_MAX == handle)
  264. {
  265. uint16_t back = m_alloc.getBack();
  266. invalidate(back);
  267. handle = m_alloc.alloc();
  268. }
  269. BX_CHECK(UINT16_MAX != handle, "Failed to find handle.");
  270. Data& data = m_data[handle];
  271. data.m_hash = _key;
  272. data.m_value = _value;
  273. data.m_parent = _parent;
  274. m_hashMap.insert(stl::make_pair(_key, handle) );
  275. return &m_data[handle].m_value;
  276. }
  277. Ty* find(uint64_t _key)
  278. {
  279. HashMap::iterator it = m_hashMap.find(_key);
  280. if (it != m_hashMap.end() )
  281. {
  282. uint16_t handle = it->second;
  283. m_alloc.touch(handle);
  284. return &m_data[handle].m_value;
  285. }
  286. return NULL;
  287. }
  288. void invalidate(uint64_t _key)
  289. {
  290. HashMap::iterator it = m_hashMap.find(_key);
  291. if (it != m_hashMap.end() )
  292. {
  293. uint16_t handle = it->second;
  294. m_alloc.free(handle);
  295. m_hashMap.erase(it);
  296. release(m_data[handle].m_value);
  297. }
  298. }
  299. void invalidate(uint16_t _handle)
  300. {
  301. if (m_alloc.isValid(_handle) )
  302. {
  303. m_alloc.free(_handle);
  304. Data& data = m_data[_handle];
  305. m_hashMap.erase(m_hashMap.find(data.m_hash) );
  306. release(data.m_value);
  307. }
  308. }
  309. void invalidateWithParent(uint16_t _parent)
  310. {
  311. for (uint16_t ii = 0; ii < m_alloc.getNumHandles();)
  312. {
  313. uint16_t handle = m_alloc.getHandleAt(ii);
  314. Data& data = m_data[handle];
  315. if (data.m_parent == _parent)
  316. {
  317. m_alloc.free(handle);
  318. m_hashMap.erase(m_hashMap.find(data.m_hash) );
  319. release(data.m_value);
  320. }
  321. else
  322. {
  323. ++ii;
  324. }
  325. }
  326. }
  327. void invalidate()
  328. {
  329. for (uint16_t ii = 0, num = m_alloc.getNumHandles(); ii < num; ++ii)
  330. {
  331. uint16_t handle = m_alloc.getHandleAt(ii);
  332. Data& data = m_data[handle];
  333. release(data.m_value);
  334. }
  335. m_hashMap.clear();
  336. m_alloc.reset();
  337. }
  338. uint32_t getCount() const
  339. {
  340. return uint32_t(m_hashMap.size() );
  341. }
  342. private:
  343. typedef stl::unordered_map<uint64_t, uint16_t> HashMap;
  344. HashMap m_hashMap;
  345. bx::HandleAllocLruT<MaxHandleT> m_alloc;
  346. struct Data
  347. {
  348. uint64_t m_hash;
  349. Ty m_value;
  350. uint16_t m_parent;
  351. };
  352. Data m_data[MaxHandleT];
  353. };
  354. class StateCache
  355. {
  356. public:
  357. void add(uint64_t _key, uint16_t _value)
  358. {
  359. invalidate(_key);
  360. m_hashMap.insert(stl::make_pair(_key, _value) );
  361. }
  362. uint16_t find(uint64_t _key)
  363. {
  364. HashMap::iterator it = m_hashMap.find(_key);
  365. if (it != m_hashMap.end() )
  366. {
  367. return it->second;
  368. }
  369. return UINT16_MAX;
  370. }
  371. void invalidate(uint64_t _key)
  372. {
  373. HashMap::iterator it = m_hashMap.find(_key);
  374. if (it != m_hashMap.end() )
  375. {
  376. m_hashMap.erase(it);
  377. }
  378. }
  379. void invalidate()
  380. {
  381. m_hashMap.clear();
  382. }
  383. uint32_t getCount() const
  384. {
  385. return uint32_t(m_hashMap.size() );
  386. }
  387. private:
  388. typedef stl::unordered_map<uint64_t, uint16_t> HashMap;
  389. HashMap m_hashMap;
  390. };
  391. inline bool hasVertexStreamChanged(const RenderDraw& _current, const RenderDraw& _new)
  392. {
  393. if (_current.m_streamMask != _new.m_streamMask
  394. || _current.m_instanceDataBuffer.idx != _new.m_instanceDataBuffer.idx
  395. || _current.m_instanceDataOffset != _new.m_instanceDataOffset
  396. || _current.m_instanceDataStride != _new.m_instanceDataStride)
  397. {
  398. return true;
  399. }
  400. for (uint32_t idx = 0, streamMask = _new.m_streamMask
  401. ; 0 != streamMask
  402. ; streamMask >>= 1, idx += 1
  403. )
  404. {
  405. const uint32_t ntz = bx::uint32_cnttz(streamMask);
  406. streamMask >>= ntz;
  407. idx += ntz;
  408. if (_current.m_stream[idx].m_handle.idx != _new.m_stream[idx].m_handle.idx
  409. || _current.m_stream[idx].m_startVertex != _new.m_stream[idx].m_startVertex)
  410. {
  411. return true;
  412. }
  413. }
  414. return false;
  415. }
  416. template<typename Ty>
  417. struct Profiler
  418. {
  419. Profiler(Frame* _frame, Ty& _gpuTimer, const char (*_viewName)[BGFX_CONFIG_MAX_VIEW_NAME], bool _enabled = true)
  420. : m_viewName(_viewName)
  421. , m_frame(_frame)
  422. , m_gpuTimer(_gpuTimer)
  423. , m_queryIdx(UINT32_MAX)
  424. , m_numViews(0)
  425. , m_enabled(_enabled && 0 != (_frame->m_debug & BGFX_DEBUG_PROFILER) )
  426. {
  427. }
  428. ~Profiler()
  429. {
  430. m_frame->m_perfStats.numViews = m_numViews;
  431. }
  432. void begin(uint16_t _view)
  433. {
  434. if (m_enabled)
  435. {
  436. ViewStats& viewStats = m_frame->m_perfStats.viewStats[m_numViews];
  437. viewStats.cpuTimeBegin = bx::getHPCounter();
  438. m_queryIdx = m_gpuTimer.begin(_view);
  439. viewStats.view = ViewId(_view);
  440. bx::strCopy(viewStats.name
  441. , BGFX_CONFIG_MAX_VIEW_NAME
  442. , &m_viewName[_view][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED]
  443. );
  444. }
  445. }
  446. void end()
  447. {
  448. if (m_enabled
  449. && UINT32_MAX != m_queryIdx)
  450. {
  451. m_gpuTimer.end(m_queryIdx);
  452. ViewStats& viewStats = m_frame->m_perfStats.viewStats[m_numViews];
  453. const typename Ty::Result& result = m_gpuTimer.m_result[viewStats.view];
  454. viewStats.cpuTimeEnd = bx::getHPCounter();
  455. viewStats.gpuTimeBegin = result.m_begin;
  456. viewStats.gpuTimeEnd = result.m_end;
  457. ++m_numViews;
  458. m_queryIdx = UINT32_MAX;
  459. }
  460. }
  461. const char (*m_viewName)[BGFX_CONFIG_MAX_VIEW_NAME];
  462. Frame* m_frame;
  463. Ty& m_gpuTimer;
  464. uint32_t m_queryIdx;
  465. uint16_t m_numViews;
  466. bool m_enabled;
  467. };
  468. } // namespace bgfx
  469. #endif // BGFX_RENDERER_H_HEADER_GUARD