renderer.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  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] = 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>
  280. inline void release(Ty)
  281. {
  282. }
  283. template <typename Ty, uint16_t MaxHandleT>
  284. class StateCacheLru
  285. {
  286. public:
  287. Ty* add(uint64_t _key, const Ty& _value, uint16_t _parent)
  288. {
  289. uint16_t handle = m_alloc.alloc();
  290. if (UINT16_MAX == handle)
  291. {
  292. uint16_t back = m_alloc.getBack();
  293. invalidate(back);
  294. handle = m_alloc.alloc();
  295. }
  296. BX_CHECK(UINT16_MAX != handle, "Failed to find handle.");
  297. Data& data = m_data[handle];
  298. data.m_hash = _key;
  299. data.m_value = _value;
  300. data.m_parent = _parent;
  301. m_hashMap.insert(stl::make_pair(_key, handle) );
  302. return &m_data[handle].m_value;
  303. }
  304. Ty* find(uint64_t _key)
  305. {
  306. HashMap::iterator it = m_hashMap.find(_key);
  307. if (it != m_hashMap.end() )
  308. {
  309. uint16_t handle = it->second;
  310. m_alloc.touch(handle);
  311. return &m_data[handle].m_value;
  312. }
  313. return NULL;
  314. }
  315. void invalidate(uint64_t _key)
  316. {
  317. HashMap::iterator it = m_hashMap.find(_key);
  318. if (it != m_hashMap.end() )
  319. {
  320. uint16_t handle = it->second;
  321. m_alloc.free(handle);
  322. m_hashMap.erase(it);
  323. release(m_data[handle].m_value);
  324. }
  325. }
  326. void invalidate(uint16_t _handle)
  327. {
  328. if (m_alloc.isValid(_handle) )
  329. {
  330. m_alloc.free(_handle);
  331. Data& data = m_data[_handle];
  332. m_hashMap.erase(m_hashMap.find(data.m_hash) );
  333. release(data.m_value);
  334. }
  335. }
  336. void invalidateWithParent(uint16_t _parent)
  337. {
  338. for (uint16_t ii = 0; ii < m_alloc.getNumHandles();)
  339. {
  340. uint16_t handle = m_alloc.getHandleAt(ii);
  341. Data& data = m_data[handle];
  342. if (data.m_parent == _parent)
  343. {
  344. m_alloc.free(handle);
  345. m_hashMap.erase(m_hashMap.find(data.m_hash) );
  346. release(data.m_value);
  347. }
  348. else
  349. {
  350. ++ii;
  351. }
  352. }
  353. }
  354. void invalidate()
  355. {
  356. for (uint16_t ii = 0, num = m_alloc.getNumHandles(); ii < num; ++ii)
  357. {
  358. uint16_t handle = m_alloc.getHandleAt(ii);
  359. Data& data = m_data[handle];
  360. release(data.m_value);
  361. }
  362. m_hashMap.clear();
  363. m_alloc.reset();
  364. }
  365. uint32_t getCount() const
  366. {
  367. return uint32_t(m_hashMap.size() );
  368. }
  369. private:
  370. typedef stl::unordered_map<uint64_t, uint16_t> HashMap;
  371. HashMap m_hashMap;
  372. bx::HandleAllocLruT<MaxHandleT> m_alloc;
  373. struct Data
  374. {
  375. uint64_t m_hash;
  376. Ty m_value;
  377. uint16_t m_parent;
  378. };
  379. Data m_data[MaxHandleT];
  380. };
  381. class StateCache
  382. {
  383. public:
  384. void add(uint64_t _key, uint16_t _value)
  385. {
  386. invalidate(_key);
  387. m_hashMap.insert(stl::make_pair(_key, _value) );
  388. }
  389. uint16_t find(uint64_t _key)
  390. {
  391. HashMap::iterator it = m_hashMap.find(_key);
  392. if (it != m_hashMap.end() )
  393. {
  394. return it->second;
  395. }
  396. return UINT16_MAX;
  397. }
  398. void invalidate(uint64_t _key)
  399. {
  400. HashMap::iterator it = m_hashMap.find(_key);
  401. if (it != m_hashMap.end() )
  402. {
  403. m_hashMap.erase(it);
  404. }
  405. }
  406. void invalidate()
  407. {
  408. m_hashMap.clear();
  409. }
  410. uint32_t getCount() const
  411. {
  412. return uint32_t(m_hashMap.size() );
  413. }
  414. private:
  415. typedef stl::unordered_map<uint64_t, uint16_t> HashMap;
  416. HashMap m_hashMap;
  417. };
  418. inline bool hasVertexStreamChanged(const RenderDraw& _current, const RenderDraw& _new)
  419. {
  420. if (_current.m_streamMask != _new.m_streamMask
  421. || _current.m_instanceDataBuffer.idx != _new.m_instanceDataBuffer.idx
  422. || _current.m_instanceDataOffset != _new.m_instanceDataOffset
  423. || _current.m_instanceDataStride != _new.m_instanceDataStride)
  424. {
  425. return true;
  426. }
  427. for (uint32_t idx = 0, streamMask = _new.m_streamMask, ntz = bx::uint32_cnttz(streamMask)
  428. ; 0 != streamMask
  429. ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask)
  430. )
  431. {
  432. streamMask >>= ntz;
  433. idx += ntz;
  434. if (_current.m_stream[idx].m_handle.idx != _new.m_stream[idx].m_handle.idx
  435. || _current.m_stream[idx].m_startVertex != _new.m_stream[idx].m_startVertex)
  436. {
  437. return true;
  438. }
  439. }
  440. return false;
  441. }
  442. template<typename Ty>
  443. struct Profiler
  444. {
  445. Profiler(Frame* _frame, Ty& _gpuTimer, const char (*_viewName)[BGFX_CONFIG_MAX_VIEW_NAME], bool _enabled = true)
  446. : m_viewName(_viewName)
  447. , m_frame(_frame)
  448. , m_gpuTimer(_gpuTimer)
  449. , m_queryIdx(UINT32_MAX)
  450. , m_numViews(0)
  451. , m_enabled(_enabled && 0 != (_frame->m_debug & BGFX_DEBUG_PROFILER) )
  452. {
  453. }
  454. ~Profiler()
  455. {
  456. m_frame->m_perfStats.numViews = m_numViews;
  457. }
  458. void begin(uint16_t _view)
  459. {
  460. if (m_enabled)
  461. {
  462. ViewStats& viewStats = m_frame->m_perfStats.viewStats[m_numViews];
  463. viewStats.cpuTimeElapsed = -bx::getHPCounter();
  464. m_queryIdx = m_gpuTimer.begin(_view);
  465. viewStats.view = ViewId(_view);
  466. bx::strCopy(viewStats.name
  467. , BGFX_CONFIG_MAX_VIEW_NAME
  468. , &m_viewName[_view][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED]
  469. );
  470. }
  471. }
  472. void end()
  473. {
  474. if (m_enabled
  475. && UINT32_MAX != m_queryIdx)
  476. {
  477. m_gpuTimer.end(m_queryIdx);
  478. ViewStats& viewStats = m_frame->m_perfStats.viewStats[m_numViews];
  479. const typename Ty::Result& result = m_gpuTimer.m_result[viewStats.view];
  480. viewStats.cpuTimeElapsed += bx::getHPCounter();
  481. viewStats.gpuTimeElapsed = result.m_end - result.m_begin;
  482. ++m_numViews;
  483. m_queryIdx = UINT32_MAX;
  484. }
  485. }
  486. const char (*m_viewName)[BGFX_CONFIG_MAX_VIEW_NAME];
  487. Frame* m_frame;
  488. Ty& m_gpuTimer;
  489. uint32_t m_queryIdx;
  490. uint16_t m_numViews;
  491. bool m_enabled;
  492. };
  493. } // namespace bgfx
  494. #endif // BGFX_RENDERER_H_HEADER_GUARD