| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 |
- /*
- * Copyright 2011-2017 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
- */
- #ifndef BGFX_RENDERER_H_HEADER_GUARD
- #define BGFX_RENDERER_H_HEADER_GUARD
- #include "bgfx_p.h"
- namespace bgfx
- {
- struct BlitState
- {
- BlitState(const Frame* _frame)
- : m_frame(_frame)
- , m_item(0)
- {
- m_key.decode(_frame->m_blitKeys[0]);
- }
- bool hasItem(uint16_t _view) const
- {
- return m_item < m_frame->m_numBlitItems
- && m_key.m_view <= _view
- ;
- }
- const BlitItem& advance()
- {
- const BlitItem& bi = m_frame->m_blitItem[m_key.m_item];
- ++m_item;
- m_key.decode(m_frame->m_blitKeys[m_item]);
- return bi;
- }
- const Frame* m_frame;
- BlitKey m_key;
- uint16_t m_item;
- };
- struct ViewState
- {
- ViewState()
- {
- }
- ViewState(Frame* _frame, bool _hmdEnabled)
- {
- reset(_frame, _hmdEnabled);
- }
- void reset(Frame* _frame, bool _hmdEnabled)
- {
- m_alphaRef = 0.0f;
- m_invViewCached = UINT16_MAX;
- m_invProjCached = UINT16_MAX;
- m_invViewProjCached = UINT16_MAX;
- m_view[0] = _frame->m_view;
- m_view[1] = m_viewTmp[1];
- if (_hmdEnabled)
- {
- HMD& hmd = _frame->m_hmd;
- m_view[0] = m_viewTmp[0];
- Matrix4 viewAdjust;
- bx::mtxIdentity(viewAdjust.un.val);
- for (uint32_t eye = 0; eye < 2; ++eye)
- {
- const HMD::Eye& hmdEye = hmd.eye[eye];
- viewAdjust.un.val[12] = hmdEye.viewOffset[0];
- viewAdjust.un.val[13] = hmdEye.viewOffset[1];
- viewAdjust.un.val[14] = hmdEye.viewOffset[2];
- for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
- {
- if (BGFX_VIEW_STEREO == (_frame->m_viewFlags[ii] & BGFX_VIEW_STEREO) )
- {
- bx::float4x4_mul(&m_view[eye][ii].un.f4x4
- , &_frame->m_view[ii].un.f4x4
- , &viewAdjust.un.f4x4
- );
- }
- else
- {
- bx::memCopy(&m_view[0][ii].un.f4x4, &_frame->m_view[ii].un.f4x4, sizeof(Matrix4) );
- }
- }
- }
- }
- for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
- {
- for (uint32_t eye = 0; eye < uint32_t(_hmdEnabled)+1; ++eye)
- {
- bx::float4x4_mul(&m_viewProj[eye][ii].un.f4x4
- , &m_view[eye][ii].un.f4x4
- , &_frame->m_proj[eye][ii].un.f4x4
- );
- }
- }
- }
- template<uint16_t mtxRegs, typename RendererContext, typename Program, typename Draw>
- void setPredefined(RendererContext* _renderer, uint16_t _view, uint8_t _eye, const Program& _program, const Frame* _frame, const Draw& _draw)
- {
- for (uint32_t ii = 0, num = _program.m_numPredefined; ii < num; ++ii)
- {
- const PredefinedUniform& predefined = _program.m_predefined[ii];
- uint8_t flags = predefined.m_type&BGFX_UNIFORM_FRAGMENTBIT;
- switch (predefined.m_type&(~BGFX_UNIFORM_FRAGMENTBIT) )
- {
- case PredefinedUniform::ViewRect:
- {
- float frect[4];
- frect[0] = m_rect.m_x;
- frect[1] = m_rect.m_y;
- frect[2] = m_rect.m_width;
- frect[3] = m_rect.m_height;
- _renderer->setShaderUniform4f(flags
- , predefined.m_loc
- , &frect[0]
- , 1
- );
- }
- break;
- case PredefinedUniform::ViewTexel:
- {
- float frect[4];
- frect[0] = 1.0f/float(m_rect.m_width);
- frect[1] = 1.0f/float(m_rect.m_height);
- _renderer->setShaderUniform4f(flags
- , predefined.m_loc
- , &frect[0]
- , 1
- );
- }
- break;
- case PredefinedUniform::View:
- {
- _renderer->setShaderUniform4x4f(flags
- , predefined.m_loc
- , m_view[_eye][_view].un.val
- , bx::uint32_min(mtxRegs, predefined.m_count)
- );
- }
- break;
- case PredefinedUniform::InvView:
- {
- uint16_t viewEye = (_view << 1) | _eye;
- if (viewEye != m_invViewCached)
- {
- m_invViewCached = viewEye;
- bx::float4x4_inverse(&m_invView.un.f4x4
- , &m_view[_eye][_view].un.f4x4
- );
- }
- _renderer->setShaderUniform4x4f(flags
- , predefined.m_loc
- , m_invView.un.val
- , bx::uint32_min(mtxRegs, predefined.m_count)
- );
- }
- break;
- case PredefinedUniform::Proj:
- {
- _renderer->setShaderUniform4x4f(flags
- , predefined.m_loc
- , _frame->m_proj[_eye][_view].un.val
- , bx::uint32_min(mtxRegs, predefined.m_count)
- );
- }
- break;
- case PredefinedUniform::InvProj:
- {
- uint16_t viewEye = (_view << 1) | _eye;
- if (viewEye != m_invProjCached)
- {
- m_invProjCached = viewEye;
- bx::float4x4_inverse(&m_invProj.un.f4x4
- , &_frame->m_proj[_eye][_view].un.f4x4
- );
- }
- _renderer->setShaderUniform4x4f(flags
- , predefined.m_loc
- , m_invProj.un.val
- , bx::uint32_min(mtxRegs, predefined.m_count)
- );
- }
- break;
- case PredefinedUniform::ViewProj:
- {
- _renderer->setShaderUniform4x4f(flags
- , predefined.m_loc
- , m_viewProj[_eye][_view].un.val
- , bx::uint32_min(mtxRegs, predefined.m_count)
- );
- }
- break;
- case PredefinedUniform::InvViewProj:
- {
- uint16_t viewEye = (_view << 1) | _eye;
- if (viewEye != m_invViewProjCached)
- {
- m_invViewProjCached = viewEye;
- bx::float4x4_inverse(&m_invViewProj.un.f4x4
- , &m_viewProj[_eye][_view].un.f4x4
- );
- }
- _renderer->setShaderUniform4x4f(flags
- , predefined.m_loc
- , m_invViewProj.un.val
- , bx::uint32_min(mtxRegs, predefined.m_count)
- );
- }
- break;
- case PredefinedUniform::Model:
- {
- const Matrix4& model = _frame->m_matrixCache.m_cache[_draw.m_matrix];
- _renderer->setShaderUniform4x4f(flags
- , predefined.m_loc
- , model.un.val
- , bx::uint32_min(_draw.m_num*mtxRegs, predefined.m_count)
- );
- }
- break;
- case PredefinedUniform::ModelView:
- {
- Matrix4 modelView;
- const Matrix4& model = _frame->m_matrixCache.m_cache[_draw.m_matrix];
- bx::float4x4_mul(&modelView.un.f4x4
- , &model.un.f4x4
- , &m_view[_eye][_view].un.f4x4
- );
- _renderer->setShaderUniform4x4f(flags
- , predefined.m_loc
- , modelView.un.val
- , bx::uint32_min(mtxRegs, predefined.m_count)
- );
- }
- break;
- case PredefinedUniform::ModelViewProj:
- {
- Matrix4 modelViewProj;
- const Matrix4& model = _frame->m_matrixCache.m_cache[_draw.m_matrix];
- bx::float4x4_mul(&modelViewProj.un.f4x4
- , &model.un.f4x4
- , &m_viewProj[_eye][_view].un.f4x4
- );
- _renderer->setShaderUniform4x4f(flags
- , predefined.m_loc
- , modelViewProj.un.val
- , bx::uint32_min(mtxRegs, predefined.m_count)
- );
- }
- break;
- case PredefinedUniform::AlphaRef:
- {
- _renderer->setShaderUniform4f(flags
- , predefined.m_loc
- , &m_alphaRef
- , 1
- );
- }
- break;
- default:
- BX_CHECK(false, "predefined %d not handled", predefined.m_type);
- break;
- }
- }
- }
- Matrix4 m_viewTmp[2][BGFX_CONFIG_MAX_VIEWS];
- Matrix4 m_viewProj[2][BGFX_CONFIG_MAX_VIEWS];
- Matrix4* m_view[2];
- Rect m_rect;
- Matrix4 m_invView;
- Matrix4 m_invProj;
- Matrix4 m_invViewProj;
- float m_alphaRef;
- uint16_t m_invViewCached;
- uint16_t m_invProjCached;
- uint16_t m_invViewProjCached;
- };
- template<typename Ty>
- inline void release(Ty)
- {
- }
- template <typename Ty, uint16_t MaxHandleT>
- class StateCacheLru
- {
- public:
- Ty* add(uint64_t _key, const Ty& _value, uint16_t _parent)
- {
- uint16_t handle = m_alloc.alloc();
- if (UINT16_MAX == handle)
- {
- uint16_t back = m_alloc.getBack();
- invalidate(back);
- handle = m_alloc.alloc();
- }
- BX_CHECK(UINT16_MAX != handle, "Failed to find handle.");
- Data& data = m_data[handle];
- data.m_hash = _key;
- data.m_value = _value;
- data.m_parent = _parent;
- m_hashMap.insert(stl::make_pair(_key, handle) );
- return &m_data[handle].m_value;
- }
- Ty* find(uint64_t _key)
- {
- HashMap::iterator it = m_hashMap.find(_key);
- if (it != m_hashMap.end() )
- {
- uint16_t handle = it->second;
- m_alloc.touch(handle);
- return &m_data[handle].m_value;
- }
- return NULL;
- }
- void invalidate(uint64_t _key)
- {
- HashMap::iterator it = m_hashMap.find(_key);
- if (it != m_hashMap.end() )
- {
- uint16_t handle = it->second;
- m_alloc.free(handle);
- m_hashMap.erase(it);
- release(m_data[handle].m_value);
- }
- }
- void invalidate(uint16_t _handle)
- {
- if (m_alloc.isValid(_handle) )
- {
- m_alloc.free(_handle);
- Data& data = m_data[_handle];
- m_hashMap.erase(m_hashMap.find(data.m_hash) );
- release(data.m_value);
- }
- }
- void invalidateWithParent(uint16_t _parent)
- {
- for (uint16_t ii = 0; ii < m_alloc.getNumHandles();)
- {
- uint16_t handle = m_alloc.getHandleAt(ii);
- Data& data = m_data[handle];
- if (data.m_parent == _parent)
- {
- m_alloc.free(handle);
- m_hashMap.erase(m_hashMap.find(data.m_hash) );
- release(data.m_value);
- }
- else
- {
- ++ii;
- }
- }
- }
- void invalidate()
- {
- for (uint16_t ii = 0, num = m_alloc.getNumHandles(); ii < num; ++ii)
- {
- uint16_t handle = m_alloc.getHandleAt(ii);
- Data& data = m_data[handle];
- release(data.m_value);
- }
- m_hashMap.clear();
- m_alloc.reset();
- }
- uint32_t getCount() const
- {
- return uint32_t(m_hashMap.size() );
- }
- private:
- typedef stl::unordered_map<uint64_t, uint16_t> HashMap;
- HashMap m_hashMap;
- bx::HandleAllocLruT<MaxHandleT> m_alloc;
- struct Data
- {
- uint64_t m_hash;
- Ty m_value;
- uint16_t m_parent;
- };
- Data m_data[MaxHandleT];
- };
- class StateCache
- {
- public:
- void add(uint64_t _key, uint16_t _value)
- {
- invalidate(_key);
- m_hashMap.insert(stl::make_pair(_key, _value) );
- }
- uint16_t find(uint64_t _key)
- {
- HashMap::iterator it = m_hashMap.find(_key);
- if (it != m_hashMap.end() )
- {
- return it->second;
- }
- return UINT16_MAX;
- }
- void invalidate(uint64_t _key)
- {
- HashMap::iterator it = m_hashMap.find(_key);
- if (it != m_hashMap.end() )
- {
- m_hashMap.erase(it);
- }
- }
- void invalidate()
- {
- m_hashMap.clear();
- }
- uint32_t getCount() const
- {
- return uint32_t(m_hashMap.size() );
- }
- private:
- typedef stl::unordered_map<uint64_t, uint16_t> HashMap;
- HashMap m_hashMap;
- };
- inline bool hasVertexStreamChanged(const RenderDraw& _current, const RenderDraw& _new)
- {
- if (_current.m_streamMask != _new.m_streamMask
- || _current.m_instanceDataBuffer.idx != _new.m_instanceDataBuffer.idx
- || _current.m_instanceDataOffset != _new.m_instanceDataOffset
- || _current.m_instanceDataStride != _new.m_instanceDataStride)
- {
- return true;
- }
- for (uint32_t idx = 0, streamMask = _new.m_streamMask, ntz = bx::uint32_cnttz(streamMask)
- ; 0 != streamMask
- ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask)
- )
- {
- streamMask >>= ntz;
- idx += ntz;
- if (_current.m_stream[idx].m_handle.idx != _new.m_stream[idx].m_handle.idx
- || _current.m_stream[idx].m_startVertex != _new.m_stream[idx].m_startVertex)
- {
- return true;
- }
- }
- return false;
- }
- template<typename Ty>
- struct Profiler
- {
- Profiler(Frame* _frame, Ty& _gpuTimer, const char (*_viewName)[BGFX_CONFIG_MAX_VIEW_NAME], bool _enabled = true)
- : m_viewName(_viewName)
- , m_frame(_frame)
- , m_gpuTimer(_gpuTimer)
- , m_queryIdx(UINT32_MAX)
- , m_numViews(0)
- , m_enabled(_enabled && 0 != (_frame->m_debug & BGFX_DEBUG_PROFILER) )
- {
- }
- ~Profiler()
- {
- m_frame->m_perfStats.numViews = m_numViews;
- }
- void begin(uint16_t _view)
- {
- if (m_enabled)
- {
- ViewStats& viewStats = m_frame->m_perfStats.viewStats[m_numViews];
- viewStats.cpuTimeElapsed = -bx::getHPCounter();
- m_queryIdx = m_gpuTimer.begin(_view);
- viewStats.view = uint8_t(_view);
- bx::strCopy(viewStats.name
- , BGFX_CONFIG_MAX_VIEW_NAME
- , &m_viewName[_view][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED]
- );
- }
- }
- void end()
- {
- if (m_enabled
- && UINT32_MAX != m_queryIdx)
- {
- m_gpuTimer.end(m_queryIdx);
- ViewStats& viewStats = m_frame->m_perfStats.viewStats[m_numViews];
- const typename Ty::Result& result = m_gpuTimer.m_result[viewStats.view];
- viewStats.cpuTimeElapsed += bx::getHPCounter();
- viewStats.gpuTimeElapsed = result.m_end - result.m_begin;
- ++m_numViews;
- m_queryIdx = UINT32_MAX;
- }
- }
- const char (*m_viewName)[BGFX_CONFIG_MAX_VIEW_NAME];
- Frame* m_frame;
- Ty& m_gpuTimer;
- uint32_t m_queryIdx;
- uint16_t m_numViews;
- bool m_enabled;
- };
- } // namespace bgfx
- #endif // BGFX_RENDERER_H_HEADER_GUARD
|