renderer.h 13 KB

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