diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e419cb035..be6ba292d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -295,7 +295,7 @@ jobs: path: bimg - uses: mymindstorm/setup-emsdk@v14 with: - version: 5.0.2 + version: 6.0.9 actions-cache-folder: emsdk-cache - name: Build run: | @@ -347,7 +347,7 @@ jobs: - uses: mymindstorm/setup-emsdk@v14 if: matrix.name == 'wasm' with: - version: 5.0.2 + version: 6.0.9 actions-cache-folder: emsdk-cache - name: Build if: matrix.name == 'msvc' diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 428148e41..0b75b20ec 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -2690,6 +2690,7 @@ namespace bgfx { for (uint16_t ii = 0, num = _frame->m_freeIndexBuffer.getNumQueued(); ii < num; ++ii) { + m_indexBuffers.release(_frame->m_freeIndexBuffer.get(ii).idx); m_indexBufferHandle.free(_frame->m_freeIndexBuffer.get(ii).idx); } @@ -2705,6 +2706,7 @@ namespace bgfx for (uint16_t ii = 0, num = _frame->m_freeShader.getNumQueued(); ii < num; ++ii) { + m_shaderRef.release(_frame->m_freeShader.get(ii).idx); m_shaderHandle.free(_frame->m_freeShader.get(ii).idx); } @@ -2715,11 +2717,13 @@ namespace bgfx for (uint16_t ii = 0, num = _frame->m_freeTexture.getNumQueued(); ii < num; ++ii) { + m_textureRef.release(_frame->m_freeTexture.get(ii).idx); m_textureHandle.free(_frame->m_freeTexture.get(ii).idx); } for (uint16_t ii = 0, num = _frame->m_freeFrameBuffer.getNumQueued(); ii < num; ++ii) { + m_frameBufferRef.release(_frame->m_freeFrameBuffer.get(ii).idx); m_frameBufferHandle.free(_frame->m_freeFrameBuffer.get(ii).idx); } @@ -2727,6 +2731,7 @@ namespace bgfx { UniformHandle handle = _frame->m_freeUniform.get(ii); m_uniformCache.invalidate(handle); + m_uniformRef.release(handle.idx); m_uniformHandle.free(handle.idx); } } @@ -2898,6 +2903,14 @@ namespace bgfx { m_view.freeUnset(); m_viewNames.freeUnused(); + m_textureRef.freeUnused(); + m_shaderRef.freeUnused(); + m_dynamicIndexBuffers.freeUnused(); + m_dynamicVertexBuffers.freeUnused(); + m_indexBuffers.freeUnused(); + m_vertexBuffers.freeUnused(); + m_uniformRef.freeUnused(); + m_frameBufferRef.freeUnused(); m_viewObserve = 0; } diff --git a/src/bgfx_p.h b/src/bgfx_p.h index ac730346c..a844cfb83 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -3277,6 +3277,211 @@ namespace bgfx uint32_t m_sampleMask; }; + template + class HandleArenaT + { + public: + static_assert(bx::isPowerOf2(BlockT), "HandleArenaT BlockT must be power of two."); + + ~HandleArenaT() + { + destroy(); + } + +#if BGFX_CONFIG_DYNAMIC_FRAME_STORAGE + static constexpr uint32_t kBlockMask = BlockT - 1; + static constexpr uint32_t kNumBlocks = (MaxT + kBlockMask)/BlockT; + + HandleArenaT() + { + bx::memSet(m_block, 0, sizeof(m_block) ); + bx::memSet(m_numLive, 0, sizeof(m_numLive) ); + bx::memSet(m_touched, 0, sizeof(m_touched) ); + } + + void destroy() + { + for (uint32_t ii = 0; ii < kNumBlocks; ++ii) + { + freeBlock(ii); + } + + bx::memSet(m_numLive, 0, sizeof(m_numLive) ); + bx::memSet(m_touched, 0, sizeof(m_touched) ); + } + + Ty& alloc(uint16_t _idx) + { + const uint32_t blockIdx = _idx / BlockT; + + Ty* block = m_block[blockIdx]; + + if (NULL == block) + { + block = allocBlock(blockIdx); + } + + m_numLive[blockIdx]++; + m_touched[blockIdx] = true; + + return block[_idx & kBlockMask]; + } + + template + void each(Fn _fn) + { + for (uint32_t ii = 0; ii < kNumBlocks; ++ii) + { + Ty* block = m_block[ii]; + + if (NULL != block) + { + for (uint32_t jj = 0; jj < BlockT; ++jj) + { + _fn(block[jj]); + } + } + } + } + + uint16_t indexOf(const Ty& _ref) const + { + const Ty* ptr = &_ref; + + for (uint32_t ii = 0; ii < kNumBlocks; ++ii) + { + const Ty* block = m_block[ii]; + + if (NULL != block + && ptr >= block + && ptr < block + BlockT) + { + return uint16_t(ii*BlockT + uint32_t(ptr - block) ); + } + } + + BX_ASSERT(false, "Element is not in arena."); + return UINT16_MAX; + } + + void release(uint16_t _idx) + { + const uint32_t blockIdx = _idx / BlockT; + + BX_ASSERT(0 < m_numLive[blockIdx], "Handle %d released more times than allocated.", _idx); + m_numLive[blockIdx]--; + } + + BX_FORCE_INLINE Ty& operator[](uint16_t _idx) + { + return load(_idx / BlockT)[_idx & kBlockMask]; + } + + BX_FORCE_INLINE const Ty& operator[](uint16_t _idx) const + { + return load(_idx / BlockT)[_idx & kBlockMask]; + } + + void freeUnused() + { + for (uint32_t ii = 0; ii < kNumBlocks; ++ii) + { + if (0 == m_numLive[ii] + && !m_touched[ii]) + { + freeBlock(ii); + } + + m_touched[ii] = false; + } + } + + private: + BX_FORCE_INLINE Ty* load(uint32_t _blockIdx) const + { + return *(Ty* volatile*)&m_block[_blockIdx]; + } + + BX_NO_INLINE Ty* allocBlock(uint32_t _blockIdx) + { + Ty* block = (Ty*)bx::alloc(g_allocator, sizeof(Ty)*BlockT, BX_ALIGNOF(Ty) ); + + for (uint32_t ii = 0; ii < BlockT; ++ii) + { + BX_PLACEMENT_NEW(&block[ii], Ty); + } + + bx::atomicExchangePtr( (void**)&m_block[_blockIdx], block); + + return block; + } + + BX_NO_INLINE void freeBlock(uint32_t _blockIdx) + { + Ty* block = m_block[_blockIdx]; + + if (NULL != block) + { + for (uint32_t ii = 0; ii < BlockT; ++ii) + { + block[ii].~Ty(); + } + + bx::free(g_allocator, block, BX_ALIGNOF(Ty) ); + m_block[_blockIdx] = NULL; + } + } + + Ty* m_block[kNumBlocks]; + uint16_t m_numLive[kNumBlocks]; + bool m_touched[kNumBlocks]; +#else + void destroy() + { + } + + Ty& alloc(uint16_t _idx) + { + return m_data[_idx]; + } + + void release(uint16_t /*_idx*/) + { + } + + BX_FORCE_INLINE Ty& operator[](uint16_t _idx) + { + return m_data[_idx]; + } + + BX_FORCE_INLINE const Ty& operator[](uint16_t _idx) const + { + return m_data[_idx]; + } + + template + void each(Fn _fn) + { + for (uint32_t ii = 0; ii < MaxT; ++ii) + { + _fn(m_data[ii]); + } + } + + uint16_t indexOf(const Ty& _ref) const + { + return uint16_t(&_ref - m_data); + } + + void freeUnused() + { + } + + private: + Ty m_data[MaxT]; +#endif // BGFX_CONFIG_DYNAMIC_FRAME_STORAGE + }; + class ViewArena { public: @@ -5913,7 +6118,7 @@ namespace bgfx BX_WARN(isValid(handle), "Failed to allocate index buffer handle."); if (isValid(handle) ) { - IndexBuffer& ib = m_indexBuffers[handle.idx]; + IndexBuffer& ib = m_indexBuffers.alloc(handle.idx); ib.m_size = _mem->size; ib.m_flags = _flags; @@ -6031,7 +6236,7 @@ namespace bgfx m_vertexLayoutRef.add(handle, layoutHandle, _layout.m_hash); - VertexBuffer& vb = m_vertexBuffers[handle.idx]; + VertexBuffer& vb = m_vertexBuffers.alloc(handle.idx); vb.m_size = _mem->size; vb.m_stride = _layout.m_stride; vb.m_flags = _flags; @@ -6090,6 +6295,7 @@ namespace bgfx m_render->free(layoutHandle); } + m_vertexBuffers.release(_handle.idx); m_vertexBufferHandle.free(_handle.idx); } @@ -6107,7 +6313,7 @@ namespace bgfx const uint32_t allocSize = bx::max(BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE, bx::alignUp(_size, 1<<20) ); - IndexBuffer& ib = m_indexBuffers[indexBufferHandle.idx]; + IndexBuffer& ib = m_indexBuffers.alloc(indexBufferHandle.idx); ib.m_size = allocSize; ib.m_flags = _flags; @@ -6132,7 +6338,7 @@ namespace bgfx return NonLocalAllocator::kInvalidBlock; } - IndexBuffer& ib = m_indexBuffers[indexBufferHandle.idx]; + IndexBuffer& ib = m_indexBuffers.alloc(indexBufferHandle.idx); ib.m_size = _size; ib.m_flags = _flags; @@ -6171,7 +6377,7 @@ namespace bgfx return BGFX_INVALID_HANDLE; } - DynamicIndexBuffer& dib = m_dynamicIndexBuffers[handle.idx]; + DynamicIndexBuffer& dib = m_dynamicIndexBuffers.alloc(handle.idx); dib.m_handle.idx = uint16_t(ptr>>32); dib.m_offset = uint32_t(ptr); dib.m_size = _num * indexSize; @@ -6275,6 +6481,7 @@ namespace bgfx DynamicIndexBuffer& dib = m_dynamicIndexBuffers[_handle.idx]; destroy(dib); dib.reset(); + m_dynamicIndexBuffers.release(_handle.idx); m_dynamicIndexBufferHandle.free(_handle.idx); } @@ -6292,7 +6499,7 @@ namespace bgfx const uint32_t allocSize = bx::max(BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE, bx::alignUp(_size, 1<<20) ); - VertexBuffer& vb = m_vertexBuffers[vertexBufferHandle.idx]; + VertexBuffer& vb = m_vertexBuffers.alloc(vertexBufferHandle.idx); vb.m_size = allocSize; vb.m_stride = 0; vb.m_flags = _flags; @@ -6319,7 +6526,7 @@ namespace bgfx return NonLocalAllocator::kInvalidBlock; } - VertexBuffer& vb = m_vertexBuffers[vertexBufferHandle.idx]; + VertexBuffer& vb = m_vertexBuffers.alloc(vertexBufferHandle.idx); vb.m_size = _size; vb.m_stride = 0; vb.m_flags = _flags; @@ -6365,7 +6572,7 @@ namespace bgfx return BGFX_INVALID_HANDLE; } - DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[handle.idx]; + DynamicVertexBuffer& dvb = m_dynamicVertexBuffers.alloc(handle.idx); dvb.m_handle.idx = uint16_t(ptr>>32); dvb.m_offset = uint32_t(ptr); dvb.m_size = _num * _layout.m_stride; @@ -6486,6 +6693,7 @@ namespace bgfx DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[_handle.idx]; destroy(dvb); dvb.reset(); + m_dynamicVertexBuffers.release(_handle.idx); m_dynamicVertexBufferHandle.free(_handle.idx); } @@ -6513,6 +6721,8 @@ namespace bgfx BX_WARN(isValid(handle), "Failed to allocate transient index buffer handle."); if (isValid(handle) ) { + m_indexBuffers.alloc(handle.idx); + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicIndexBuffer); cmdbuf.write(handle); cmdbuf.write(_size); @@ -6569,6 +6779,8 @@ namespace bgfx BX_WARN(isValid(handle), "Failed to allocate transient vertex buffer handle."); if (isValid(handle) ) { + m_vertexBuffers.alloc(handle.idx); + uint16_t stride = 0; VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE; @@ -6656,7 +6868,7 @@ namespace bgfx const uint32_t size = _num * BGFX_CONFIG_DRAW_INDIRECT_STRIDE; const uint16_t flags = BGFX_BUFFER_DRAW_INDIRECT; - VertexBuffer& vb = m_vertexBuffers[handle.idx]; + VertexBuffer& vb = m_vertexBuffers.alloc(handle.idx); vb.m_size = size; vb.m_stride = BGFX_CONFIG_DRAW_INDIRECT_STRIDE; vb.m_flags = flags; @@ -6780,7 +6992,7 @@ namespace bgfx bool ok = m_shaderHashMap.insert(shaderHash, handle.idx); BX_ASSERT(ok, "Shader already exists!"); BX_UNUSED(ok); - ShaderRef& sr = m_shaderRef[handle.idx]; + ShaderRef& sr = m_shaderRef.alloc(handle.idx); sr.m_refCount = 1; sr.m_hashIn = hashIn; sr.m_hashOut = hashOut; @@ -7190,7 +7402,7 @@ namespace bgfx return BGFX_INVALID_HANDLE; } - TextureRef& ref = m_textureRef[handle.idx]; + TextureRef& ref = m_textureRef.alloc(handle.idx); ref.init( _ratio , uint16_t(imageContainer.m_width) @@ -7584,7 +7796,7 @@ namespace bgfx const TextureRef& firstTexture = m_textureRef[_attachment[0].handle.idx]; const BackbufferRatio::Enum bbRatio = BackbufferRatio::Enum(firstTexture.m_bbRatio); - FrameBufferRef& fbr = m_frameBufferRef[handle.idx]; + FrameBufferRef& fbr = m_frameBufferRef.alloc(handle.idx); if (BackbufferRatio::Count == bbRatio) { fbr.m_width = bx::max(firstTexture.m_width >> _attachment[0].mip, 1); @@ -7729,7 +7941,7 @@ namespace bgfx if (isValid(handle) ) { - FrameBufferRef& fbr = m_frameBufferRef[handle.idx]; + FrameBufferRef& fbr = m_frameBufferRef.alloc(handle.idx); fbr.m_swapChain = _desc; fbr.m_swapChain.flags = checkSwapChainFlags(_desc.flags & kSwapChainFlagMask); fbr.m_width = uint16_t(bx::max(_desc.width, 1) ); @@ -7895,7 +8107,7 @@ namespace bgfx BX_TRACE("Creating uniform (handle %3d) `%s`, num %d", handle.idx, _name, _num); - UniformRef& uniform = m_uniformRef[handle.idx]; + UniformRef& uniform = m_uniformRef.alloc(handle.idx); uniform.m_name.set(_name); uniform.m_refCount = 1; uniform.m_freq = UniformFreq::Count == _freq @@ -8325,11 +8537,11 @@ namespace bgfx typedef stl::unordered_map BindHashMap; BindHashMap m_renderBindHashMap; - IndexBuffer m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS]; - VertexBuffer m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS]; + HandleArenaT m_indexBuffers; + HandleArenaT m_vertexBuffers; - DynamicIndexBuffer m_dynamicIndexBuffers[BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS]; - DynamicVertexBuffer m_dynamicVertexBuffers[BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS]; + HandleArenaT m_dynamicIndexBuffers; + HandleArenaT m_dynamicVertexBuffers; uint16_t m_numFreeDynamicIndexBufferHandles; uint16_t m_numFreeDynamicVertexBufferHandles; @@ -8358,18 +8570,18 @@ namespace bgfx typedef bx::HandleHashMapT UniformHashMap; UniformHashMap m_uniformHashMap; - UniformRef m_uniformRef[BGFX_CONFIG_MAX_UNIFORMS]; + HandleArenaT m_uniformRef; typedef bx::HandleHashMapT ShaderHashMap; ShaderHashMap m_shaderHashMap; - ShaderRef m_shaderRef[BGFX_CONFIG_MAX_SHADERS]; + HandleArenaT m_shaderRef; typedef bx::HandleHashMapT ProgramHashMap; ProgramHashMap m_programHashMap; ProgramRef m_programRef[BGFX_CONFIG_MAX_PROGRAMS]; - TextureRef m_textureRef[BGFX_CONFIG_MAX_TEXTURES]; - FrameBufferRef m_frameBufferRef[BGFX_CONFIG_MAX_FRAME_BUFFERS]; + HandleArenaT m_textureRef; + HandleArenaT m_frameBufferRef; VertexLayoutRef m_vertexLayoutRef; ViewId m_viewRemap[BGFX_CONFIG_MAX_VIEWS]; diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 3f07c21d7..15fe1527b 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -831,6 +831,8 @@ namespace bgfx { namespace d3d11 bool init(const Init& _init) { + m_frameBuffers.alloc(kMainFrameBufferIdx); + struct ErrorState { enum Enum @@ -1733,30 +1735,15 @@ namespace bgfx { namespace d3d11 invalidateCache(); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].destroy(); - } + m_frameBuffers.each([](FrameBufferD3D11& _frameBuffer) { _frameBuffer.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_indexBuffers); ++ii) - { - m_indexBuffers[ii].destroy(); - } + m_indexBuffers.each([](IndexBufferD3D11& _indexBuffer) { _indexBuffer.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_vertexBuffers); ++ii) - { - m_vertexBuffers[ii].destroy(); - } + m_vertexBuffers.each([](VertexBufferD3D11& _vertexBuffer) { _vertexBuffer.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii) - { - m_shaders[ii].destroy(); - } + m_shaders.each([](ShaderD3D11& _shader) { _shader.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_textures); ++ii) - { - m_textures[ii].destroy(); - } + m_textures.each([](TextureD3D11& _texture) { _texture.destroy(); }); DX_RELEASE_I(m_deviceCtx1); DX_RELEASE(m_annotation, 1); @@ -1799,13 +1786,14 @@ namespace bgfx { namespace d3d11 void createIndexBuffer(IndexBufferHandle _handle, const Memory* _mem, uint16_t _flags) override { - m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags); + m_indexBuffers.alloc(_handle.idx).create(_mem->size, _mem->data, _flags); } void destroyIndexBuffer(IndexBufferHandle _handle) override { m_srvUavLru.invalidateWithParent(bufferViewParent(_handle.idx, false) ); m_indexBuffers[_handle.idx].destroy(); + m_indexBuffers.release(_handle.idx); } void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override @@ -1821,18 +1809,19 @@ namespace bgfx { namespace d3d11 void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override { - m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _layoutHandle, _flags); + m_vertexBuffers.alloc(_handle.idx).create(_mem->size, _mem->data, _layoutHandle, _flags); } void destroyVertexBuffer(VertexBufferHandle _handle) override { m_srvUavLru.invalidateWithParent(bufferViewParent(_handle.idx, true) ); m_vertexBuffers[_handle.idx].destroy(); + m_vertexBuffers.release(_handle.idx); } void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { - m_indexBuffers[_handle.idx].create(_size, NULL, _flags); + m_indexBuffers.alloc(_handle.idx).create(_size, NULL, _flags); } void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -1844,12 +1833,13 @@ namespace bgfx { namespace d3d11 { m_srvUavLru.invalidateWithParent(bufferViewParent(_handle.idx, false) ); m_indexBuffers[_handle.idx].destroy(); + m_indexBuffers.release(_handle.idx); } void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE; - m_vertexBuffers[_handle.idx].create(_size, NULL, layoutHandle, _flags); + m_vertexBuffers.alloc(_handle.idx).create(_size, NULL, layoutHandle, _flags); } void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -1861,31 +1851,34 @@ namespace bgfx { namespace d3d11 { m_srvUavLru.invalidateWithParent(bufferViewParent(_handle.idx, true) ); m_vertexBuffers[_handle.idx].destroy(); + m_vertexBuffers.release(_handle.idx); } void createShader(ShaderHandle _handle, const Memory* _mem) override { - m_shaders[_handle.idx].create(_mem); + m_shaders.alloc(_handle.idx).create(_mem); } void destroyShader(ShaderHandle _handle) override { m_shaders[_handle.idx].destroy(); + m_shaders.release(_handle.idx); } void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) override { - m_program[_handle.idx].create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); + m_program.alloc(_handle.idx).create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); } void destroyProgram(ProgramHandle _handle) override { m_program[_handle.idx].destroy(); + m_program.release(_handle.idx); } void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { - return m_textures[_handle.idx].create(_mem, _flags, _skip, _external); + return m_textures.alloc(_handle.idx).create(_mem, _flags, _skip, _external); } void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) override @@ -2045,11 +2038,12 @@ namespace bgfx { namespace d3d11 void destroyTexture(TextureHandle _handle) override { m_textures[_handle.idx].destroy(); + m_textures.release(_handle.idx); } void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) override { - m_frameBuffers[_handle.idx].create(_num, _attachment); + m_frameBuffers.alloc(_handle.idx).create(_num, _attachment); } void createFrameBuffer(FrameBufferHandle _handle, const SwapChain& _desc) override @@ -2066,7 +2060,7 @@ namespace bgfx { namespace d3d11 uint16_t denseIdx = m_numWindows++; m_windows[denseIdx] = _handle; - m_frameBuffers[_handle.idx].create(denseIdx, _desc); + m_frameBuffers.alloc(_handle.idx).create(denseIdx, _desc); } void resizeFrameBuffer(FrameBufferHandle _handle, const SwapChain& _desc) override @@ -2082,6 +2076,7 @@ namespace bgfx { namespace d3d11 } uint16_t denseIdx = m_frameBuffers[_handle.idx].destroy(); + m_frameBuffers.release(_handle.idx); if (UINT16_MAX != denseIdx) { --m_numWindows; @@ -2346,10 +2341,7 @@ namespace bgfx { namespace d3d11 } m_occlusionQuery.preReset(); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].preReset(); - } + m_frameBuffers.each([](FrameBufferD3D11& _frameBuffer) { _frameBuffer.preReset(); }); // invalidateCache(); @@ -2367,10 +2359,7 @@ namespace bgfx { namespace d3d11 mainFrameBuffer().m_desc = m_mainSwapChain; - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].postReset(); - } + m_frameBuffers.each([](FrameBufferD3D11& _frameBuffer) { _frameBuffer.postReset(); }); FrameBufferD3D11& mainFb = mainFrameBuffer(); m_deviceCtx->OMSetRenderTargets(1, &mainFb.m_rtv[0], mainFb.m_dsv); @@ -4040,13 +4029,13 @@ namespace bgfx { namespace d3d11 uint32_t m_maxAnisotropy; bool m_wireframe; - IndexBufferD3D11 m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS]; - VertexBufferD3D11 m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS]; - ShaderD3D11 m_shaders[BGFX_CONFIG_MAX_SHADERS]; - ProgramD3D11 m_program[BGFX_CONFIG_MAX_PROGRAMS]; - TextureD3D11 m_textures[BGFX_CONFIG_MAX_TEXTURES]; + HandleArenaT m_indexBuffers; + HandleArenaT m_vertexBuffers; + HandleArenaT m_shaders; + HandleArenaT m_program; + HandleArenaT m_textures; VertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS]; - FrameBufferD3D11 m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS+1]; + HandleArenaT m_frameBuffers; Matrix4 m_predefinedUniforms[PredefinedUniform::Count]; StateCacheT m_blendStateCache; @@ -5585,7 +5574,7 @@ namespace bgfx { namespace d3d11 if (asArray) { ts.m_srv[_stage] = s_renderD3D11->getCachedSrv( - TextureHandle{ uint16_t(this - s_renderD3D11->m_textures) } + TextureHandle{ s_renderD3D11->m_textures.indexOf(*this) } , _firstMip , numMips , _firstLayer @@ -5599,7 +5588,7 @@ namespace bgfx { namespace d3d11 else if (0 != (flags & BGFX_SAMPLER_SAMPLE_STENCIL) ) { ts.m_srv[_stage] = s_renderD3D11->getCachedSrv( - TextureHandle{ uint16_t(this - s_renderD3D11->m_textures) } + TextureHandle{ s_renderD3D11->m_textures.indexOf(*this) } , _firstMip , numMips , _firstLayer @@ -5612,7 +5601,7 @@ namespace bgfx { namespace d3d11 || srgbMutable) { ts.m_srv[_stage] = s_renderD3D11->getCachedSrv( - TextureHandle{ uint16_t(this - s_renderD3D11->m_textures) } + TextureHandle{ s_renderD3D11->m_textures.indexOf(*this) } , _firstMip , numMips , _firstLayer @@ -5670,7 +5659,7 @@ namespace bgfx { namespace d3d11 TextureHandle TextureD3D11::getHandle() const { - TextureHandle handle = { (uint16_t)(this - s_renderD3D11->m_textures) }; + TextureHandle handle = { s_renderD3D11->m_textures.indexOf(*this) }; return handle; } @@ -6889,6 +6878,13 @@ namespace bgfx { namespace d3d11 void RendererContextD3D11::submit(Frame* _render, const ClearQuad& _clearQuad, const MipGen& /*_mipGen*/, TextVideoMemBlitter& _textVideoMemBlitter) { + m_indexBuffers.freeUnused(); + m_vertexBuffers.freeUnused(); + m_shaders.freeUnused(); + m_program.freeUnused(); + m_textures.freeUnused(); + m_frameBuffers.freeUnused(); + if (m_lost) { return; diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 5700fada6..54c54a25e 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -898,6 +898,8 @@ namespace bgfx { namespace d3d12 bool init(const Init& _init) { + m_frameBuffers.alloc(kMainFrameBufferIdx); + struct ErrorState { enum Enum @@ -2137,25 +2139,13 @@ namespace bgfx { namespace d3d12 m_pipelineStateCache.invalidate(); m_lastPso = NULL; - for (uint32_t ii = 0; ii < BX_COUNTOF(m_indexBuffers); ++ii) - { - m_indexBuffers[ii].destroy(); - } + m_indexBuffers.each([](BufferD3D12& _indexBuffer) { _indexBuffer.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_vertexBuffers); ++ii) - { - m_vertexBuffers[ii].destroy(); - } + m_vertexBuffers.each([](VertexBufferD3D12& _vertexBuffer) { _vertexBuffer.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii) - { - m_shaders[ii].destroy(); - } + m_shaders.each([](ShaderD3D12& _shader) { _shader.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_textures); ++ii) - { - m_textures[ii].destroy(); - } + m_textures.each([](TextureD3D12& _texture) { _texture.destroy(); }); #if BX_PLATFORM_WINDOWS dumpInfoQueue(); @@ -2393,12 +2383,13 @@ namespace bgfx { namespace d3d12 void createIndexBuffer(IndexBufferHandle _handle, const Memory* _mem, uint16_t _flags) override { - m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags, false); + m_indexBuffers.alloc(_handle.idx).create(_mem->size, _mem->data, _flags, false); } void destroyIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); + m_indexBuffers.release(_handle.idx); } void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override @@ -2414,17 +2405,18 @@ namespace bgfx { namespace d3d12 void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override { - m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _layoutHandle, _flags); + m_vertexBuffers.alloc(_handle.idx).create(_mem->size, _mem->data, _layoutHandle, _flags); } void destroyVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); + m_vertexBuffers.release(_handle.idx); } void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { - m_indexBuffers[_handle.idx].create(_size, NULL, _flags, false); + m_indexBuffers.alloc(_handle.idx).create(_size, NULL, _flags, false); } void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -2435,12 +2427,13 @@ namespace bgfx { namespace d3d12 void destroyDynamicIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); + m_indexBuffers.release(_handle.idx); } void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE; - m_vertexBuffers[_handle.idx].create(_size, NULL, layoutHandle, _flags); + m_vertexBuffers.alloc(_handle.idx).create(_size, NULL, layoutHandle, _flags); } void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -2451,31 +2444,34 @@ namespace bgfx { namespace d3d12 void destroyDynamicVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); + m_vertexBuffers.release(_handle.idx); } void createShader(ShaderHandle _handle, const Memory* _mem) override { - m_shaders[_handle.idx].create(_mem); + m_shaders.alloc(_handle.idx).create(_mem); } void destroyShader(ShaderHandle _handle) override { m_shaders[_handle.idx].destroy(); + m_shaders.release(_handle.idx); } void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) override { - m_program[_handle.idx].create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); + m_program.alloc(_handle.idx).create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); } void destroyProgram(ProgramHandle _handle) override { m_program[_handle.idx].destroy(); + m_program.release(_handle.idx); } void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { - return m_textures[_handle.idx].create(_mem, _flags, _skip, _external); + return m_textures.alloc(_handle.idx).create(_mem, _flags, _skip, _external); } void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) override @@ -2807,11 +2803,12 @@ namespace bgfx { namespace d3d12 void destroyTexture(TextureHandle _handle) override { m_textures[_handle.idx].destroy(); + m_textures.release(_handle.idx); } void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) override { - m_frameBuffers[_handle.idx].create(_num, _attachment); + m_frameBuffers.alloc(_handle.idx).create(_num, _attachment); } void createFrameBuffer(FrameBufferHandle _handle, const SwapChain& _desc) override @@ -2830,7 +2827,7 @@ namespace bgfx { namespace d3d12 uint16_t denseIdx = m_numWindows++; m_windows[denseIdx] = _handle; - m_frameBuffers[_handle.idx].create(denseIdx, _desc); + m_frameBuffers.alloc(_handle.idx).create(denseIdx, _desc); } void resizeFrameBuffer(FrameBufferHandle _handle, const SwapChain& _desc) override @@ -2863,6 +2860,7 @@ namespace bgfx { namespace d3d12 } uint16_t denseIdx = frameBuffer.destroy(); + m_frameBuffers.release(_handle.idx); if (UINT16_MAX != denseIdx) { --m_numWindows; @@ -3180,10 +3178,7 @@ namespace bgfx { namespace d3d12 { finishAll(); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].preReset(); - } + m_frameBuffers.each([](FrameBufferD3D12& _frameBuffer) { _frameBuffer.preReset(); }); invalidateCache(); @@ -3198,10 +3193,7 @@ namespace bgfx { namespace d3d12 mainFrameBuffer().m_desc = m_mainSwapChain; - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].postReset(); - } + m_frameBuffers.each([](FrameBufferD3D12& _frameBuffer) { _frameBuffer.postReset(); }); // capturePostReset(); } @@ -4574,13 +4566,13 @@ namespace bgfx { namespace d3d12 DxgiSwapChainDesc m_scd; uint32_t m_maxAnisotropy; - BufferD3D12 m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS]; - VertexBufferD3D12 m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS]; - ShaderD3D12 m_shaders[BGFX_CONFIG_MAX_SHADERS]; - ProgramD3D12 m_program[BGFX_CONFIG_MAX_PROGRAMS]; - TextureD3D12 m_textures[BGFX_CONFIG_MAX_TEXTURES]; + HandleArenaT m_indexBuffers; + HandleArenaT m_vertexBuffers; + HandleArenaT m_shaders; + HandleArenaT m_program; + HandleArenaT m_textures; VertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS]; - FrameBufferD3D12 m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS+1]; + HandleArenaT m_frameBuffers; Matrix4 m_predefinedUniforms[PredefinedUniform::Count]; StateCacheT m_pipelineStateCache; @@ -4933,7 +4925,7 @@ namespace bgfx { namespace d3d12 if (0 == _texture.m_srvHandle.ptr) { D3D12_CPU_DESCRIPTOR_HANDLE cached = getCPUHandleHeapStart(s_renderD3D12->m_textureSrvHeap); - cached.ptr += uint32_t(&_texture - s_renderD3D12->m_textures) * m_incrementSize; + cached.ptr += s_renderD3D12->m_textures.indexOf(_texture) * m_incrementSize; device->CreateShaderResourceView(resource, srvd, cached); _texture.m_srvHandle = cached; } @@ -6673,7 +6665,7 @@ namespace bgfx { namespace d3d12 ; BX_TRACE("Texture %3d: %s (requested: %s), %dx%d%s RT[%c], BO[%c], CW[%c]%s." - , this - s_renderD3D12->m_textures + , s_renderD3D12->m_textures.indexOf(*this) , getName( (TextureFormat::Enum)m_textureFormat) , getName( (TextureFormat::Enum)m_requestedFormat) , ti.width @@ -6964,7 +6956,7 @@ namespace bgfx { namespace d3d12 m_flags |= BGFX_SAMPLER_INTERNAL_SHARED; m_state = D3D12_RESOURCE_STATE_COMMON; - s_renderD3D12->m_cmd.addExternal({ uint16_t(this - s_renderD3D12->m_textures) }); + s_renderD3D12->m_cmd.addExternal({ s_renderD3D12->m_textures.indexOf(*this) }); } else { @@ -7127,7 +7119,7 @@ namespace bgfx { namespace d3d12 if (external) { - s_renderD3D12->m_cmd.removeExternal({ uint16_t(this - s_renderD3D12->m_textures) }); + s_renderD3D12->m_cmd.removeExternal({ s_renderD3D12->m_textures.indexOf(*this) }); } else { @@ -7937,7 +7929,7 @@ namespace bgfx { namespace d3d12 #if BX_PLATFORM_WINDOWS ID3D12Device* device = s_renderD3D12->m_device; - const FrameBufferHandle fbh = { uint16_t(this - s_renderD3D12->m_frameBuffers) }; + const FrameBufferHandle fbh = { s_renderD3D12->m_frameBuffers.indexOf(*this) }; const DxgiSwapChainDesc scd = getSwapChainDesc(); if (1 < scd.sampleDesc.Count @@ -8208,7 +8200,7 @@ namespace bgfx { namespace d3d12 D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = getCPUHandleHeapStart(s_renderD3D12->m_rtvDescriptorHeap); uint32_t rtvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - uint32_t fbhIdx = (uint32_t)(this - s_renderD3D12->m_frameBuffers); + uint32_t fbhIdx = s_renderD3D12->m_frameBuffers.indexOf(*this); rtvDescriptor.ptr += fbhIdx * BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS * rtvDescriptorSize; m_width = 0; @@ -8414,7 +8406,7 @@ namespace bgfx { namespace d3d12 void FrameBufferD3D12::clear(ID3D12GraphicsCommandList* _commandList, const Clear& _clear, const float _palette[][4], const D3D12_RECT* _rect, uint32_t _num) { ID3D12Device* device = s_renderD3D12->m_device; - FrameBufferHandle fbh = { (uint16_t)(this - s_renderD3D12->m_frameBuffers) }; + FrameBufferHandle fbh = { s_renderD3D12->m_frameBuffers.indexOf(*this) }; D3D12_CPU_DESCRIPTOR_HANDLE rtv = s_renderD3D12->getRtv(fbh); uint32_t rtvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); @@ -9436,6 +9428,13 @@ namespace bgfx { namespace d3d12 void RendererContextD3D12::submit(Frame* _render, const ClearQuad& /*_clearQuad*/, const MipGen& _mipGen, TextVideoMemBlitter& _textVideoMemBlitter) { + m_indexBuffers.freeUnused(); + m_vertexBuffers.freeUnused(); + m_shaders.freeUnused(); + m_program.freeUnused(); + m_textures.freeUnused(); + m_frameBuffers.freeUnused(); + m_mipGen = &_mipGen; if (m_lost || updateResolution(_render->m_mainSwapChain, _render->m_reset) ) diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 3e67ce9c7..b43eb02a6 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -3273,12 +3273,13 @@ namespace bgfx { namespace gl void createIndexBuffer(IndexBufferHandle _handle, const Memory* _mem, uint16_t _flags) override { - m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags); + m_indexBuffers.alloc(_handle.idx).create(_mem->size, _mem->data, _flags); } void destroyIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); + m_indexBuffers.release(_handle.idx); } void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override @@ -3294,17 +3295,18 @@ namespace bgfx { namespace gl void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override { - m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _layoutHandle, _flags); + m_vertexBuffers.alloc(_handle.idx).create(_mem->size, _mem->data, _layoutHandle, _flags); } void destroyVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); + m_vertexBuffers.release(_handle.idx); } void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { - m_indexBuffers[_handle.idx].create(_size, NULL, _flags); + m_indexBuffers.alloc(_handle.idx).create(_size, NULL, _flags); } void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -3315,12 +3317,13 @@ namespace bgfx { namespace gl void destroyDynamicIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); + m_indexBuffers.release(_handle.idx); } void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE; - m_vertexBuffers[_handle.idx].create(_size, NULL, layoutHandle, _flags); + m_vertexBuffers.alloc(_handle.idx).create(_size, NULL, layoutHandle, _flags); } void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -3331,32 +3334,35 @@ namespace bgfx { namespace gl void destroyDynamicVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); + m_vertexBuffers.release(_handle.idx); } void createShader(ShaderHandle _handle, const Memory* _mem) override { - m_shaders[_handle.idx].create(_mem); + m_shaders.alloc(_handle.idx).create(_mem); } void destroyShader(ShaderHandle _handle) override { m_shaders[_handle.idx].destroy(); + m_shaders.release(_handle.idx); } void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) override { ShaderGL dummyFragmentShader; - m_program[_handle.idx].create(m_shaders[_vsh.idx], isValid(_fsh) ? m_shaders[_fsh.idx] : dummyFragmentShader); + m_program.alloc(_handle.idx).create(m_shaders[_vsh.idx], isValid(_fsh) ? m_shaders[_fsh.idx] : dummyFragmentShader); } void destroyProgram(ProgramHandle _handle) override { m_program[_handle.idx].destroy(); + m_program.release(_handle.idx); } void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { - m_textures[_handle.idx].create(_mem, _flags, _skip, _external); + m_textures.alloc(_handle.idx).create(_mem, _flags, _skip, _external); return NULL; } @@ -3747,18 +3753,19 @@ namespace bgfx { namespace gl void destroyTexture(TextureHandle _handle) override { m_textures[_handle.idx].destroy(); + m_textures.release(_handle.idx); } void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) override { - m_frameBuffers[_handle.idx].create(_num, _attachment); + m_frameBuffers.alloc(_handle.idx).create(_num, _attachment); } void createFrameBuffer(FrameBufferHandle _handle, const SwapChain& _desc) override { uint16_t denseIdx = m_numWindows++; m_windows[denseIdx] = _handle; - m_frameBuffers[_handle.idx].create(denseIdx, _desc); + m_frameBuffers.alloc(_handle.idx).create(denseIdx, _desc); } void resizeFrameBuffer(FrameBufferHandle _handle, const SwapChain& _desc) override @@ -3774,6 +3781,7 @@ namespace bgfx { namespace gl } uint16_t denseIdx = m_frameBuffers[_handle.idx].destroy(); + m_frameBuffers.release(_handle.idx); if (UINT16_MAX != denseIdx) { --m_numWindows; @@ -4073,10 +4081,7 @@ namespace bgfx { namespace gl setRenderContextSize(m_mainSwapChain); updateCapture(); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].postReset(); - } + m_frameBuffers.each([](FrameBufferGL& _frameBuffer) { _frameBuffer.postReset(); }); m_currentFbo = 0; @@ -5377,13 +5382,13 @@ namespace bgfx { namespace gl uint16_t m_numWindows; FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS]; - IndexBufferGL m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS]; - VertexBufferGL m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS]; - ShaderGL m_shaders[BGFX_CONFIG_MAX_SHADERS]; - ProgramGL m_program[BGFX_CONFIG_MAX_PROGRAMS]; - TextureGL m_textures[BGFX_CONFIG_MAX_TEXTURES]; + HandleArenaT m_indexBuffers; + HandleArenaT m_vertexBuffers; + HandleArenaT m_shaders; + HandleArenaT m_program; + HandleArenaT m_textures; VertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS]; - FrameBufferGL m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS]; + HandleArenaT m_frameBuffers; TimerQueryGL m_gpuTimer; OcclusionQueryGL m_occlusionQuery; @@ -6631,7 +6636,7 @@ namespace bgfx { namespace gl BX_TRACE("Texture%-4s %3d: %s %s(requested: %s), layers %d, %dx%dx%d%s." , imageContainer.m_cubeMap ? "Cube" : (isVolume(imageContainer) ? "3D" : "2D") - , this - s_renderGL->m_textures + , s_renderGL->m_textures.indexOf(*this) , getName( (TextureFormat::Enum)m_textureFormat) , srgb ? "+sRGB " : "" , getName( (TextureFormat::Enum)m_requestedFormat) @@ -6805,7 +6810,7 @@ namespace bgfx { namespace gl void TextureGL::destroy() { - s_renderGL->m_textureViewStateCache.invalidateWithParent(uint16_t(this - s_renderGL->m_textures) ); + s_renderGL->m_textureViewStateCache.invalidateWithParent(s_renderGL->m_textures.indexOf(*this) ); if (0 == (m_flags & BGFX_SAMPLER_INTERNAL_SHARED) && 0 != m_id) @@ -7156,7 +7161,7 @@ namespace bgfx { namespace gl *_target = target; } - const uint16_t parent = uint16_t(this - s_renderGL->m_textures); + const uint16_t parent = s_renderGL->m_textures.indexOf(*this); const uint64_t key = 0 | (uint64_t(parent) << 48) @@ -8901,6 +8906,13 @@ namespace bgfx { namespace gl void RendererContextGL::submit(Frame* _render, const ClearQuad& _clearQuad, const MipGen& /*_mipGen*/, TextVideoMemBlitter& _textVideoMemBlitter) { + m_indexBuffers.freeUnused(); + m_vertexBuffers.freeUnused(); + m_shaders.freeUnused(); + m_program.freeUnused(); + m_textures.freeUnused(); + m_frameBuffers.freeUnused(); + if (_render->m_capture) { renderDocTriggerCapture(); diff --git a/src/renderer_mtl.cpp b/src/renderer_mtl.cpp index 0063a31cb..5d7c66e8b 100644 --- a/src/renderer_mtl.cpp +++ b/src/renderer_mtl.cpp @@ -1253,15 +1253,9 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames m_depthStencilStateCache.invalidate(); m_samplerStateCache.invalidate(); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii) - { - m_shaders[ii].destroy(); - } + m_shaders.each([](ShaderMtl& _shader) { _shader.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_textures); ++ii) - { - m_textures[ii].destroy(); - } + m_textures.each([](TextureMtl& _texture) { _texture.destroy(); }); m_screenshotBlitProgramVsh.destroy(); m_screenshotBlitProgramFsh.destroy(); @@ -1302,12 +1296,13 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames void createIndexBuffer(IndexBufferHandle _handle, const Memory* _mem, uint16_t _flags) override { - m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags); + m_indexBuffers.alloc(_handle.idx).create(_mem->size, _mem->data, _flags); } void destroyIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); + m_indexBuffers.release(_handle.idx); } void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override @@ -1323,17 +1318,18 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override { - m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _layoutHandle, _flags); + m_vertexBuffers.alloc(_handle.idx).create(_mem->size, _mem->data, _layoutHandle, _flags); } void destroyVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); + m_vertexBuffers.release(_handle.idx); } void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { - m_indexBuffers[_handle.idx].create(_size, NULL, _flags); + m_indexBuffers.alloc(_handle.idx).create(_size, NULL, _flags); } void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -1344,12 +1340,13 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames void destroyDynamicIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); + m_indexBuffers.release(_handle.idx); } void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE; - m_vertexBuffers[_handle.idx].create(_size, NULL, layoutHandle, _flags); + m_vertexBuffers.alloc(_handle.idx).create(_size, NULL, layoutHandle, _flags); } void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -1360,21 +1357,23 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames void destroyDynamicVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); + m_vertexBuffers.release(_handle.idx); } void createShader(ShaderHandle _handle, const Memory* _mem) override { - m_shaders[_handle.idx].create(_mem); + m_shaders.alloc(_handle.idx).create(_mem); } void destroyShader(ShaderHandle _handle) override { m_shaders[_handle.idx].destroy(); + m_shaders.release(_handle.idx); } void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) override { - m_program[_handle.idx].create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); + m_program.alloc(_handle.idx).create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); } void destroyProgram(ProgramHandle _handle) override @@ -1394,11 +1393,12 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames m_lastPso = NULL; m_program[_handle.idx].destroy(); + m_program.release(_handle.idx); } void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { - m_textures[_handle.idx].create(_mem, _flags, _skip, _external); + m_textures.alloc(_handle.idx).create(_mem, _flags, _skip, _external); return NULL; } @@ -1724,11 +1724,12 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames void destroyTexture(TextureHandle _handle) override { m_textures[_handle.idx].destroy(); + m_textures.release(_handle.idx); } void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) override { - m_frameBuffers[_handle.idx].create(_num, _attachment); + m_frameBuffers.alloc(_handle.idx).create(_num, _attachment); } void createFrameBuffer(FrameBufferHandle _handle, const SwapChain& _desc) override @@ -1746,7 +1747,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames uint16_t denseIdx = m_numWindows++; m_windows[denseIdx] = _handle; - FrameBufferMtl& fb = m_frameBuffers[_handle.idx]; + FrameBufferMtl& fb = m_frameBuffers.alloc(_handle.idx); fb.create(denseIdx, _desc); } @@ -1767,6 +1768,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames } uint16_t denseIdx = m_frameBuffers[_handle.idx].destroy(); + m_frameBuffers.release(_handle.idx); if (UINT16_MAX != denseIdx) { @@ -2125,10 +2127,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames m_reset &= ~BGFX_RESET_INTERNAL_FORCE; - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].postReset(); - } + m_frameBuffers.each([](FrameBufferMtl& _frameBuffer) { _frameBuffer.postReset(); }); updateCapture(); @@ -3743,13 +3742,13 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames uint16_t m_numWindows; FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS]; - IndexBufferMtl m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS]; - VertexBufferMtl m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS]; - ShaderMtl m_shaders[BGFX_CONFIG_MAX_SHADERS]; - ProgramMtl m_program[BGFX_CONFIG_MAX_PROGRAMS]; - TextureMtl m_textures[BGFX_CONFIG_MAX_TEXTURES]; + HandleArenaT m_indexBuffers; + HandleArenaT m_vertexBuffers; + HandleArenaT m_shaders; + HandleArenaT m_program; + HandleArenaT m_textures; FrameBufferMtl m_mainFrameBuffer; - FrameBufferMtl m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS]; + HandleArenaT m_frameBuffers; VertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS]; struct PipelineProgram @@ -4324,7 +4323,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames const bool srgb = 0 != (_flags&BGFX_TEXTURE_SRGB); BX_TRACE("Texture %3d: %s (requested: %s), layers %d, %dx%d%s RT[%c], WO[%c], CW[%c], sRGB[%c]" - , this - s_renderMtl->m_textures + , s_renderMtl->m_textures.indexOf(*this) , getName( (TextureFormat::Enum)m_textureFormat) , getName( (TextureFormat::Enum)m_requestedFormat) , ti.numLayers @@ -6075,6 +6074,13 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames void RendererContextMtl::submit(Frame* _render, const ClearQuad& _clearQuad, const MipGen& /*_mipGen*/, TextVideoMemBlitter& _textVideoMemBlitter) { + m_indexBuffers.freeUnused(); + m_vertexBuffers.freeUnused(); + m_shaders.freeUnused(); + m_program.freeUnused(); + m_textures.freeUnused(); + m_frameBuffers.freeUnused(); + m_cmd.finish(false); m_colorPalette = _render->m_colorPalette; diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 471686500..9a7043eee 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -2557,30 +2557,15 @@ VK_IMPORT_DEVICE m_scratchStagingBuffer[ii].destroy(); } - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].destroy(); - } + m_frameBuffers.each([](FrameBufferVK& _frameBuffer) { _frameBuffer.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_indexBuffers); ++ii) - { - m_indexBuffers[ii].destroy(); - } + m_indexBuffers.each([](IndexBufferVK& _indexBuffer) { _indexBuffer.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_vertexBuffers); ++ii) - { - m_vertexBuffers[ii].destroy(); - } + m_vertexBuffers.each([](VertexBufferVK& _vertexBuffer) { _vertexBuffer.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii) - { - m_shaders[ii].destroy(); - } + m_shaders.each([](ShaderVK& _shader) { _shader.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_textures); ++ii) - { - m_textures[ii].destroy(); - } + m_textures.each([](TextureVK& _texture) { _texture.destroy(); }); m_backBuffer.destroy(); @@ -2677,12 +2662,13 @@ VK_IMPORT_DEVICE void createIndexBuffer(IndexBufferHandle _handle, const Memory* _mem, uint16_t _flags) override { - m_indexBuffers[_handle.idx].create(m_commandBuffer, _mem->size, _mem->data, _flags, false); + m_indexBuffers.alloc(_handle.idx).create(m_commandBuffer, _mem->size, _mem->data, _flags, false); } void destroyIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); + m_indexBuffers.release(_handle.idx); } void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override @@ -2698,17 +2684,18 @@ VK_IMPORT_DEVICE void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override { - m_vertexBuffers[_handle.idx].create(m_commandBuffer, _mem->size, _mem->data, _layoutHandle, _flags); + m_vertexBuffers.alloc(_handle.idx).create(m_commandBuffer, _mem->size, _mem->data, _layoutHandle, _flags); } void destroyVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); + m_vertexBuffers.release(_handle.idx); } void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { - m_indexBuffers[_handle.idx].create(m_commandBuffer, _size, NULL, _flags, false); + m_indexBuffers.alloc(_handle.idx).create(m_commandBuffer, _size, NULL, _flags, false); } void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -2719,12 +2706,13 @@ VK_IMPORT_DEVICE void destroyDynamicIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); + m_indexBuffers.release(_handle.idx); } void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE; - m_vertexBuffers[_handle.idx].create(m_commandBuffer, _size, NULL, layoutHandle, _flags); + m_vertexBuffers.alloc(_handle.idx).create(m_commandBuffer, _size, NULL, layoutHandle, _flags); } void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -2735,31 +2723,34 @@ VK_IMPORT_DEVICE void destroyDynamicVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); + m_vertexBuffers.release(_handle.idx); } void createShader(ShaderHandle _handle, const Memory* _mem) override { - m_shaders[_handle.idx].create(_mem); + m_shaders.alloc(_handle.idx).create(_mem); } void destroyShader(ShaderHandle _handle) override { m_shaders[_handle.idx].destroy(); + m_shaders.release(_handle.idx); } void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) override { - m_program[_handle.idx].create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); + m_program.alloc(_handle.idx).create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); } void destroyProgram(ProgramHandle _handle) override { m_program[_handle.idx].destroy(); + m_program.release(_handle.idx); } void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { - return m_textures[_handle.idx].create(m_commandBuffer, _mem, _flags, _skip, _external); + return m_textures.alloc(_handle.idx).create(m_commandBuffer, _mem, _flags, _skip, _external); } void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) override @@ -2879,11 +2870,12 @@ VK_IMPORT_DEVICE { m_imageViewCache.invalidateWithParent(_handle.idx); m_textures[_handle.idx].destroy(); + m_textures.release(_handle.idx); } void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) override { - m_frameBuffers[_handle.idx].create(_num, _attachment); + m_frameBuffers.alloc(_handle.idx).create(_num, _attachment); } void createFrameBuffer(FrameBufferHandle _handle, const SwapChain& _desc) override @@ -2900,7 +2892,7 @@ VK_IMPORT_DEVICE uint16_t denseIdx = m_numWindows++; m_windows[denseIdx] = _handle; - VK_CHECK(m_frameBuffers[_handle.idx].create(denseIdx, _desc) ); + VK_CHECK(m_frameBuffers.alloc(_handle.idx).create(denseIdx, _desc) ); } void resizeFrameBuffer(FrameBufferHandle _handle, const SwapChain& _desc) override @@ -2918,6 +2910,7 @@ VK_IMPORT_DEVICE } uint16_t denseIdx = frameBuffer.destroy(); + m_frameBuffers.release(_handle.idx); if (UINT16_MAX != denseIdx) { --m_numWindows; @@ -3186,10 +3179,7 @@ VK_IMPORT_DEVICE void preReset() { - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].preReset(); - } + m_frameBuffers.each([](FrameBufferVK& _frameBuffer) { _frameBuffer.preReset(); }); if (m_captureSize > 0) { @@ -3203,10 +3193,7 @@ VK_IMPORT_DEVICE void postReset() { - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].postReset(); - } + m_frameBuffers.each([](FrameBufferVK& _frameBuffer) { _frameBuffer.postReset(); }); if (m_reset & BGFX_RESET_CAPTURE) { @@ -3252,11 +3239,10 @@ VK_IMPORT_DEVICE m_mainSwapChain.width = _swapChain.width; m_mainSwapChain.height = _swapChain.height; - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].preReset(); - m_frameBuffers[ii].postReset(); - } + m_frameBuffers.each([](FrameBufferVK& _frameBuffer) { + _frameBuffer.preReset(); + _frameBuffer.postReset(); + }); } return suspended; @@ -5268,13 +5254,13 @@ VK_IMPORT_DEVICE void* m_renderDocDll; void* m_vulkan1Dll; - IndexBufferVK m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS]; - VertexBufferVK m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS]; - ShaderVK m_shaders[BGFX_CONFIG_MAX_SHADERS]; - ProgramVK m_program[BGFX_CONFIG_MAX_PROGRAMS]; - TextureVK m_textures[BGFX_CONFIG_MAX_TEXTURES]; + HandleArenaT m_indexBuffers; + HandleArenaT m_vertexBuffers; + HandleArenaT m_shaders; + HandleArenaT m_program; + HandleArenaT m_textures; VertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS]; - FrameBufferVK m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS]; + HandleArenaT m_frameBuffers; Matrix4 m_predefinedUniforms[PredefinedUniform::Count]; @@ -7018,7 +7004,7 @@ VK_DESTROY m_textureDeviceMem = {}; m_flags |= BGFX_SAMPLER_INTERNAL_SHARED; - s_renderVK->m_cmd.addExternal({ uint16_t(this - s_renderVK->m_textures) }); + s_renderVK->m_cmd.addExternal({ s_renderVK->m_textures.indexOf(*this) }); } else { @@ -7185,7 +7171,7 @@ VK_DESTROY BX_TRACE( "Texture %3d: %s (requested: %s), %dx%dx%d%s RT[%c], BO[%c], CW[%c]%s." - , (int)(this - s_renderVK->m_textures) + , s_renderVK->m_textures.indexOf(*this) , getName( (TextureFormat::Enum)m_textureFormat) , getName( (TextureFormat::Enum)m_requestedFormat) , ti.width @@ -7437,7 +7423,7 @@ VK_DESTROY if (external) { - s_renderVK->m_cmd.removeExternal({ uint16_t(this - s_renderVK->m_textures) }); + s_renderVK->m_cmd.removeExternal({ s_renderVK->m_textures.indexOf(*this) }); } else { @@ -10385,6 +10371,13 @@ VK_DESTROY void RendererContextVK::submit(Frame* _render, const ClearQuad& /*_clearQuad*/, const MipGen& /*_mipGen*/, TextVideoMemBlitter& _textVideoMemBlitter) { + m_indexBuffers.freeUnused(); + m_vertexBuffers.freeUnused(); + m_shaders.freeUnused(); + m_program.freeUnused(); + m_textures.freeUnused(); + m_frameBuffers.freeUnused(); + if (m_lost || updateResolution(_render->m_mainSwapChain, _render->m_reset) ) { diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp index 9f721289d..9c4d4c445 100644 --- a/src/renderer_webgpu.cpp +++ b/src/renderer_webgpu.cpp @@ -1583,30 +1583,15 @@ WGPU_IMPORT } } - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].destroy(); - } + m_frameBuffers.each([](FrameBufferWGPU& _frameBuffer) { _frameBuffer.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_indexBuffers); ++ii) - { - m_indexBuffers[ii].destroy(); - } + m_indexBuffers.each([](IndexBufferWGPU& _indexBuffer) { _indexBuffer.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_vertexBuffers); ++ii) - { - m_vertexBuffers[ii].destroy(); - } + m_vertexBuffers.each([](VertexBufferWGPU& _vertexBuffer) { _vertexBuffer.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii) - { - m_shaders[ii].destroy(); - } + m_shaders.each([](ShaderWGPU& _shader) { _shader.destroy(); }); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_textures); ++ii) - { - m_textures[ii].destroy(); - } + m_textures.each([](TextureWGPU& _texture) { _texture.destroy(); }); m_backBuffer.destroy(); @@ -1664,13 +1649,14 @@ WGPU_IMPORT void createIndexBuffer(IndexBufferHandle _handle, const Memory* _mem, uint16_t _flags) override { - m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags, false); + m_indexBuffers.alloc(_handle.idx).create(_mem->size, _mem->data, _flags, false); } void destroyIndexBuffer(IndexBufferHandle _handle) override { invalidateBindGroupCache(); m_indexBuffers[_handle.idx].destroy(); + m_indexBuffers.release(_handle.idx); } void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override @@ -1686,18 +1672,19 @@ WGPU_IMPORT void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override { - m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _layoutHandle, _flags); + m_vertexBuffers.alloc(_handle.idx).create(_mem->size, _mem->data, _layoutHandle, _flags); } void destroyVertexBuffer(VertexBufferHandle _handle) override { invalidateBindGroupCache(); m_vertexBuffers[_handle.idx].destroy(); + m_vertexBuffers.release(_handle.idx); } void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { - m_indexBuffers[_handle.idx].create(_size, NULL, _flags, false); + m_indexBuffers.alloc(_handle.idx).create(_size, NULL, _flags, false); } void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -1709,12 +1696,13 @@ WGPU_IMPORT { invalidateBindGroupCache(); m_indexBuffers[_handle.idx].destroy(); + m_indexBuffers.release(_handle.idx); } void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE; - m_vertexBuffers[_handle.idx].create(_size, NULL, layoutHandle, _flags); + m_vertexBuffers.alloc(_handle.idx).create(_size, NULL, layoutHandle, _flags); } void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -1726,32 +1714,35 @@ WGPU_IMPORT { invalidateBindGroupCache(); m_vertexBuffers[_handle.idx].destroy(); + m_vertexBuffers.release(_handle.idx); } void createShader(ShaderHandle _handle, const Memory* _mem) override { - m_shaders[_handle.idx].create(_mem); + m_shaders.alloc(_handle.idx).create(_mem); } void destroyShader(ShaderHandle _handle) override { m_shaders[_handle.idx].destroy(); + m_shaders.release(_handle.idx); } void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) override { - m_program[_handle.idx].create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); + m_program.alloc(_handle.idx).create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); } void destroyProgram(ProgramHandle _handle) override { m_program[_handle.idx].destroy(); + m_program.release(_handle.idx); } void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip, uint64_t _external) override { BX_UNUSED(_external); - m_textures[_handle.idx].create(_mem, _flags, _skip); + m_textures.alloc(_handle.idx).create(_mem, _flags, _skip); return NULL; } @@ -2138,11 +2129,12 @@ WGPU_IMPORT { invalidateBindGroupCache(); m_textures[_handle.idx].destroy(); + m_textures.release(_handle.idx); } void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) override { - m_frameBuffers[_handle.idx].create(_num, _attachment); + m_frameBuffers.alloc(_handle.idx).create(_num, _attachment); } void createFrameBuffer(FrameBufferHandle _handle, const SwapChain& _desc) override @@ -2159,7 +2151,7 @@ WGPU_IMPORT uint16_t denseIdx = m_numWindows++; m_windows[denseIdx] = _handle; - m_frameBuffers[_handle.idx].create(denseIdx, _desc); + m_frameBuffers.alloc(_handle.idx).create(denseIdx, _desc); } void resizeFrameBuffer(FrameBufferHandle _handle, const SwapChain& _desc) override @@ -2174,6 +2166,7 @@ WGPU_IMPORT FrameBufferWGPU& frameBuffer = m_frameBuffers[_handle.idx]; uint16_t denseIdx = frameBuffer.destroy(); + m_frameBuffers.release(_handle.idx); if (UINT16_MAX != denseIdx) { --m_numWindows; @@ -2709,20 +2702,14 @@ WGPU_IMPORT { m_renderPipelineCache.invalidate(); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].preReset(); - } + m_frameBuffers.each([](FrameBufferWGPU& _frameBuffer) { _frameBuffer.preReset(); }); invalidateCache(); } void postReset() { - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].postReset(); - } + m_frameBuffers.each([](FrameBufferWGPU& _frameBuffer) { _frameBuffer.postReset(); }); if (m_reset & BGFX_RESET_CAPTURE) { @@ -2771,11 +2758,10 @@ WGPU_IMPORT m_mainSwapChain.width = _swapChain.width; m_mainSwapChain.height = _swapChain.height; - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) - { - m_frameBuffers[ii].preReset(); - m_frameBuffers[ii].postReset(); - } + m_frameBuffers.each([](FrameBufferWGPU& _frameBuffer) { + _frameBuffer.preReset(); + _frameBuffer.postReset(); + }); } return suspended; @@ -4018,13 +4004,13 @@ WGPU_IMPORT WGPUTexture m_mipGenStubTexture[2]; WGPUTextureView m_mipGenStubTextureView[2][3]; - IndexBufferWGPU m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS]; - VertexBufferWGPU m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS]; - ShaderWGPU m_shaders[BGFX_CONFIG_MAX_SHADERS]; - ProgramWGPU m_program[BGFX_CONFIG_MAX_PROGRAMS]; - TextureWGPU m_textures[BGFX_CONFIG_MAX_TEXTURES]; + HandleArenaT m_indexBuffers; + HandleArenaT m_vertexBuffers; + HandleArenaT m_shaders; + HandleArenaT m_program; + HandleArenaT m_textures; VertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS]; - FrameBufferWGPU m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS]; + HandleArenaT m_frameBuffers; StateCacheLru m_computePipelineCache; StateCacheLru m_renderPipelineCache; @@ -4764,7 +4750,7 @@ WGPU_IMPORT const bool needResolve = 1 < m_msaaCount && !writeOnly; BX_TRACE("Texture %3d: %s (requested: %s), %dx%d%s RT[%c], BO[%c], CW[%c]%s." - , this - s_renderWGPU->m_textures + , s_renderWGPU->m_textures.indexOf(*this) , getName( (TextureFormat::Enum)m_textureFormat) , getName( (TextureFormat::Enum)m_requestedFormat) , ti.width @@ -4971,7 +4957,7 @@ WGPU_IMPORT void TextureWGPU::destroy() { - s_renderWGPU->m_textureViewStateCache.invalidateWithParent(uint16_t(this - s_renderWGPU->m_textures) ); + s_renderWGPU->m_textureViewStateCache.invalidateWithParent(s_renderWGPU->m_textures.indexOf(*this) ); wgpuDestroy(m_texture); wgpuDestroy(m_textureMsaa); @@ -5286,7 +5272,7 @@ WGPU_IMPORT }; textureView = WGPU_CHECK(wgpuTextureCreateView(m_texture, &textureViewDesc) ); - s_renderWGPU->m_textureViewStateCache.add(hash, textureView, uint16_t(this - s_renderWGPU->m_textures) ); + s_renderWGPU->m_textureViewStateCache.add(hash, textureView, s_renderWGPU->m_textures.indexOf(*this) ); } return textureView; @@ -6937,6 +6923,13 @@ WGPU_IMPORT void RendererContextWGPU::submit(Frame* _render, const ClearQuad& _clearQuad, const MipGen& _mipGen, TextVideoMemBlitter& _textVideoMemBlitter) { + m_indexBuffers.freeUnused(); + m_vertexBuffers.freeUnused(); + m_shaders.freeUnused(); + m_program.freeUnused(); + m_textures.freeUnused(); + m_frameBuffers.freeUnused(); + if (0 != m_lost) { return;