renderer.h 12 KB

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