renderer.h 12 KB

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