diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 679f76a4c..774b9ff4b 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -887,7 +887,7 @@ namespace bgfx && 0 == m_draw.m_numIndices) { discard(); - ++m_frame->m_numDropped; + ++m_numDropped; return; } @@ -895,11 +895,13 @@ namespace bgfx if (BGFX_CONFIG_MAX_DRAW_CALLS-1 <= renderItemIdx) { discard(); - ++m_frame->m_numDropped; + ++m_numDropped; return; } - m_frame->m_uniformEnd = m_frame->m_uniformBuffer->getPos(); + ++m_numSubmitted; + + m_uniformEnd = m_uniformBuffer->getPos(); m_key.m_program = kInvalidHandle == _program.idx ? 0 @@ -922,8 +924,9 @@ namespace bgfx m_frame->m_sortKeys[renderItemIdx] = key; m_frame->m_sortValues[renderItemIdx] = RenderItemCount(renderItemIdx); - m_draw.m_uniformBegin = m_frame->m_uniformBegin; - m_draw.m_uniformEnd = m_frame->m_uniformEnd; + m_draw.m_uniformIdx = m_uniformIdx; + m_draw.m_uniformBegin = m_uniformBegin; + m_draw.m_uniformEnd = m_uniformEnd; m_draw.m_stateFlags |= m_stateFlags; uint32_t numVertices = UINT32_MAX; @@ -953,7 +956,7 @@ namespace bgfx { m_draw.clear(); m_bind.clear(); - m_frame->m_uniformBegin = m_frame->m_uniformEnd; + m_uniformBegin = m_uniformEnd; m_stateFlags = BGFX_STATE_NONE; } } @@ -975,11 +978,13 @@ namespace bgfx if (BGFX_CONFIG_MAX_DRAW_CALLS-1 <= renderItemIdx) { discard(); - ++m_frame->m_numDropped; + ++m_numDropped; return; } - m_frame->m_uniformEnd = m_frame->m_uniformBuffer->getPos(); + ++m_numSubmitted; + + m_uniformEnd = m_uniformBuffer->getPos(); m_compute.m_startMatrix = m_draw.m_startMatrix; m_compute.m_numMatrices = m_draw.m_numMatrices; @@ -997,14 +1002,15 @@ namespace bgfx m_frame->m_sortKeys[renderItemIdx] = key; m_frame->m_sortValues[renderItemIdx] = RenderItemCount(renderItemIdx); - m_compute.m_uniformBegin = m_frame->m_uniformBegin; - m_compute.m_uniformEnd = m_frame->m_uniformEnd; + m_compute.m_uniformIdx = m_uniformIdx; + m_compute.m_uniformBegin = m_uniformBegin; + m_compute.m_uniformEnd = m_uniformEnd; m_frame->m_renderItem[renderItemIdx].compute = m_compute; m_frame->m_renderItemBind[renderItemIdx] = m_bind; m_compute.clear(); m_bind.clear(); - m_frame->m_uniformBegin = m_frame->m_uniformEnd; + m_uniformBegin = m_uniformEnd; } void EncoderImpl::blit(uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, TextureHandle _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth) @@ -1437,7 +1443,7 @@ namespace bgfx frameNoRenderWait(); - m_encoder[0].begin(m_submit); + m_encoder[0].begin(m_submit, 0); m_encoder0 = reinterpret_cast(&m_encoder[0]); // Make sure renderer init is called from render thread. @@ -1691,9 +1697,9 @@ namespace bgfx return NULL; } - uint32_t idx = m_numEncoders++; + uint8_t idx = uint8_t(m_numEncoders++); encoder = &m_encoder[idx]; - encoder->begin(m_frame); + encoder->begin(m_submit, idx); } #endif // BGFX_CONFIG_MULTITHREADED @@ -1716,8 +1722,9 @@ namespace bgfx uint32_t Context::frame(bool _capture) { bx::MutexScope resourceApiScope(m_resourceApiLock); - bx::MutexScope encoderApiScope(m_encoderApiLock); + encoderApiWait(); + bx::MutexScope encoderApiScope(m_encoderApiLock); m_encoder[0].end(); m_submit->m_capture = _capture; @@ -1727,7 +1734,7 @@ namespace bgfx renderSemWait(); frameNoRenderWait(); - m_encoder[0].begin(m_submit); + m_encoder[0].begin(m_submit, 0); return m_frames; } diff --git a/src/bgfx_p.h b/src/bgfx_p.h index b91458bfe..48972f694 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -1110,13 +1110,9 @@ namespace bgfx uint32_t reserve(uint16_t* _num) { uint32_t num = *_num; - BX_WARN(m_num+num < BGFX_CONFIG_MAX_MATRIX_CACHE, "Matrix cache overflow. %d (max: %d)", m_num+num, BGFX_CONFIG_MAX_MATRIX_CACHE); - num = bx::uint32_min(num, BGFX_CONFIG_MAX_MATRIX_CACHE-m_num); - uint32_t first = m_num < BGFX_CONFIG_MAX_MATRIX_CACHE - ? m_num - : BGFX_CONFIG_MAX_MATRIX_CACHE - 1 - ; - m_num += num; + uint32_t first = bx::atomicFetchAndAddsat(&m_num, num, BGFX_CONFIG_MAX_MATRIX_CACHE - 1); + BX_WARN(first+num < BGFX_CONFIG_MAX_MATRIX_CACHE, "Matrix cache overflow. %d (max: %d)", first+num, BGFX_CONFIG_MAX_MATRIX_CACHE); + num = bx::uint32_min(num, BGFX_CONFIG_MAX_MATRIX_CACHE-1-first); *_num = (uint16_t)num; return first; } @@ -1165,17 +1161,16 @@ namespace bgfx uint32_t add(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) { - BX_CHECK(m_num+1 < BGFX_CONFIG_MAX_RECT_CACHE, "Rect cache overflow. %d (max: %d)", m_num, BGFX_CONFIG_MAX_RECT_CACHE); + const uint32_t first = bx::atomicFetchAndAddsat(&m_num, 1, BGFX_CONFIG_MAX_RECT_CACHE-1); + BX_CHECK(first+1 < BGFX_CONFIG_MAX_RECT_CACHE, "Rect cache overflow. %d (max: %d)", first, BGFX_CONFIG_MAX_RECT_CACHE); - uint32_t first = m_num; - Rect& rect = m_cache[m_num]; + Rect& rect = m_cache[first]; rect.m_x = _x; rect.m_y = _y; rect.m_width = _width; rect.m_height = _height; - m_num++; return first; } @@ -1460,6 +1455,7 @@ namespace bgfx m_instanceDataBuffer.idx = kInvalidHandle; m_indirectBuffer.idx = kInvalidHandle; m_occlusionQuery.idx = kInvalidHandle; + m_uniformIdx = UINT8_MAX; } bool setStreamBit(uint8_t _stream, VertexBufferHandle _handle) @@ -1490,6 +1486,7 @@ namespace bgfx uint16_t m_scissor; uint8_t m_submitFlags; uint8_t m_streamMask; + uint8_t m_uniformIdx; IndexBufferHandle m_indexBuffer; VertexBufferHandle m_instanceDataBuffer; @@ -1509,6 +1506,7 @@ namespace bgfx m_numZ = 0; m_numMatrices = 0; m_submitFlags = BGFX_SUBMIT_EYE_FIRST; + m_uniformIdx = UINT8_MAX; m_indirectBuffer.idx = kInvalidHandle; m_startIndirect = 0; @@ -1527,6 +1525,7 @@ namespace bgfx uint16_t m_numIndirect; uint16_t m_numMatrices; uint8_t m_submitFlags; + uint8_t m_uniformIdx; }; union RenderItem @@ -1697,8 +1696,7 @@ namespace bgfx BX_ALIGN_DECL_CACHE_LINE(struct) Frame { Frame() - : m_uniformMax(0) - , m_waitSubmit(0) + : m_waitSubmit(0) , m_waitRender(0) , m_hmdInitialized(false) , m_capture(false) @@ -1717,7 +1715,11 @@ namespace bgfx void create() { - m_uniformBuffer = UniformBuffer::create(); + for (uint32_t ii = 0; ii < BX_COUNTOF(m_uniformBuffer); ++ii) + { + m_uniformBuffer[ii] = UniformBuffer::create(); + } + reset(); start(); m_textVideoMem = BX_NEW(g_allocator, TextVideoMem); @@ -1725,7 +1727,10 @@ namespace bgfx void destroy() { - UniformBuffer::destroy(m_uniformBuffer); + for (uint32_t ii = 0; ii < BX_COUNTOF(m_uniformBuffer); ++ii) + { + UniformBuffer::destroy(m_uniformBuffer[ii]); + } BX_DELETE(g_allocator, m_textVideoMem); } @@ -1738,17 +1743,13 @@ namespace bgfx void start() { - m_uniformBegin = 0; - m_uniformEnd = 0; m_frameCache.reset(); m_numRenderItems = 0; - m_numDropped = 0; m_numBlitItems = 0; m_iboffset = 0; m_vboffset = 0; m_cmdPre.start(); m_cmdPost.start(); - m_uniformBuffer->reset(); m_capture = false; } @@ -1757,17 +1758,14 @@ namespace bgfx m_cmdPre.finish(); m_cmdPost.finish(); - m_uniformMax = bx::uint32_max(m_uniformMax, m_uniformBuffer->getPos() ); - m_uniformBuffer->finish(); - - if (0 < m_numDropped) - { - BX_TRACE("Too many draw calls: %d, dropped %d (max: %d)" - , m_numRenderItems+m_numDropped - , m_numDropped - , BGFX_CONFIG_MAX_DRAW_CALLS - ); - } +// if (0 < m_numDropped) +// { +// BX_TRACE("Too many draw calls: %d, dropped %d (max: %d)" +// , m_numRenderItems+m_numDropped +// , m_numDropped +// , BGFX_CONFIG_MAX_DRAW_CALLS +// ); +// } } void sort(); @@ -1876,15 +1874,11 @@ namespace bgfx uint32_t m_blitKeys[BGFX_CONFIG_MAX_BLIT_ITEMS+1]; BlitItem m_blitItem[BGFX_CONFIG_MAX_BLIT_ITEMS+1]; - uint32_t m_uniformBegin; - uint32_t m_uniformEnd; - uint32_t m_uniformMax; FrameCache m_frameCache; - UniformBuffer* m_uniformBuffer; + UniformBuffer* m_uniformBuffer[BGFX_CONFIG_MAX_ENCODERS]; uint32_t m_numRenderItems; - uint32_t m_numDropped; uint16_t m_numBlitItems; uint32_t m_iboffset; @@ -1981,13 +1975,25 @@ namespace bgfx discard(); } - void begin(Frame* _frame) + void begin(Frame* _frame, uint8_t _idx) { m_frame = _frame; + + m_uniformIdx = _idx; + m_uniformBegin = 0; + m_uniformEnd = 0; + + m_uniformBuffer = m_frame->m_uniformBuffer[m_uniformIdx]; + m_uniformBuffer->reset(); + + m_numSubmitted = 0; + m_numDropped = 0; } void end() { + m_uniformBuffer->finish(); + if (BX_ENABLED(BGFX_CONFIG_DEBUG_OCCLUSION) ) { m_occlusionQuerySet.clear(); @@ -2001,7 +2007,7 @@ namespace bgfx void setMarker(const char* _name) { - m_frame->m_uniformBuffer->writeMarker(_name); + m_uniformBuffer->writeMarker(_name); } void setUniform(UniformType::Enum _type, UniformHandle _handle, const void* _value, uint16_t _num) @@ -2016,8 +2022,8 @@ namespace bgfx m_uniformSet.insert(_handle.idx); } - UniformBuffer::update(m_frame->m_uniformBuffer); - m_frame->m_uniformBuffer->writeUniform(_type, _handle.idx, _value, _num); + UniformBuffer::update(m_uniformBuffer); + m_uniformBuffer->writeUniform(_type, _handle.idx, _value, _num); } void setState(uint64_t _state, uint32_t _rgba) @@ -2261,13 +2267,21 @@ namespace bgfx RenderCompute m_compute; RenderBind m_bind; + uint32_t m_numSubmitted; + uint32_t m_numDropped; + + uint32_t m_uniformBegin; + uint32_t m_uniformEnd; uint64_t m_stateFlags; uint32_t m_numVertices[BGFX_CONFIG_MAX_VERTEX_STREAMS]; + uint8_t m_uniformIdx; bool m_discard; typedef stl::unordered_set HandleSet; HandleSet m_uniformSet; HandleSet m_occlusionQuerySet; + + UniformBuffer* m_uniformBuffer; }; struct VertexDeclRef @@ -4345,9 +4359,9 @@ namespace bgfx } } - void encoderApiWait() + BX_NO_INLINE void encoderApiWait() { - for (uint32_t ii = 1; ii < m_numEncoders; ++ii) + for (uint32_t ii = 1, num = m_numEncoders; ii < num; ++ii) { m_encoderApiSem.wait(); } diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 12f52af7a..524f0c3f1 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -5810,7 +5810,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); bool programChanged = false; bool constantsChanged = compute.m_uniformBegin < compute.m_uniformEnd; - rendererUpdateUniforms(this, _render->m_uniformBuffer, compute.m_uniformBegin, compute.m_uniformEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd); if (key.m_program != programIdx) { @@ -6079,7 +6079,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); bool programChanged = false; bool constantsChanged = draw.m_uniformBegin < draw.m_uniformEnd; - rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_uniformBegin, draw.m_uniformEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd); if (key.m_program != programIdx) { @@ -6598,7 +6598,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } tvm.printf(10, pos++, 0x8e, " Indices: %7d ", statsNumIndices); - tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); +// tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); tvm.printf(10, pos++, 0x8e, " DVB size: %7d ", _render->m_vboffset); tvm.printf(10, pos++, 0x8e, " DIB size: %7d ", _render->m_iboffset); diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 42f832b09..960cddc44 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -5318,7 +5318,7 @@ data.NumQualityLevels = 0; if (compute.m_uniformBegin < compute.m_uniformEnd || currentProgramIdx != key.m_program) { - rendererUpdateUniforms(this, _render->m_uniformBuffer, compute.m_uniformBegin, compute.m_uniformEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd); currentProgramIdx = key.m_program; ProgramD3D12& program = m_program[currentProgramIdx]; @@ -5432,7 +5432,7 @@ data.NumQualityLevels = 0; primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT); } - rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_uniformBegin, draw.m_uniformEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd); if (isValid(draw.m_stream[0].m_handle) ) { @@ -5898,7 +5898,7 @@ data.NumQualityLevels = 0; } tvm.printf(10, pos++, 0x8e, " Indices: %7d ", statsNumIndices); - tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); +// tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); tvm.printf(10, pos++, 0x8e, " DVB size: %7d ", _render->m_vboffset); tvm.printf(10, pos++, 0x8e, " DIB size: %7d ", _render->m_iboffset); diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index ffa372ddc..b91a2933d 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -4083,7 +4083,7 @@ namespace bgfx { namespace d3d9 bool programChanged = false; bool constantsChanged = draw.m_uniformBegin < draw.m_uniformEnd; - rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_uniformBegin, draw.m_uniformEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd); if (key.m_program != programIdx) { @@ -4444,7 +4444,7 @@ namespace bgfx { namespace d3d9 } tvm.printf(10, pos++, 0x8e, " Indices: %7d ", statsNumIndices); - tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); +// tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); tvm.printf(10, pos++, 0x8e, " DVB size: %7d ", _render->m_vboffset); tvm.printf(10, pos++, 0x8e, " DIB size: %7d ", _render->m_iboffset); diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index cb485eb4e..f76c56357 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -6827,7 +6827,7 @@ namespace bgfx { namespace gl if (0 != barrier) { bool constantsChanged = compute.m_uniformBegin < compute.m_uniformEnd; - rendererUpdateUniforms(this, _render->m_uniformBuffer, compute.m_uniformBegin, compute.m_uniformEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd); if (constantsChanged && NULL != program.m_constantBuffer) @@ -7242,7 +7242,7 @@ namespace bgfx { namespace gl bool programChanged = false; bool constantsChanged = draw.m_uniformBegin < draw.m_uniformEnd; bool bindAttribs = false; - rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_uniformBegin, draw.m_uniformEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd); if (key.m_program != programIdx) { @@ -7710,7 +7710,7 @@ namespace bgfx { namespace gl } tvm.printf(10, pos++, 0x8e, " Indices: %7d ", statsNumIndices); - tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); +// tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); tvm.printf(10, pos++, 0x8e, " DVB size: %7d ", _render->m_vboffset); tvm.printf(10, pos++, 0x8e, " DIB size: %7d ", _render->m_iboffset); diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index db4ba868c..18b1dd2db 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -3961,7 +3961,7 @@ BX_UNUSED(currentSamplerStateIdx); if (compute.m_uniformBegin < compute.m_uniformEnd || currentProgramIdx != key.m_program) { - rendererUpdateUniforms(this, _render->m_uniformBuffer, compute.m_uniformBegin, compute.m_uniformEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd); currentProgramIdx = key.m_program; ProgramVK& program = m_program[currentProgramIdx]; @@ -4073,7 +4073,7 @@ BX_UNUSED(currentSamplerStateIdx); primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT); } - rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_uniformBegin, draw.m_uniformEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd); if (isValid(draw.m_stream[0].m_handle) ) { @@ -4529,7 +4529,7 @@ BX_UNUSED(presentMin, presentMax); } tvm.printf(10, pos++, 0x8e, " Indices: %7d ", statsNumIndices); - tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); +// tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); tvm.printf(10, pos++, 0x8e, " DVB size: %7d ", _render->m_vboffset); tvm.printf(10, pos++, 0x8e, " DIB size: %7d ", _render->m_iboffset);