Sized handle allocators, timer query rings and free handle queues by use. (#4025)

This commit is contained in:
Branimir Karadžić
2026-10-05 02:56:08 +00:00
committed by GitHub
parent 01e69a6307
commit e13b87cdd9
10 changed files with 293 additions and 223 deletions
+71 -61
View File
@@ -2588,65 +2588,75 @@ namespace bgfx
if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
{
#define CHECK_HANDLE_LEAK(_name, _handleAlloc) \
BX_MACRO_BLOCK_BEGIN \
if (0 != _handleAlloc.getNumHandles() ) \
{ \
BX_TRACE("LEAK: %s %d (max: %d)" \
, _name \
, _handleAlloc.getNumHandles() \
, _handleAlloc.getMaxHandles() \
); \
for (uint16_t ii = 0, num = _handleAlloc.getNumHandles(); ii < num; ++ii) \
{ \
BX_TRACE("\t%3d: %4d", ii, _handleAlloc.getHandleAt(ii) ); \
} \
} \
#define CHECK_HANDLE_LEAK(_name, _handleAlloc) \
BX_MACRO_BLOCK_BEGIN \
if (0 != _handleAlloc.getNumHandles() ) \
{ \
BX_TRACE("LEAK: %s %d (max: %d)" \
, _name \
, _handleAlloc.getNumHandles() \
, _handleAlloc.getMaxHandles() \
); \
uint16_t ii = 0; BX_UNUSED(ii); \
for (uint16_t idx = _handleAlloc.findFirst() \
; bx::kInvalidHandle != idx \
; idx = _handleAlloc.findNext(idx), ++ii \
) \
{ \
BX_TRACE("\t%3d: %4d", ii, idx); \
} \
} \
BX_MACRO_BLOCK_END
#define CHECK_HANDLE_LEAK_NAME(_name, _handleAlloc, _type, _ref) \
BX_MACRO_BLOCK_BEGIN \
if (0 != _handleAlloc.getNumHandles() ) \
{ \
BX_TRACE("LEAK: %s %d (max: %d)" \
, _name \
, _handleAlloc.getNumHandles() \
, _handleAlloc.getMaxHandles() \
); \
for (uint16_t ii = 0, num = _handleAlloc.getNumHandles(); ii < num; ++ii) \
{ \
uint16_t idx = _handleAlloc.getHandleAt(ii); \
const _type& ref = _ref[idx]; BX_UNUSED(ref); \
BX_TRACE("\t%3d: %4d %s" \
, ii \
, idx \
, ref.m_name.getCPtr() \
); \
} \
} \
#define CHECK_HANDLE_LEAK_NAME(_name, _handleAlloc, _type, _ref) \
BX_MACRO_BLOCK_BEGIN \
if (0 != _handleAlloc.getNumHandles() ) \
{ \
BX_TRACE("LEAK: %s %d (max: %d)" \
, _name \
, _handleAlloc.getNumHandles() \
, _handleAlloc.getMaxHandles() \
); \
uint16_t ii = 0; BX_UNUSED(ii); \
for (uint16_t idx = _handleAlloc.findFirst() \
; bx::kInvalidHandle != idx \
; idx = _handleAlloc.findNext(idx), ++ii \
) \
{ \
const _type& ref = _ref[idx]; BX_UNUSED(ref); \
BX_TRACE("\t%3d: %4d %s" \
, ii \
, idx \
, ref.m_name.getCPtr() \
); \
} \
} \
BX_MACRO_BLOCK_END
#define CHECK_HANDLE_LEAK_RC_NAME(_name, _handleAlloc, _type, _ref) \
BX_MACRO_BLOCK_BEGIN \
if (0 != _handleAlloc.getNumHandles() ) \
{ \
BX_TRACE("LEAK: %s %d (max: %d)" \
, _name \
, _handleAlloc.getNumHandles() \
, _handleAlloc.getMaxHandles() \
); \
for (uint16_t ii = 0, num = _handleAlloc.getNumHandles(); ii < num; ++ii) \
{ \
uint16_t idx = _handleAlloc.getHandleAt(ii); \
const _type& ref = _ref[idx]; BX_UNUSED(ref); \
BX_TRACE("\t%3d: %4d %s (count %d)" \
, ii \
, idx \
, ref.m_name.getCPtr() \
, ref.m_refCount \
); \
} \
} \
#define CHECK_HANDLE_LEAK_RC_NAME(_name, _handleAlloc, _type, _ref) \
BX_MACRO_BLOCK_BEGIN \
if (0 != _handleAlloc.getNumHandles() ) \
{ \
BX_TRACE("LEAK: %s %d (max: %d)" \
, _name \
, _handleAlloc.getNumHandles() \
, _handleAlloc.getMaxHandles() \
); \
uint16_t ii = 0; BX_UNUSED(ii); \
for (uint16_t idx = _handleAlloc.findFirst() \
; bx::kInvalidHandle != idx \
; idx = _handleAlloc.findNext(idx), ++ii \
) \
{ \
const _type& ref = _ref[idx]; BX_UNUSED(ref); \
BX_TRACE("\t%3d: %4d %s (count %d)" \
, ii \
, idx \
, ref.m_name.getCPtr() \
, ref.m_refCount \
); \
} \
} \
BX_MACRO_BLOCK_END
CHECK_HANDLE_LEAK ("DynamicIndexBufferHandle", m_dynamicIndexBufferHandle );
@@ -2667,17 +2677,17 @@ namespace bgfx
void Context::freeDynamicBuffers()
{
for (uint16_t ii = 0, num = m_numFreeDynamicIndexBufferHandles; ii < num; ++ii)
for (uint16_t ii = 0, num = m_freeDynamicIndexBuffer.getNumQueued(); ii < num; ++ii)
{
destroyDynamicIndexBufferInternal(m_freeDynamicIndexBufferHandle[ii]);
destroyDynamicIndexBufferInternal(m_freeDynamicIndexBuffer.get(ii) );
}
m_numFreeDynamicIndexBufferHandles = 0;
m_freeDynamicIndexBuffer.reset();
for (uint16_t ii = 0, num = m_numFreeDynamicVertexBufferHandles; ii < num; ++ii)
for (uint16_t ii = 0, num = m_freeDynamicVertexBuffer.getNumQueued(); ii < num; ++ii)
{
destroyDynamicVertexBufferInternal(m_freeDynamicVertexBufferHandle[ii]);
destroyDynamicVertexBufferInternal(m_freeDynamicVertexBuffer.get(ii) );
}
m_numFreeDynamicVertexBufferHandles = 0;
m_freeDynamicVertexBuffer.reset();
for (uint16_t ii = 0, num = m_numFreeOcclusionQueryHandles; ii < num; ++ii)
{
+154 -148
View File
@@ -2870,6 +2870,7 @@ namespace bgfx
uint32_t m_size;
uint16_t m_stride;
uint16_t m_flags;
VertexLayoutHandle m_layoutHandle = BGFX_INVALID_HANDLE;
};
struct BufferRef
@@ -2961,7 +2962,7 @@ namespace bgfx
uint32_t m_startVertex;
uint32_t m_numVertices;
uint16_t m_stride;
VertexLayoutHandle m_layoutHandle;
VertexLayoutHandle m_layoutHandle = BGFX_INVALID_HANDLE;
uint16_t m_flags;
};
@@ -3706,10 +3707,10 @@ namespace bgfx
void create()
{
bx::memSet(m_used, 0, sizeof(m_used) );
bx::memSet(m_touched, 0, sizeof(m_touched) );
m_alloc.reset();
m_alloc.alloc();
m_used[0] = 1;
bx::memSet(m_touched, 0, sizeof(m_touched) );
}
void destroy()
@@ -3724,44 +3725,36 @@ namespace bgfx
uint16_t alloc()
{
for (uint32_t blockIdx = 0; blockIdx < kNumBlocks; ++blockIdx)
const uint16_t idx = m_alloc.alloc();
if (bx::kInvalidHandle == idx
|| idx >= kNumNames)
{
const uint64_t avail = ~m_used[blockIdx];
if (0 != avail)
{
const uint32_t bit = bx::countTrailingZeros(avail);
const uint32_t idx = blockIdx*kBlock + bit;
if (idx >= kNumNames)
{
break;
}
#if BGFX_CONFIG_DYNAMIC_FRAME_STORAGE
if (NULL == m_block[blockIdx])
{
char* block = (char*)bx::alloc(g_allocator, kBlock*kNameSize);
bx::memSet(block, 0, kBlock*kNameSize);
bx::atomicExchangePtr( (void**)&m_block[blockIdx], block);
}
#endif // BGFX_CONFIG_DYNAMIC_FRAME_STORAGE
m_used[blockIdx] |= UINT64_C(1) << bit;
m_touched[blockIdx] = true;
return uint16_t(idx);
}
BX_ASSERT(false, "Out of view names.");
m_alloc.free(idx);
return 0;
}
BX_ASSERT(false, "Out of view names.");
return 0;
const uint32_t blockIdx = idx / kBlock;
#if BGFX_CONFIG_DYNAMIC_FRAME_STORAGE
if (NULL == m_block[blockIdx])
{
char* block = (char*)bx::alloc(g_allocator, kBlock*kNameSize);
bx::memSet(block, 0, kBlock*kNameSize);
bx::atomicExchangePtr( (void**)&m_block[blockIdx], block);
}
#endif // BGFX_CONFIG_DYNAMIC_FRAME_STORAGE
m_touched[blockIdx] = true;
return idx;
}
void free(uint16_t _idx)
{
m_used[_idx / kBlock] &= ~(UINT64_C(1) << (_idx & kBlockMask) );
m_alloc.free(_idx);
}
const char* get(uint16_t _idx) const
@@ -3791,7 +3784,7 @@ namespace bgfx
{
for (uint32_t ii = 1; ii < kNumBlocks; ++ii)
{
if (0 == m_used[ii]
if (m_alloc.getBits().testNone(ii*kBlock, (ii+1)*kBlock)
&& !m_touched[ii])
{
#if BGFX_CONFIG_DYNAMIC_FRAME_STORAGE
@@ -3819,8 +3812,8 @@ namespace bgfx
char m_name[kNumBlocks][kBlock*kNameSize] = {};
#endif // BGFX_CONFIG_DYNAMIC_FRAME_STORAGE
uint64_t m_used[kNumBlocks];
bool m_touched[kNumBlocks];
bool m_touched[kNumBlocks];
bx::HandleAlloc2T<kNumBlocks*kBlock> m_alloc;
};
struct UniformCacheKey
@@ -4021,6 +4014,89 @@ namespace bgfx
FrameBufferHandle handle;
};
template<typename Ty, uint32_t Max>
struct FreeHandle
{
FreeHandle()
: m_num(0)
{
}
bool isQueued(Ty _handle)
{
for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
{
if (m_queue[ii].idx == _handle.idx)
{
return true;
}
}
return false;
}
bool queue(Ty _handle)
{
if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
{
if (isQueued(_handle) )
{
return false;
}
}
reserve(m_num + 1);
m_queue[m_num] = _handle;
++m_num;
return true;
}
void reset()
{
m_num = 0;
}
Ty get(uint16_t _idx) const
{
return m_queue[_idx];
}
uint16_t getNumQueued() const
{
return m_num;
}
#if BGFX_CONFIG_DYNAMIC_FRAME_STORAGE
~FreeHandle()
{
bx::free(g_allocator, m_queue);
}
private:
void reserve(uint32_t _num)
{
if (_num > m_capacity)
{
m_capacity = bx::min<uint32_t>(bx::alignUp(_num, 64), Max);
m_queue = (Ty*)bx::realloc(g_allocator, m_queue, sizeof(Ty)*m_capacity);
}
}
Ty* m_queue = NULL;
uint32_t m_capacity = 0;
#else
private:
void reserve(uint32_t /*_num*/)
{
}
Ty m_queue[Max];
#endif // BGFX_CONFIG_DYNAMIC_FRAME_STORAGE
uint16_t m_num;
};
BX_ALIGN_DECL_CACHE_LINE(struct) Frame
{
Frame()
@@ -4435,62 +4511,6 @@ namespace bgfx
CommandBuffer m_cmdPre;
CommandBuffer m_cmdPost;
template<typename Ty, uint32_t Max>
struct FreeHandle
{
FreeHandle()
: m_num(0)
{
}
bool isQueued(Ty _handle)
{
for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
{
if (m_queue[ii].idx == _handle.idx)
{
return true;
}
}
return false;
}
bool queue(Ty _handle)
{
if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
{
if (isQueued(_handle) )
{
return false;
}
}
m_queue[m_num] = _handle;
++m_num;
return true;
}
void reset()
{
m_num = 0;
}
Ty get(uint16_t _idx) const
{
return m_queue[_idx];
}
uint16_t getNumQueued() const
{
return m_num;
}
Ty m_queue[Max];
uint16_t m_num;
};
FreeHandle<IndexBufferHandle, BGFX_CONFIG_MAX_INDEX_BUFFERS> m_freeIndexBuffer;
FreeHandle<VertexLayoutHandle, BGFX_CONFIG_MAX_VERTEX_LAYOUTS> m_freeVertexLayout;
FreeHandle<VertexBufferHandle, BGFX_CONFIG_MAX_VERTEX_BUFFERS> m_freeVertexBuffer;
@@ -5137,21 +5157,18 @@ namespace bgfx
void init()
{
bx::memSet(m_refCount, 0, sizeof(m_refCount) );
bx::memSet(m_stride, 0, sizeof(m_stride) );
bx::memSet(m_vertexBufferRef, 0xff, sizeof(m_vertexBufferRef) );
bx::memSet(m_dynamicVertexBufferRef, 0xff, sizeof(m_dynamicVertexBufferRef) );
bx::memSet(m_refCount, 0, sizeof(m_refCount) );
bx::memSet(m_stride, 0, sizeof(m_stride) );
}
template <uint16_t MaxHandlesT>
void shutdown(bx::HandleAllocT<MaxHandlesT>& _handleAlloc)
void shutdown(bx::HandleAlloc2T<MaxHandlesT>& _handleAlloc)
{
for (uint16_t ii = 0, num = _handleAlloc.getNumHandles(); ii < num; ++ii)
for (uint16_t idx = _handleAlloc.findFirst(); bx::kInvalidHandle != idx; idx = _handleAlloc.findNext(idx) )
{
VertexLayoutHandle handle = { _handleAlloc.getHandleAt(ii) };
m_refCount[handle.idx] = 0;
m_vertexLayoutMap.removeByHandle(handle.idx);
_handleAlloc.free(handle.idx);
m_refCount[idx] = 0;
m_vertexLayoutMap.removeByHandle(idx);
_handleAlloc.free(idx);
}
m_vertexLayoutMap.reset();
@@ -5169,18 +5186,18 @@ namespace bgfx
m_vertexLayoutMap.insert(_hash, _layoutHandle.idx);
}
void add(VertexBufferHandle _handle, VertexLayoutHandle _layoutHandle, uint32_t _hash)
void add(VertexBuffer& _vb, VertexLayoutHandle _layoutHandle, uint32_t _hash)
{
BX_ASSERT(!isValid(m_vertexBufferRef[_handle.idx]), "");
m_vertexBufferRef[_handle.idx] = _layoutHandle;
BX_ASSERT(!isValid(_vb.m_layoutHandle), "");
_vb.m_layoutHandle = _layoutHandle;
m_refCount[_layoutHandle.idx]++;
m_vertexLayoutMap.insert(_hash, _layoutHandle.idx);
}
void add(DynamicVertexBufferHandle _handle, VertexLayoutHandle _layoutHandle, uint32_t _hash)
void add(DynamicVertexBuffer& _dvb, VertexLayoutHandle _layoutHandle, uint32_t _hash)
{
BX_ASSERT(!isValid(m_dynamicVertexBufferRef[_handle.idx]), "");
m_dynamicVertexBufferRef[_handle.idx] = _layoutHandle;
BX_ASSERT(!isValid(_dvb.m_layoutHandle), "");
_dvb.m_layoutHandle = _layoutHandle;
m_refCount[_layoutHandle.idx]++;
m_vertexLayoutMap.insert(_hash, _layoutHandle.idx);
}
@@ -5201,20 +5218,18 @@ namespace bgfx
return BGFX_INVALID_HANDLE;
}
VertexLayoutHandle release(VertexBufferHandle _handle)
VertexLayoutHandle release(VertexBuffer& _vb)
{
VertexLayoutHandle layoutHandle = m_vertexBufferRef[_handle.idx];
layoutHandle = release(layoutHandle);
m_vertexBufferRef[_handle.idx] = BGFX_INVALID_HANDLE;
VertexLayoutHandle layoutHandle = release(_vb.m_layoutHandle);
_vb.m_layoutHandle = BGFX_INVALID_HANDLE;
return layoutHandle;
}
VertexLayoutHandle release(DynamicVertexBufferHandle _handle)
VertexLayoutHandle release(DynamicVertexBuffer& _dvb)
{
VertexLayoutHandle layoutHandle = m_dynamicVertexBufferRef[_handle.idx];
layoutHandle = release(layoutHandle);
m_dynamicVertexBufferRef[_handle.idx] = BGFX_INVALID_HANDLE;
VertexLayoutHandle layoutHandle = release(_dvb.m_layoutHandle);
_dvb.m_layoutHandle = BGFX_INVALID_HANDLE;
return layoutHandle;
}
@@ -5224,8 +5239,6 @@ namespace bgfx
uint16_t m_refCount[BGFX_CONFIG_MAX_VERTEX_LAYOUTS];
uint16_t m_stride[BGFX_CONFIG_MAX_VERTEX_LAYOUTS];
VertexLayoutHandle m_vertexBufferRef[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
VertexLayoutHandle m_dynamicVertexBufferRef[BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS];
};
// First-fit non-local allocator.
@@ -5835,8 +5848,6 @@ namespace bgfx
, m_tempValues(NULL)
, m_tempCapacity(0)
, m_numDrawCallsPeak(0)
, m_numFreeDynamicIndexBufferHandles(0)
, m_numFreeDynamicVertexBufferHandles(0)
, m_numFreeOcclusionQueryHandles(0)
, m_numNewOcclusionQueryHandles(0)
, m_colorPaletteDirty(2)
@@ -5990,9 +6001,8 @@ namespace bgfx
}
}
for (uint16_t ii = 0, num = m_textureHandle.getNumHandles(); ii < num; ++ii)
for (uint16_t textureIdx = m_textureHandle.findFirst(); bx::kInvalidHandle != textureIdx; textureIdx = m_textureHandle.findNext(textureIdx) )
{
uint16_t textureIdx = m_textureHandle.getHandleAt(ii);
const TextureRef& ref = m_textureRef[textureIdx];
if (BackbufferRatio::Count != ref.m_bbRatio)
{
@@ -6234,9 +6244,8 @@ namespace bgfx
return BGFX_INVALID_HANDLE;
}
m_vertexLayoutRef.add(handle, layoutHandle, _layout.m_hash);
VertexBuffer& vb = m_vertexBuffers.alloc(handle.idx);
m_vertexLayoutRef.add(vb, layoutHandle, _layout.m_hash);
vb.m_size = _mem->size;
vb.m_stride = _layout.m_stride;
vb.m_flags = _flags;
@@ -6287,7 +6296,7 @@ namespace bgfx
void destroyVertexBufferInternal(VertexBufferHandle _handle)
{
VertexLayoutHandle layoutHandle = m_vertexLayoutRef.release(_handle);
VertexLayoutHandle layoutHandle = m_vertexLayoutRef.release(m_vertexBuffers[_handle.idx]);
if (isValid(layoutHandle) )
{
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexLayout);
@@ -6455,7 +6464,7 @@ namespace bgfx
BGFX_CHECK_HANDLE("destroyDynamicIndexBuffer", m_dynamicIndexBufferHandle, _handle);
m_freeDynamicIndexBufferHandle[m_numFreeDynamicIndexBufferHandles++] = _handle;
m_freeDynamicIndexBuffer.queue(_handle);
}
void destroy(const DynamicIndexBuffer& _dib)
@@ -6579,9 +6588,8 @@ namespace bgfx
dvb.m_startVertex = bx::strideAlign(dvb.m_offset, _layout.m_stride)/_layout.m_stride;
dvb.m_numVertices = _num;
dvb.m_stride = _layout.m_stride;
dvb.m_layoutHandle = layoutHandle;
dvb.m_flags = _flags;
m_vertexLayoutRef.add(handle, layoutHandle, _layout.m_hash);
m_vertexLayoutRef.add(dvb, layoutHandle, _layout.m_hash);
return handle;
}
@@ -6657,7 +6665,7 @@ namespace bgfx
BGFX_CHECK_HANDLE("destroyDynamicVertexBuffer", m_dynamicVertexBufferHandle, _handle);
m_freeDynamicVertexBufferHandle[m_numFreeDynamicVertexBufferHandles++] = _handle;
m_freeDynamicVertexBuffer.queue(_handle);
}
void destroy(const DynamicVertexBuffer& _dvb)
@@ -6680,7 +6688,7 @@ namespace bgfx
void destroyDynamicVertexBufferInternal(DynamicVertexBufferHandle _handle)
{
VertexLayoutHandle layoutHandle = m_vertexLayoutRef.release(_handle);
VertexLayoutHandle layoutHandle = m_vertexLayoutRef.release(m_dynamicVertexBuffers[_handle.idx]);
BGFX_CHECK_HANDLE_INVALID_OK("destroyDynamicVertexBufferInternal", m_layoutHandle, layoutHandle);
if (isValid(layoutHandle) )
@@ -6787,7 +6795,7 @@ namespace bgfx
if (NULL != _layout)
{
layoutHandle = findOrCreateVertexLayout(*_layout);
m_vertexLayoutRef.add(handle, layoutHandle, _layout->m_hash);
m_vertexLayoutRef.add(m_vertexBuffers[handle.idx], layoutHandle, _layout->m_hash);
stride = _layout->m_stride;
}
@@ -8543,30 +8551,28 @@ namespace bgfx
HandleArenaT<DynamicIndexBuffer, BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS> m_dynamicIndexBuffers;
HandleArenaT<DynamicVertexBuffer, BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS> m_dynamicVertexBuffers;
uint16_t m_numFreeDynamicIndexBufferHandles;
uint16_t m_numFreeDynamicVertexBufferHandles;
uint16_t m_numFreeOcclusionQueryHandles;
uint16_t m_numNewOcclusionQueryHandles;
DynamicIndexBufferHandle m_freeDynamicIndexBufferHandle[BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS];
DynamicVertexBufferHandle m_freeDynamicVertexBufferHandle[BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS];
FreeHandle<DynamicIndexBufferHandle, BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS> m_freeDynamicIndexBuffer;
FreeHandle<DynamicVertexBufferHandle, BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS> m_freeDynamicVertexBuffer;
OcclusionQueryHandle m_freeOcclusionQueryHandle[BGFX_CONFIG_MAX_OCCLUSION_QUERIES];
OcclusionQueryHandle m_newOcclusionQueryHandle[BGFX_CONFIG_MAX_OCCLUSION_QUERIES];
NonLocalAllocator m_dynIndexBufferAllocator;
bx::HandleAllocT<BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS> m_dynamicIndexBufferHandle;
bx::HandleAlloc2T<BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS> m_dynamicIndexBufferHandle;
NonLocalAllocator m_dynVertexBufferAllocator;
bx::HandleAllocT<BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS> m_dynamicVertexBufferHandle;
bx::HandleAlloc2T<BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS> m_dynamicVertexBufferHandle;
bx::HandleAllocT<BGFX_CONFIG_MAX_INDEX_BUFFERS> m_indexBufferHandle;
bx::HandleAllocT<BGFX_CONFIG_MAX_VERTEX_LAYOUTS > m_layoutHandle;
bx::HandleAlloc2T<BGFX_CONFIG_MAX_INDEX_BUFFERS> m_indexBufferHandle;
bx::HandleAlloc2T<BGFX_CONFIG_MAX_VERTEX_LAYOUTS > m_layoutHandle;
bx::HandleAllocT<BGFX_CONFIG_MAX_VERTEX_BUFFERS> m_vertexBufferHandle;
bx::HandleAllocT<BGFX_CONFIG_MAX_SHADERS> m_shaderHandle;
bx::HandleAllocT<BGFX_CONFIG_MAX_PROGRAMS> m_programHandle;
bx::HandleAllocT<BGFX_CONFIG_MAX_TEXTURES> m_textureHandle;
bx::HandleAllocT<BGFX_CONFIG_MAX_FRAME_BUFFERS> m_frameBufferHandle;
bx::HandleAllocT<BGFX_CONFIG_MAX_UNIFORMS> m_uniformHandle;
bx::HandleAllocT<BGFX_CONFIG_MAX_OCCLUSION_QUERIES> m_occlusionQueryHandle;
bx::HandleAlloc2T<BGFX_CONFIG_MAX_VERTEX_BUFFERS> m_vertexBufferHandle;
bx::HandleAlloc2T<BGFX_CONFIG_MAX_SHADERS> m_shaderHandle;
bx::HandleAlloc2T<BGFX_CONFIG_MAX_PROGRAMS> m_programHandle;
bx::HandleAlloc2T<BGFX_CONFIG_MAX_TEXTURES> m_textureHandle;
bx::HandleAlloc2T<BGFX_CONFIG_MAX_FRAME_BUFFERS> m_frameBufferHandle;
bx::HandleAlloc2T<BGFX_CONFIG_MAX_UNIFORMS> m_uniformHandle;
bx::HandleAlloc2T<BGFX_CONFIG_MAX_OCCLUSION_QUERIES> m_occlusionQueryHandle;
typedef bx::HandleHashMapT<BGFX_CONFIG_MAX_UNIFORMS*2> UniformHashMap;
UniformHashMap m_uniformHashMap;
+36
View File
@@ -84,6 +84,42 @@ namespace bgfx
_control.resize(int32_t(_size) - int32_t(_control.getSize() ) );
}
template<typename QueryT>
class TimerQueryArrayT
{
public:
TimerQueryArrayT(uint32_t _num)
: m_query(NULL)
, m_num(0)
{
resize(_num);
}
~TimerQueryArrayT()
{
bx::free(g_allocator, m_query);
}
void resize(uint32_t _num)
{
if (_num != m_num)
{
m_query = (QueryT*)bx::realloc(g_allocator, m_query, sizeof(QueryT)*_num);
m_num = _num;
}
}
QueryT& operator[](uint32_t _idx)
{
BX_ASSERT(_idx < m_num, "Timer query index %d out of range %d.", _idx, m_num);
return m_query[_idx];
}
private:
QueryT* m_query;
uint32_t m_num;
};
template<typename ResultT>
class TimerResultT
{
+9 -3
View File
@@ -6366,7 +6366,10 @@ namespace bgfx { namespace d3d11
{
const uint32_t num = newSize - size;
bx::memMove(&m_query[write+num], &m_query[write], (size-write)*sizeof(Query) );
m_query.resize(newSize);
Query* query = &m_query[0];
bx::memMove(&query[write+num], &query[write], (size-write)*sizeof(Query) );
create(write, write+num);
}
else if (newSize < size)
@@ -6378,8 +6381,11 @@ namespace bgfx { namespace d3d11
destroy(write, write+back);
destroy(0, front);
bx::memMove(&m_query[write], &m_query[write+back], (size-write-back)*sizeof(Query) );
bx::memMove(&m_query[0], &m_query[front], newSize*sizeof(Query) );
Query* query = &m_query[0];
bx::memMove(&query[write], &query[write+back], (size-write-back)*sizeof(Query) );
bx::memMove(&query[0], &query[front], newSize*sizeof(Query) );
m_query.resize(newSize);
}
}
+3 -2
View File
@@ -480,7 +480,8 @@ namespace bgfx { namespace d3d11
struct TimerQueryD3D11
{
TimerQueryD3D11()
: m_control(kMinTimerQueries)
: m_query(kMinTimerQueries)
, m_control(kMinTimerQueries)
{
}
@@ -523,7 +524,7 @@ namespace bgfx { namespace d3d11
TimerResultT<Result> m_result;
Query m_query[kMaxTimerQueries];
TimerQueryArrayT<Query> m_query;
bx::RingBufferControl m_control;
};
+1
View File
@@ -8563,6 +8563,7 @@ namespace bgfx { namespace d3d12
shutdown();
bgfx::resize(m_control, _size);
m_query.resize(m_control.getSize() );
create();
m_result.resetPending();
+3 -2
View File
@@ -750,7 +750,8 @@ namespace bgfx { namespace d3d12
struct TimerQueryD3D12
{
TimerQueryD3D12()
: m_control(kMinTimerQueries)
: m_query(kMinTimerQueries)
, m_control(kMinTimerQueries)
{
}
@@ -789,7 +790,7 @@ namespace bgfx { namespace d3d12
uint64_t m_frequency;
TimerResultT<Result> m_result;
Query m_query[kMaxTimerQueries];
TimerQueryArrayT<Query> m_query;
ID3D12Resource* m_readback;
ID3D12QueryHeap* m_queryHeap;
+12 -5
View File
@@ -1660,7 +1660,8 @@ namespace bgfx { namespace gl
struct TimerQueryGL
{
TimerQueryGL()
: m_control(kMinTimerQueries)
: m_query(kMinTimerQueries)
, m_control(kMinTimerQueries)
{
}
@@ -1711,7 +1712,10 @@ namespace bgfx { namespace gl
{
const uint32_t num = newSize - size;
bx::memMove(&m_query[write+num], &m_query[write], (size-write)*sizeof(Query) );
m_query.resize(newSize);
Query* query = &m_query[0];
bx::memMove(&query[write+num], &query[write], (size-write)*sizeof(Query) );
create(write, write+num);
}
else if (newSize < size)
@@ -1723,8 +1727,11 @@ namespace bgfx { namespace gl
destroy(write, write+back);
destroy(0, front);
bx::memMove(&m_query[write], &m_query[write+back], (size-write-back)*sizeof(Query) );
bx::memMove(&m_query[0], &m_query[front], newSize*sizeof(Query) );
Query* query = &m_query[0];
bx::memMove(&query[write], &query[write+back], (size-write-back)*sizeof(Query) );
bx::memMove(&query[0], &query[front], newSize*sizeof(Query) );
m_query.resize(newSize);
}
}
@@ -1844,7 +1851,7 @@ namespace bgfx { namespace gl
TimerResultT<Result> m_result;
Query m_query[kMaxTimerQueries];
TimerQueryArrayT<Query> m_query;
bx::RingBufferControl m_control;
};
+1
View File
@@ -6443,6 +6443,7 @@ VK_DESTROY
s_renderVK->recycleMemory(m_readbackMemory);
bgfx::resize(m_control, _size);
m_query.resize(m_control.getSize() );
VK_CHECK(create() );
m_result.resetPending();
+3 -2
View File
@@ -605,7 +605,8 @@ VK_DESTROY_FUNC(DescriptorSet);
struct TimerQueryVK
{
TimerQueryVK()
: m_control(kMinTimerQueries)
: m_query(kMinTimerQueries)
, m_control(kMinTimerQueries)
{
}
@@ -644,7 +645,7 @@ VK_DESTROY_FUNC(DescriptorSet);
uint64_t m_frequency;
TimerResultT<Result> m_result;
Query m_query[kMaxTimerQueries];
TimerQueryArrayT<Query> m_query;
VkBuffer m_readback;
DeviceMemoryAllocationVK m_readbackMemory;