From edef345b5abdf10d663173ca8e7d16ee9042b16e Mon Sep 17 00:00:00 2001 From: bkaradzic Date: Sat, 23 Jun 2012 11:44:22 -0700 Subject: [PATCH] Added dynamic index/vertex buffers. --- README.md | 6 + include/bgfx.h | 41 +++- src/bgfx.cpp | 65 +++++- src/bgfx_p.h | 460 +++++++++++++++++++++++++++++++++++------- src/config.h | 24 ++- src/renderer_d3d9.cpp | 48 +++-- src/renderer_d3d9.h | 12 +- src/renderer_gl.cpp | 42 ++-- src/renderer_gl.h | 20 +- src/renderer_null.cpp | 28 ++- 10 files changed, 590 insertions(+), 156 deletions(-) diff --git a/README.md b/README.md index 80ea17a2..d2eda981 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,12 @@ OpenGL 2.1, OpenGL ES 2.0, and Direct3D 9.0. Platforms: Windows, Linux, Android, and Native Client. +Notice +------ + +This is alpha software, and it lacks documentation and examples. If you're +interested to use it in your project, please let me know. + Contact ------- diff --git a/include/bgfx.h b/include/bgfx.h index 17e96b7f..62c260c9 100644 --- a/include/bgfx.h +++ b/include/bgfx.h @@ -217,6 +217,8 @@ namespace bgfx static const uint16_t invalidHandle = 0xffff; + typedef struct { uint16_t idx; } DynamicIndexBufferHandle; + typedef struct { uint16_t idx; } DynamicVertexBufferHandle; typedef struct { uint16_t idx; } FragmentShaderHandle; typedef struct { uint16_t idx; } IndexBufferHandle; typedef struct { uint16_t idx; } MaterialHandle; @@ -325,18 +327,36 @@ namespace bgfx /// void destroyIndexBuffer(IndexBufferHandle _handle); - /// - bool checkAvailTransientIndexBuffer(uint16_t _num); - - /// - const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num); - /// VertexBufferHandle createVertexBuffer(const Memory* _mem, const VertexDecl& _decl); /// void destroyVertexBuffer(VertexBufferHandle _handle); + /// + DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem); + + /// + void updateDynamicIndexBuffer(DynamicIndexBufferHandle _handle, const Memory* _mem); + + /// + void destroyDynamicIndexBuffer(DynamicIndexBufferHandle _handle); + + /// + DynamicVertexBufferHandle createDynamicVertexBuffer(const Memory* _mem, const VertexDecl& _decl); + + /// + void updateDynamicVertexBuffer(DynamicIndexBufferHandle _handle, const Memory* _mem); + + /// + void destroyDynamicVertexBuffer(DynamicVertexBufferHandle _handle); + + /// + bool checkAvailTransientIndexBuffer(uint16_t _num); + + /// + const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num); + /// bool checkAvailTransientVertexBuffer(uint16_t _num, const VertexDecl& _decl); @@ -427,12 +447,21 @@ namespace bgfx /// void setIndexBuffer(IndexBufferHandle _handle); + /// + void setIndexBuffer(DynamicVertexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices); + + /// + void setIndexBuffer(DynamicVertexBufferHandle _handle); + /// void setIndexBuffer(const TransientIndexBuffer* _ib, uint32_t _numIndices = 0xffffffff); /// void setVertexBuffer(VertexBufferHandle _handle); + /// + void setVertexBuffer(DynamicVertexBufferHandle _handle); + /// void setVertexBuffer(const TransientVertexBuffer* _vb); diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 0b9a7c3d..4de4d336 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -739,16 +739,6 @@ namespace bgfx s_ctx.destroyIndexBuffer(_handle); } - bool checkAvailTransientIndexBuffer(uint16_t _num) - { - return s_ctx.m_submit->checkAvailTransientIndexBuffer(_num); - } - - const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num) - { - return s_ctx.allocTransientIndexBuffer(_num); - } - VertexBufferHandle createVertexBuffer(const Memory* _mem, const VertexDecl& _decl) { return s_ctx.createVertexBuffer(_mem, _decl); @@ -759,6 +749,46 @@ namespace bgfx s_ctx.destroyVertexBuffer(_handle); } + DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem) + { + return s_ctx.createDynamicIndexBuffer(_mem); + } + + void updateDynamicIndexBuffer(DynamicIndexBufferHandle _handle, const Memory* _mem) + { + s_ctx.updateDynamicIndexBuffer(_handle, _mem); + } + + void destroyDynamicIndexBuffer(DynamicIndexBufferHandle _handle) + { + s_ctx.destroyDynamicIndexBuffer(_handle); + } + + DynamicVertexBufferHandle createDynamicVertexBuffer(const Memory* _mem, const VertexDecl& _decl) + { + return s_ctx.createDynamicVertexBuffer(_mem, _decl); + } + + void updateDynamicVertexBuffer(DynamicIndexBufferHandle _handle, const Memory* _mem) + { + s_ctx.updateDynamicVertexBuffer(_handle, _mem); + } + + void destroyDynamicVertexBuffer(DynamicVertexBufferHandle _handle) + { + s_ctx.destroyDynamicVertexBuffer(_handle); + } + + bool checkAvailTransientIndexBuffer(uint16_t _num) + { + return s_ctx.m_submit->checkAvailTransientIndexBuffer(_num); + } + + const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num) + { + return s_ctx.allocTransientIndexBuffer(_num); + } + bool checkAvailTransientVertexBuffer(uint16_t _num, const VertexDecl& _decl) { return s_ctx.m_submit->checkAvailTransientVertexBuffer(_num, _decl.m_stride); @@ -914,6 +944,16 @@ namespace bgfx s_ctx.m_submit->setIndexBuffer(_handle, BGFX_DRAW_WHOLE_INDEX_BUFFER, 0); } + void setIndexBuffer(DynamicIndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices) + { + s_ctx.m_submit->setIndexBuffer(s_ctx.m_dynamicIndexBuffers[_handle.idx].m_handle, _firstIndex, _numIndices); + } + + void setIndexBuffer(DynamicIndexBufferHandle _handle) + { + s_ctx.m_submit->setIndexBuffer(s_ctx.m_dynamicIndexBuffers[_handle.idx].m_handle, BGFX_DRAW_WHOLE_INDEX_BUFFER, 0); + } + void setIndexBuffer(const TransientIndexBuffer* _ib, uint32_t _numIndices) { uint32_t numIndices = uint32_min(_numIndices, _ib->size/2); @@ -925,6 +965,11 @@ namespace bgfx s_ctx.m_submit->setVertexBuffer(_handle); } + void setVertexBuffer(DynamicVertexBufferHandle _handle) + { + s_ctx.m_submit->setVertexBuffer(s_ctx.m_dynamicVertexBuffers[_handle.idx]); + } + void setVertexBuffer(const TransientVertexBuffer* _vb) { s_ctx.m_submit->setVertexBuffer(_vb); diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 8a97206d..267fbcde 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -78,7 +78,9 @@ extern HWND g_bgfxHwnd; namespace std { namespace tr1 {} using namespace tr1; } // namespace std #include +#include #include +#include #include "config.h" @@ -178,7 +180,7 @@ namespace bgfx return _offset+align-(_offset%align); } - BX_FORCE_INLINE uint32_t castfi(float _value) + BX_FORCE_INLINE uint32_t castfu(float _value) { union { float fl; uint32_t ui; } un; un.fl = _value; @@ -434,9 +436,11 @@ namespace bgfx RendererInit, CreateVertexDecl, CreateIndexBuffer, - CreateTransientIndexBuffer, CreateVertexBuffer, - CreateTransientVertexBuffer, + CreateDynamicIndexBuffer, + UpdateDynamicIndexBuffer, + CreateDynamicVertexBuffer, + UpdateDynamicVertexBuffer, CreateVertexShader, CreateFragmentShader, CreateMaterial, @@ -447,9 +451,9 @@ namespace bgfx RendererShutdown, DestroyVertexDecl, DestroyIndexBuffer, - DestroyTransientIndexBuffer, DestroyVertexBuffer, - DestroyTransientVertexBuffer, + DestroyDynamicIndexBuffer, + DestroyDynamicVertexBuffer, DestroyVertexShader, DestroyFragmentShader, DestroyMaterial, @@ -881,6 +885,24 @@ namespace bgfx uint32_t m_flags; }; + struct DynamicIndexBuffer + { + IndexBufferHandle m_handle; + uint32_t m_offset; + uint32_t m_size; + }; + + struct DynamicVertexBuffer + { + VertexBufferHandle m_handle; + uint32_t m_offset; + uint32_t m_size; + uint32_t m_startVertex; + uint32_t m_numVertices; + uint32_t m_stride; + VertexDeclHandle m_decl; + }; + struct Frame { BX_CACHE_LINE_ALIGN_MARKER(); @@ -1021,6 +1043,14 @@ namespace bgfx m_state.m_vertexBuffer = _handle; } + void setVertexBuffer(const DynamicVertexBuffer& dvb) + { + m_state.m_startVertex = dvb.m_startVertex; + m_state.m_numVertices = dvb.m_numVertices; + m_state.m_vertexBuffer = dvb.m_handle; + m_state.m_vertexDecl = dvb.m_decl; + } + void setVertexBuffer(const TransientVertexBuffer* _vb) { m_state.m_startVertex = _vb->startVertex; @@ -1312,6 +1342,113 @@ namespace bgfx VertexDeclHandle m_vertexBufferRef[BGFX_CONFIG_MAX_VERTEX_BUFFERS]; }; + // First-fit non-local allocator. + class NonLocalAllocator + { + public: + static const uint64_t invalidBlock = UINT64_MAX; + + NonLocalAllocator() + { + } + + ~NonLocalAllocator() + { + } + + void reset() + { + m_free.clear(); + m_used.clear(); + } + + void add(uint64_t _ptr, uint32_t _size) + { + m_free.push_back(Free(_ptr, _size) ); + } + + uint64_t alloc(uint32_t _size) + { + for (FreeList::iterator it = m_free.begin(), itEnd = m_free.end(); it != itEnd; ++it) + { + if (it->m_size >= _size) + { + uint64_t ptr = it->m_ptr; + + m_used.insert(std::make_pair(ptr, _size) ); + + if (it->m_size != _size) + { + it->m_size -= _size; + it->m_ptr += _size; + } + else + { + m_free.erase(it); + } + + return ptr; + } + } + + // there is no block large enough. + return invalidBlock; + } + + void free(uint64_t _block) + { + UsedList::iterator it = m_used.find(_block); + if (it != m_used.end() ) + { + m_free.push_front(Free(it->first, it->second) ); + m_used.erase(it); + } + } + + void compact() + { + m_free.sort(); + + for (FreeList::iterator it = m_free.begin(), next = it, itEnd = m_free.end(); next != itEnd;) + { + if ( (it->m_ptr + it->m_size) == next->m_ptr) + { + it->m_size += next->m_size; + next = m_free.erase(next); + } + else + { + it = next; + ++next; + } + } + } + + private: + struct Free + { + Free(uint64_t _ptr, uint32_t _size) + : m_ptr(_ptr) + , m_size(_size) + { + } + + bool operator<(const Free& rhs) const + { + return m_ptr < rhs.m_ptr; + } + + uint64_t m_ptr; + uint32_t m_size; + }; + + typedef std::list FreeList; + FreeList m_free; + + typedef std::unordered_map UsedList; + UsedList m_used; + }; + #if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 DWORD WINAPI renderThread(LPVOID _arg); #elif BX_PLATFORM_LINUX @@ -1323,6 +1460,8 @@ namespace bgfx Context() : m_render(&m_frame[0]) , m_submit(&m_frame[1]) + , m_dynamicIndexBufferHandle(BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS) + , m_dynamicVertexBufferHandle(BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS) , m_indexBufferHandle(BGFX_CONFIG_MAX_INDEX_BUFFERS) , m_vertexDeclHandle(BGFX_CONFIG_MAX_VERTEX_DECLS) , m_vertexBufferHandle(BGFX_CONFIG_MAX_VERTEX_BUFFERS) @@ -1415,45 +1554,6 @@ namespace bgfx m_submit->free(_handle); } - TransientIndexBuffer* createTransientIndexBuffer(uint32_t _size) - { - IndexBufferHandle handle = { m_indexBufferHandle.alloc() }; - CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateTransientIndexBuffer); - cmdbuf.write(handle); - cmdbuf.write(_size); - - TransientIndexBuffer* ib = (TransientIndexBuffer*)g_realloc(NULL, sizeof(TransientIndexBuffer)+_size); - ib->data = (uint8_t*)&ib[1]; - ib->size = _size; - ib->handle = handle; - - return ib; - } - - void destroyTransientIndexBuffer(TransientIndexBuffer* _ib) - { - CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyTransientIndexBuffer); - cmdbuf.write(_ib->handle); - - m_submit->free(_ib->handle); - g_free(const_cast(_ib) ); - } - - const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num) - { - uint32_t offset = m_submit->allocTransientIndexBuffer(_num); - - TransientIndexBuffer& dib = *m_submit->m_transientIb; - - TransientIndexBuffer* ib = (TransientIndexBuffer*)g_realloc(NULL, sizeof(TransientIndexBuffer) ); - ib->data = &dib.data[offset]; - ib->size = _num * sizeof(uint16_t); - ib->handle = dib.handle; - ib->startIndex = offset/sizeof(uint16_t); - - return ib; - } - VertexDeclHandle findVertexDecl(const VertexDecl& _decl) { VertexDeclHandle declHandle = m_declRef.find(_decl.m_hash); @@ -1498,6 +1598,166 @@ namespace bgfx m_submit->free(_handle); } + DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem) + { + DynamicIndexBufferHandle handle = BGFX_INVALID_HANDLE; + uint32_t size = BX_ALIGN_16(_mem->size); + uint64_t ptr = m_dynamicIndexBufferAllocator.alloc(size); + if (ptr == NonLocalAllocator::invalidBlock) + { + IndexBufferHandle indexBufferHandle = { m_indexBufferHandle.alloc() }; + if (indexBufferHandle.idx == invalidHandle) + { + return handle; + } + + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicIndexBuffer); + cmdbuf.write(indexBufferHandle); + cmdbuf.write(BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE); + + m_dynamicIndexBufferAllocator.add(uint64_t(indexBufferHandle.idx)<<32, BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE); + ptr = m_dynamicIndexBufferAllocator.alloc(size); + } + + handle.idx = m_dynamicIndexBufferHandle.alloc(); + DynamicIndexBuffer& dib = m_dynamicIndexBuffers[handle.idx]; + dib.m_handle.idx = uint16_t(ptr>>32); + dib.m_offset = uint32_t(ptr); + dib.m_size = size; + + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::UpdateDynamicIndexBuffer); + cmdbuf.write(dib.m_handle); + cmdbuf.write(dib.m_offset); + cmdbuf.write(dib.m_size); + cmdbuf.write(_mem); + + return handle; + } + + void updateDynamicIndexBuffer(DynamicIndexBufferHandle _handle, const Memory* _mem) + { + DynamicIndexBuffer& dib = m_dynamicIndexBuffers[_handle.idx]; + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::UpdateDynamicIndexBuffer); + cmdbuf.write(dib.m_handle); + cmdbuf.write(dib.m_offset); + cmdbuf.write(dib.m_size); + cmdbuf.write(_mem); + } + + void destroyDynamicIndexBuffer(DynamicIndexBufferHandle _handle) + { + DynamicIndexBuffer& dib = m_dynamicIndexBuffers[_handle.idx]; + m_dynamicIndexBufferAllocator.free(uint64_t(dib.m_handle.idx)<<32 | dib.m_offset); + m_dynamicIndexBufferHandle.free(_handle.idx); + } + + DynamicVertexBufferHandle createDynamicVertexBuffer(const Memory* _mem, const VertexDecl& _decl) + { + DynamicVertexBufferHandle handle = BGFX_INVALID_HANDLE; + uint32_t size = strideAlign16(_mem->size, _decl.m_stride); + uint64_t ptr = m_dynamicVertexBufferAllocator.alloc(size); + if (ptr == NonLocalAllocator::invalidBlock) + { + VertexBufferHandle vertexBufferHandle = { m_vertexBufferHandle.alloc() }; + + if (vertexBufferHandle.idx == invalidHandle) + { + return handle; + } + + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicVertexBuffer); + cmdbuf.write(vertexBufferHandle); + cmdbuf.write(BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE); + + m_dynamicVertexBufferAllocator.add(uint64_t(vertexBufferHandle.idx)<<32, BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE); + ptr = m_dynamicVertexBufferAllocator.alloc(size); + } + + VertexDeclHandle declHandle = findVertexDecl(_decl); + + handle.idx = m_dynamicVertexBufferHandle.alloc(); + DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[handle.idx]; + dvb.m_handle.idx = uint16_t(ptr>>32); + dvb.m_offset = uint32_t(ptr); + dvb.m_size = size; + dvb.m_startVertex = dvb.m_offset/_decl.m_stride; + dvb.m_numVertices = dvb.m_size/_decl.m_stride; + dvb.m_decl = declHandle; + m_declRef.add(dvb.m_handle, declHandle, _decl.m_hash); + + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::UpdateDynamicVertexBuffer); + cmdbuf.write(dvb.m_handle); + cmdbuf.write(dvb.m_offset); + cmdbuf.write(dvb.m_size); + cmdbuf.write(_mem); + + return handle; + } + + void updateDynamicVertexBuffer(DynamicIndexBufferHandle _handle, const Memory* _mem) + { + DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[_handle.idx]; + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::UpdateDynamicVertexBuffer); + cmdbuf.write(dvb.m_handle); + cmdbuf.write(dvb.m_offset); + cmdbuf.write(dvb.m_size); + cmdbuf.write(_mem); + } + + void destroyDynamicVertexBuffer(DynamicVertexBufferHandle _handle) + { + DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[_handle.idx]; + + VertexDeclHandle declHandle = m_declRef.release(dvb.m_handle); + if (bgfx::invalidHandle != declHandle.idx) + { + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexDecl); + cmdbuf.write(declHandle); + } + + m_dynamicVertexBufferAllocator.free(uint64_t(dvb.m_handle.idx)<<32 | dvb.m_offset); + m_dynamicVertexBufferHandle.free(_handle.idx); + } + + TransientIndexBuffer* createTransientIndexBuffer(uint32_t _size) + { + IndexBufferHandle handle = { m_indexBufferHandle.alloc() }; + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicIndexBuffer); + cmdbuf.write(handle); + cmdbuf.write(_size); + + TransientIndexBuffer* ib = (TransientIndexBuffer*)g_realloc(NULL, sizeof(TransientIndexBuffer)+_size); + ib->data = (uint8_t*)&ib[1]; + ib->size = _size; + ib->handle = handle; + + return ib; + } + + void destroyTransientIndexBuffer(TransientIndexBuffer* _ib) + { + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyDynamicIndexBuffer); + cmdbuf.write(_ib->handle); + + m_submit->free(_ib->handle); + g_free(const_cast(_ib) ); + } + + const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num) + { + uint32_t offset = m_submit->allocTransientIndexBuffer(_num); + + TransientIndexBuffer& dib = *m_submit->m_transientIb; + + TransientIndexBuffer* ib = (TransientIndexBuffer*)g_realloc(NULL, sizeof(TransientIndexBuffer) ); + ib->data = &dib.data[offset]; + ib->size = _num * sizeof(uint16_t); + ib->handle = dib.handle; + ib->startIndex = offset/sizeof(uint16_t); + + return ib; + } + TransientVertexBuffer* createTransientVertexBuffer(uint32_t _size, const VertexDecl* _decl = NULL) { VertexBufferHandle handle = { m_vertexBufferHandle.alloc() }; @@ -1513,7 +1773,7 @@ namespace bgfx stride = _decl->m_stride; } - CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateTransientVertexBuffer); + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicVertexBuffer); cmdbuf.write(handle); cmdbuf.write(_size); @@ -1530,7 +1790,7 @@ namespace bgfx void destroyTransientVertexBuffer(TransientVertexBuffer* _vb) { - CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyTransientVertexBuffer); + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyDynamicVertexBuffer); cmdbuf.write(_vb->handle); m_submit->free(_vb->handle); @@ -1915,12 +2175,14 @@ namespace bgfx void rendererShutdown(); void rendererCreateIndexBuffer(IndexBufferHandle _handle, Memory* _mem); void rendererDestroyIndexBuffer(IndexBufferHandle _handle); - void rendererCreateTransientIndexBuffer(IndexBufferHandle _handle, uint32_t _size); - void rendererDestroyTransientIndexBuffer(IndexBufferHandle _handle); void rendererCreateVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle); void rendererDestroyVertexBuffer(VertexBufferHandle _handle); - void rendererCreateTransientVertexBuffer(VertexBufferHandle _handle, uint32_t _size); - void rendererDestroyTransientVertexBuffer(VertexBufferHandle _handle); + void rendererCreateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size); + void rendererUpdateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem); + void rendererDestroyDynamicIndexBuffer(IndexBufferHandle _handle); + void rendererCreateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size); + void rendererUpdateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem); + void rendererDestroyDynamicVertexBuffer(VertexBufferHandle _handle); void rendererCreateVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl); void rendererDestroyVertexDecl(VertexDeclHandle _handle); void rendererCreateVertexShader(VertexShaderHandle _handle, Memory* _mem); @@ -2014,27 +2276,6 @@ namespace bgfx } break; - case CommandBuffer::CreateTransientIndexBuffer: - { - IndexBufferHandle handle; - _cmdbuf.read(handle); - - uint32_t size; - _cmdbuf.read(size); - - rendererCreateTransientIndexBuffer(handle, size); - } - break; - - case CommandBuffer::DestroyTransientIndexBuffer: - { - IndexBufferHandle handle; - _cmdbuf.read(handle); - - rendererDestroyTransientIndexBuffer(handle); - } - break; - case CommandBuffer::CreateVertexDecl: { VertexDeclHandle handle; @@ -2082,7 +2323,48 @@ namespace bgfx } break; - case CommandBuffer::CreateTransientVertexBuffer: + case CommandBuffer::CreateDynamicIndexBuffer: + { + IndexBufferHandle handle; + _cmdbuf.read(handle); + + uint32_t size; + _cmdbuf.read(size); + + rendererCreateDynamicIndexBuffer(handle, size); + } + break; + + case CommandBuffer::UpdateDynamicIndexBuffer: + { + IndexBufferHandle handle; + _cmdbuf.read(handle); + + uint32_t offset; + _cmdbuf.read(offset); + + uint32_t size; + _cmdbuf.read(size); + + Memory* mem; + _cmdbuf.read(mem); + + rendererUpdateDynamicIndexBuffer(handle, offset, size, mem); + + release(mem); + } + break; + + case CommandBuffer::DestroyDynamicIndexBuffer: + { + IndexBufferHandle handle; + _cmdbuf.read(handle); + + rendererDestroyDynamicIndexBuffer(handle); + } + break; + + case CommandBuffer::CreateDynamicVertexBuffer: { VertexBufferHandle handle; _cmdbuf.read(handle); @@ -2090,16 +2372,36 @@ namespace bgfx uint32_t size; _cmdbuf.read(size); - rendererCreateTransientVertexBuffer(handle, size); + rendererCreateDynamicVertexBuffer(handle, size); } break; - case CommandBuffer::DestroyTransientVertexBuffer: + case CommandBuffer::UpdateDynamicVertexBuffer: { VertexBufferHandle handle; _cmdbuf.read(handle); - rendererDestroyTransientVertexBuffer(handle); + uint32_t offset; + _cmdbuf.read(offset); + + uint32_t size; + _cmdbuf.read(size); + + Memory* mem; + _cmdbuf.read(mem); + + rendererUpdateDynamicVertexBuffer(handle, offset, size, mem); + + release(mem); + } + break; + + case CommandBuffer::DestroyDynamicVertexBuffer: + { + VertexBufferHandle handle; + _cmdbuf.read(handle); + + rendererDestroyDynamicVertexBuffer(handle); } break; @@ -2347,6 +2649,14 @@ namespace bgfx uint64_t m_tempKeys[BGFX_CONFIG_MAX_DRAW_CALLS]; uint16_t m_tempValues[BGFX_CONFIG_MAX_DRAW_CALLS]; + DynamicIndexBuffer m_dynamicIndexBuffers[BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS]; + DynamicVertexBuffer m_dynamicVertexBuffers[BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS]; + + NonLocalAllocator m_dynamicIndexBufferAllocator; + HandleAlloc m_dynamicIndexBufferHandle; + NonLocalAllocator m_dynamicVertexBufferAllocator; + HandleAlloc m_dynamicVertexBufferHandle; + HandleAlloc m_indexBufferHandle; HandleAlloc m_vertexDeclHandle; HandleAlloc m_vertexBufferHandle; diff --git a/src/config.h b/src/config.h index 294beda6..f6f6ecd3 100644 --- a/src/config.h +++ b/src/config.h @@ -52,18 +52,34 @@ # define BGFX_CONFIG_MAX_VIEWS 32 #endif // BGFX_CONFIG_MAX_VIEWS -#ifndef BGFX_CONFIG_MAX_INDEX_BUFFERS -# define BGFX_CONFIG_MAX_INDEX_BUFFERS (4<<10) -#endif // BGFX_CONFIG_MAX_INDEX_BUFFERS - #ifndef BGFX_CONFIG_MAX_VERTEX_DECLS # define BGFX_CONFIG_MAX_VERTEX_DECLS 64 #endif // BGFX_CONFIG_MAX_VERTEX_DECLS +#ifndef BGFX_CONFIG_MAX_INDEX_BUFFERS +# define BGFX_CONFIG_MAX_INDEX_BUFFERS (4<<10) +#endif // BGFX_CONFIG_MAX_INDEX_BUFFERS + #ifndef BGFX_CONFIG_MAX_VERTEX_BUFFERS # define BGFX_CONFIG_MAX_VERTEX_BUFFERS (4<<10) #endif // BGFX_CONFIG_MAX_VERTEX_BUFFERS +#ifndef BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS +# define BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS (4<<10) +#endif // BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS + +#ifndef BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS +# define BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS (4<<10) +#endif // BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS + +#ifndef BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE +# define BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE (1<<20) +#endif // BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE + +#ifndef BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE +# define BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE (3<<20) +#endif // BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE + #ifndef BGFX_CONFIG_MAX_VERTEX_SHADERS # define BGFX_CONFIG_MAX_VERTEX_SHADERS 256 #endif // BGFX_CONFIG_MAX_VERTEX_SHADERS diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 0b0a516c..d237508f 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -697,7 +697,7 @@ namespace bgfx if (NULL != _data) { - update(_size, _data); + update(0, _size, _data); } } @@ -748,7 +748,7 @@ namespace bgfx if (NULL != _data) { - update(_size, _data); + update(0, _size, _data); } } @@ -1578,8 +1578,8 @@ namespace bgfx void TextVideoMemBlitter::render(uint32_t _numIndices) { uint32_t numVertices = _numIndices*4/6; - s_renderCtx.m_indexBuffers[m_ib->handle.idx].update(_numIndices*2, m_ib->data); - s_renderCtx.m_vertexBuffers[m_vb->handle.idx].update(numVertices*m_decl.m_stride, m_vb->data); + s_renderCtx.m_indexBuffers[m_ib->handle.idx].update(0, _numIndices*2, m_ib->data); + s_renderCtx.m_vertexBuffers[m_vb->handle.idx].update(0, numVertices*m_decl.m_stride, m_vb->data); DX_CHECK(s_renderCtx.m_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST , 0 @@ -1615,16 +1615,6 @@ namespace bgfx s_renderCtx.m_indexBuffers[_handle.idx].destroy(); } - void Context::rendererCreateTransientIndexBuffer(IndexBufferHandle _handle, uint32_t _size) - { - s_renderCtx.m_indexBuffers[_handle.idx].create(_size, NULL); - } - - void Context::rendererDestroyTransientIndexBuffer(IndexBufferHandle _handle) - { - s_renderCtx.m_indexBuffers[_handle.idx].destroy(); - } - void Context::rendererCreateVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl) { s_renderCtx.m_vertexDecls[_handle.idx].create(_decl); @@ -1645,13 +1635,33 @@ namespace bgfx s_renderCtx.m_vertexBuffers[_handle.idx].destroy(); } - void Context::rendererCreateTransientVertexBuffer(VertexBufferHandle _handle, uint32_t _size) + void Context::rendererCreateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size) + { + s_renderCtx.m_indexBuffers[_handle.idx].create(_size, NULL); + } + + void Context::rendererUpdateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) + { + s_renderCtx.m_indexBuffers[_handle.idx].update(_offset, uint32_min(_size, _mem->size), _mem->data); + } + + void Context::rendererDestroyDynamicIndexBuffer(IndexBufferHandle _handle) + { + s_renderCtx.m_indexBuffers[_handle.idx].destroy(); + } + + void Context::rendererCreateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size) { VertexDeclHandle decl = BGFX_INVALID_HANDLE; s_renderCtx.m_vertexBuffers[_handle.idx].create(_size, NULL, decl); } - void Context::rendererDestroyTransientVertexBuffer(VertexBufferHandle _handle) + void Context::rendererUpdateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) + { + s_renderCtx.m_vertexBuffers[_handle.idx].update(_offset, uint32_min(_size, _mem->size), _mem->data); + } + + void Context::rendererDestroyDynamicVertexBuffer(VertexBufferHandle _handle) { s_renderCtx.m_vertexBuffers[_handle.idx].destroy(); } @@ -1740,13 +1750,13 @@ namespace bgfx if (0 < m_render->m_iboffset) { TransientIndexBuffer* ib = m_render->m_transientIb; - s_renderCtx.m_indexBuffers[ib->handle.idx].update(m_render->m_iboffset, ib->data); + s_renderCtx.m_indexBuffers[ib->handle.idx].update(0, m_render->m_iboffset, ib->data); } if (0 < m_render->m_vboffset) { TransientVertexBuffer* vb = m_render->m_transientVb; - s_renderCtx.m_vertexBuffers[vb->handle.idx].update(m_render->m_vboffset, vb->data); + s_renderCtx.m_vertexBuffers[vb->handle.idx].update(0, m_render->m_vboffset, vb->data); } m_render->sort(); @@ -1899,7 +1909,7 @@ namespace bgfx if ( (BGFX_STATE_PT_POINTS|BGFX_STATE_POINT_SIZE_MASK) & changedFlags) { - DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_POINTSIZE, castfi( (float)( (newFlags&BGFX_STATE_POINT_SIZE_MASK)>>BGFX_STATE_POINT_SIZE_SHIFT) ) ) ); + DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_POINTSIZE, castfu( (float)( (newFlags&BGFX_STATE_POINT_SIZE_MASK)>>BGFX_STATE_POINT_SIZE_SHIFT) ) ) ); } #if BX_PLATFORM_WINDOWS diff --git a/src/renderer_d3d9.h b/src/renderer_d3d9.h index 2bd898f7..5a30f231 100644 --- a/src/renderer_d3d9.h +++ b/src/renderer_d3d9.h @@ -128,13 +128,13 @@ namespace bgfx } void create(uint32_t _size, void* _data); - void update(uint32_t _size, void* _data) + void update(uint32_t _offset, uint32_t _size, void* _data) { void* buffer; - DX_CHECK(m_ptr->Lock(0 + DX_CHECK(m_ptr->Lock(_offset , _size , &buffer - , m_dynamic?D3DLOCK_DISCARD/*|D3DLOCK_NOOVERWRITE*/:0 + , m_dynamic && 0 == _offset && m_size == _size ? D3DLOCK_DISCARD : 0 ) ); memcpy(buffer, _data, _size); @@ -168,13 +168,13 @@ namespace bgfx } void create(uint32_t _size, void* _data, VertexDeclHandle _declHandle); - void update(uint32_t _size, void* _data) + void update(uint32_t _offset, uint32_t _size, void* _data) { void* buffer; - DX_CHECK(m_ptr->Lock(0 + DX_CHECK(m_ptr->Lock(_offset , _size , &buffer - , m_dynamic?D3DLOCK_DISCARD/*|D3DLOCK_NOOVERWRITE*/:0 + , m_dynamic && 0 == _offset && m_size == _size ? D3DLOCK_DISCARD : 0 ) ); memcpy(buffer, _data, _size); diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index c18756d8..019d8cca 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -1562,8 +1562,8 @@ namespace bgfx void TextVideoMemBlitter::render(uint32_t _numIndices) { uint32_t numVertices = _numIndices*4/6; - s_renderCtx.m_indexBuffers[m_ib->handle.idx].update(_numIndices*2, m_ib->data); - s_renderCtx.m_vertexBuffers[m_vb->handle.idx].update(numVertices*m_decl.m_stride, m_vb->data); + s_renderCtx.m_indexBuffers[m_ib->handle.idx].update(0, _numIndices*2, m_ib->data); + s_renderCtx.m_vertexBuffers[m_vb->handle.idx].update(0, numVertices*m_decl.m_stride, m_vb->data); VertexBuffer& vb = s_renderCtx.m_vertexBuffers[m_vb->handle.idx]; GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) ); @@ -1702,16 +1702,6 @@ namespace bgfx s_renderCtx.m_indexBuffers[_handle.idx].destroy(); } - void Context::rendererCreateTransientIndexBuffer(IndexBufferHandle _handle, uint32_t _size) - { - s_renderCtx.m_indexBuffers[_handle.idx].create(_size, NULL); - } - - void Context::rendererDestroyTransientIndexBuffer(IndexBufferHandle _handle) - { - s_renderCtx.m_indexBuffers[_handle.idx].destroy(); - } - void Context::rendererCreateVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl) { VertexDecl& decl = s_renderCtx.m_vertexDecls[_handle.idx]; @@ -1733,13 +1723,33 @@ namespace bgfx s_renderCtx.m_vertexBuffers[_handle.idx].destroy(); } - void Context::rendererCreateTransientVertexBuffer(VertexBufferHandle _handle, uint32_t _size) + void Context::rendererCreateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size) + { + s_renderCtx.m_indexBuffers[_handle.idx].create(_size, NULL); + } + + void Context::rendererUpdateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) + { + s_renderCtx.m_indexBuffers[_handle.idx].update(_offset, uint32_min(_size, _mem->size), _mem->data); + } + + void Context::rendererDestroyDynamicIndexBuffer(IndexBufferHandle _handle) + { + s_renderCtx.m_indexBuffers[_handle.idx].destroy(); + } + + void Context::rendererCreateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size) { VertexDeclHandle decl = BGFX_INVALID_HANDLE; s_renderCtx.m_vertexBuffers[_handle.idx].create(_size, NULL, decl); } - void Context::rendererDestroyTransientVertexBuffer(VertexBufferHandle _handle) + void Context::rendererUpdateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) + { + s_renderCtx.m_vertexBuffers[_handle.idx].update(_offset, uint32_min(_size, _mem->size), _mem->data); + } + + void Context::rendererDestroyDynamicVertexBuffer(VertexBufferHandle _handle) { s_renderCtx.m_vertexBuffers[_handle.idx].destroy(); } @@ -1824,13 +1834,13 @@ namespace bgfx if (0 < m_render->m_iboffset) { TransientIndexBuffer* ib = m_render->m_transientIb; - s_renderCtx.m_indexBuffers[ib->handle.idx].update(m_render->m_iboffset, ib->data); + s_renderCtx.m_indexBuffers[ib->handle.idx].update(0, m_render->m_iboffset, ib->data); } if (0 < m_render->m_vboffset) { TransientVertexBuffer* vb = m_render->m_transientVb; - s_renderCtx.m_vertexBuffers[vb->handle.idx].update(m_render->m_vboffset, vb->data); + s_renderCtx.m_vertexBuffers[vb->handle.idx].update(0, m_render->m_vboffset, vb->data); } m_render->sort(); diff --git a/src/renderer_gl.h b/src/renderer_gl.h index 01912724..fbcb03e9 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -54,12 +54,12 @@ # endif // BX_PLATFORM_ # ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT -# define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -# endif // GL_COMPRESSED_RGBA_S3TC_DXT3_EXT - -# ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT -# define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 -# endif // GL_COMPRESSED_RGBA_S3TC_DXT5_EXT +# define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +# endif // GL_COMPRESSED_RGBA_S3TC_DXT3_EXT + +# ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT +# define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +# endif // GL_COMPRESSED_RGBA_S3TC_DXT5_EXT # ifndef GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE # define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 @@ -187,11 +187,11 @@ namespace bgfx GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) ); } - void update(uint32_t _size, void* _data) + void update(uint32_t _offset, uint32_t _size, void* _data) { GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_id) ); GL_CHECK(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER - , 0 + , _offset , _size , _data ) ); @@ -226,11 +226,11 @@ namespace bgfx GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) ); } - void update(uint32_t _size, void* _data) + void update(uint32_t _offset, uint32_t _size, void* _data) { GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, m_id) ); GL_CHECK(glBufferSubData(GL_ARRAY_BUFFER - , 0 + , _offset , _size , _data ) ); diff --git a/src/renderer_null.cpp b/src/renderer_null.cpp index 21df1c67..8894334e 100644 --- a/src/renderer_null.cpp +++ b/src/renderer_null.cpp @@ -41,14 +41,6 @@ namespace bgfx { } - void Context::rendererCreateTransientIndexBuffer(IndexBufferHandle _handle, uint32_t _size) - { - } - - void Context::rendererDestroyTransientIndexBuffer(IndexBufferHandle _handle) - { - } - void Context::rendererCreateVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl) { } @@ -65,11 +57,27 @@ namespace bgfx { } - void Context::rendererCreateTransientVertexBuffer(VertexBufferHandle _handle, uint32_t _size) + void Context::rendererCreateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size) { } - void Context::rendererDestroyTransientVertexBuffer(VertexBufferHandle _handle) + void Context::rendererUpdateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) + { + } + + void Context::rendererDestroyDynamicIndexBuffer(IndexBufferHandle _handle) + { + } + + void Context::rendererCreateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size) + { + } + + void Context::rendererUpdateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) + { + } + + void Context::rendererDestroyDynamicVertexBuffer(uint16_t _pool) { }