diff --git a/include/bgfxdefines.h b/include/bgfxdefines.h index f8878a9e..1c8a894a 100644 --- a/include/bgfxdefines.h +++ b/include/bgfxdefines.h @@ -225,6 +225,7 @@ #define BGFX_BUFFER_COMPUTE_READ UINT8_C(0x01) #define BGFX_BUFFER_COMPUTE_WRITE UINT8_C(0x02) #define BGFX_BUFFER_ALLOW_RESIZE UINT8_C(0x04) +#define BGFX_BUFFER_INDEX32 UINT8_C(0x08) #define BGFX_BUFFER_COMPUTE_READ_WRITE (BGFX_BUFFER_COMPUTE_READ | BGFX_BUFFER_COMPUTE_WRITE) /// @@ -316,6 +317,7 @@ #define BGFX_CAPS_FRAGMENT_ORDERING UINT64_C(0x0000000000000200) #define BGFX_CAPS_SWAP_CHAIN UINT64_C(0x0000000000000400) #define BGFX_CAPS_HMD UINT64_C(0x0000000000000800) +#define BGFX_CAPS_INDEX32 UINT64_C(0x0000000000001000) /// #define BGFX_CAPS_FORMAT_TEXTURE_NONE UINT8_C(0x00) diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 677d7e26..867aa477 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -887,6 +887,7 @@ namespace bgfx CAPS_FLAGS(BGFX_CAPS_FRAGMENT_ORDERING), CAPS_FLAGS(BGFX_CAPS_SWAP_CHAIN), CAPS_FLAGS(BGFX_CAPS_HMD), + CAPS_FLAGS(BGFX_CAPS_INDEX32), #undef CAPS_FLAGS }; diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 63a30325..ca818db6 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -1378,8 +1378,9 @@ namespace bgfx void setIndexBuffer(const DynamicIndexBuffer& _dib, uint32_t _firstIndex, uint32_t _numIndices) { + const uint32_t indexSize = 0 == (_dib.m_flags & BGFX_BUFFER_INDEX32) ? 2 : 4; m_draw.m_startIndex = _dib.m_startIndex + _firstIndex; - m_draw.m_numIndices = bx::uint32_min(_numIndices, _dib.m_size/2); + m_draw.m_numIndices = bx::uint32_min(_numIndices, _dib.m_size/indexSize); m_draw.m_indexBuffer = _dib.m_handle; } @@ -2106,7 +2107,8 @@ namespace bgfx BGFX_API_FUNC(DynamicIndexBufferHandle createDynamicIndexBuffer(uint32_t _num, uint8_t _flags) ) { DynamicIndexBufferHandle handle = BGFX_INVALID_HANDLE; - uint32_t size = BX_ALIGN_16( (_num+1)*2); + const uint32_t indexSize = 0 == (_flags & BGFX_BUFFER_INDEX32) ? 2 : 4; + uint32_t size = BX_ALIGN_16( (_num+1)*indexSize); uint64_t ptr = 0; if (0 != (_flags & BGFX_BUFFER_COMPUTE_WRITE) ) @@ -2144,7 +2146,7 @@ namespace bgfx dib.m_handle.idx = uint16_t(ptr>>32); dib.m_offset = uint32_t(ptr); dib.m_size = size; - dib.m_startIndex = strideAlign(dib.m_offset, 2)/2; + dib.m_startIndex = strideAlign(dib.m_offset, indexSize)/indexSize; dib.m_flags = _flags; return handle; @@ -2153,7 +2155,8 @@ namespace bgfx BGFX_API_FUNC(DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem, uint8_t _flags) ) { BX_CHECK(0 == (_flags & BGFX_BUFFER_COMPUTE_READ_WRITE), "Cannot initialize compute buffer from CPU."); - DynamicIndexBufferHandle handle = createDynamicIndexBuffer(_mem->size/2, _flags); + const uint32_t indexSize = 0 == (_flags & BGFX_BUFFER_INDEX32) ? 2 : 4; + DynamicIndexBufferHandle handle = createDynamicIndexBuffer(_mem->size/indexSize, _flags); if (isValid(handle) ) { updateDynamicIndexBuffer(handle, _mem); @@ -2167,6 +2170,7 @@ namespace bgfx DynamicIndexBuffer& dib = m_dynamicIndexBuffers[_handle.idx]; BX_CHECK(0 == (dib.m_flags & BGFX_BUFFER_COMPUTE_READ_WRITE), "Can't update GPU buffer from CPU."); + const uint32_t indexSize = 0 == (dib.m_flags & BGFX_BUFFER_INDEX32) ? 2 : 4; if (dib.m_size < _mem->size && 0 != (dib.m_flags & BGFX_BUFFER_ALLOW_RESIZE) ) @@ -2178,10 +2182,10 @@ namespace bgfx dib.m_handle.idx = uint16_t(ptr>>32); dib.m_offset = uint32_t(ptr); dib.m_size = _mem->size; - dib.m_startIndex = strideAlign(dib.m_offset, 2)/2; + dib.m_startIndex = strideAlign(dib.m_offset, indexSize)/indexSize; } - uint32_t offset = dib.m_startIndex*2; + uint32_t offset = dib.m_startIndex*indexSize; uint32_t size = bx::uint32_min(dib.m_size, _mem->size); BX_CHECK(_mem->size <= size, "Truncating dynamic index buffer update (size %d, mem size %d)." , size @@ -2426,11 +2430,11 @@ namespace bgfx { uint32_t offset = m_submit->allocTransientIndexBuffer(_num); - TransientIndexBuffer& dib = *m_submit->m_transientIb; + TransientIndexBuffer& tib = *m_submit->m_transientIb; - _tib->data = &dib.data[offset]; + _tib->data = &tib.data[offset]; _tib->size = _num * 2; - _tib->handle = dib.handle; + _tib->handle = tib.handle; _tib->startIndex = strideAlign(offset, 2)/2; } diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 4380f894..87cff84c 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -769,6 +769,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); | (getIntelExtensions(m_device) ? BGFX_CAPS_FRAGMENT_ORDERING : 0) | BGFX_CAPS_SWAP_CHAIN | (m_ovr.isInitialized() ? BGFX_CAPS_HMD : 0) + | BGFX_CAPS_INDEX32 ); g_caps.maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; g_caps.maxFBAttachments = uint8_t(bx::uint32_min(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) ); @@ -2364,8 +2365,9 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void BufferD3D11::create(uint32_t _size, void* _data, uint8_t _flags, uint16_t _stride, bool _vertex) { - m_uav = NULL; - m_size = _size; + m_uav = NULL; + m_size = _size; + m_flags = _flags; const bool needUav = 0 != (_flags & BGFX_BUFFER_COMPUTE_WRITE); const bool needSrv = 0 != (_flags & BGFX_BUFFER_COMPUTE_READ); @@ -2381,9 +2383,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); desc.MiscFlags = 0; desc.StructureByteStride = 0; - DXGI_FORMAT format = _vertex + const DXGI_FORMAT indexFormat = 0 == (_flags & BGFX_BUFFER_INDEX32) + ? DXGI_FORMAT_R16_UINT + : DXGI_FORMAT_R32_UINT + ; + const DXGI_FORMAT format = _vertex ? DXGI_FORMAT_R32G32B32A32_FLOAT - : DXGI_FORMAT_R16_UINT + : indexFormat ; ID3D11Device* device = s_renderD3D11->m_device; @@ -2512,7 +2518,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); : 0 ; - BufferD3D11::create(_size, _data, _flags, stride); + BufferD3D11::create(_size, _data, _flags, stride, true); } void ShaderD3D11::create(const Memory* _mem) @@ -3690,7 +3696,10 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (invalidHandle != handle) { const IndexBufferD3D11& ib = m_indexBuffers[handle]; - deviceCtx->IASetIndexBuffer(ib.m_ptr, DXGI_FORMAT_R16_UINT, 0); + deviceCtx->IASetIndexBuffer(ib.m_ptr + , 0 == (ib.m_flags & BGFX_BUFFER_INDEX32) ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT + , 0 + ); } else { diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h index e3a6b7d9..1a5c5655 100644 --- a/src/renderer_d3d11.h +++ b/src/renderer_d3d11.h @@ -100,11 +100,12 @@ namespace bgfx { namespace d3d11 : m_ptr(NULL) , m_srv(NULL) , m_uav(NULL) + , m_flags(BGFX_BUFFER_NONE) , m_dynamic(false) { } - void create(uint32_t _size, void* _data, uint8_t _flags, uint16_t _stride = 0, bool _vertex = true); + void create(uint32_t _size, void* _data, uint8_t _flags, uint16_t _stride = 0, bool _vertex = false); void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false); void destroy() @@ -123,6 +124,7 @@ namespace bgfx { namespace d3d11 ID3D11ShaderResourceView* m_srv; ID3D11UnorderedAccessView* m_uav; uint32_t m_size; + uint8_t m_flags; bool m_dynamic; }; diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 970485bb..0c5df9f5 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -462,6 +462,7 @@ namespace bgfx { namespace d3d9 BX_TRACE("Max fragment shader 2.0 instr. slots: %d", m_caps.PS20Caps.NumInstructionSlots); BX_TRACE("Max fragment shader 3.0 instr. slots: %d", m_caps.MaxPixelShader30InstructionSlots); BX_TRACE("Num simultaneous render targets: %d", m_caps.NumSimultaneousRTs); + BX_TRACE("Max vertex index: %d", m_caps.MaxVertexIndex); g_caps.supported |= ( 0 | BGFX_CAPS_TEXTURE_3D @@ -469,8 +470,10 @@ namespace bgfx { namespace d3d9 | BGFX_CAPS_VERTEX_ATTRIB_HALF | BGFX_CAPS_FRAGMENT_DEPTH | BGFX_CAPS_SWAP_CHAIN + | ( (UINT16_MAX < m_caps.MaxVertexIndex) ? BGFX_CAPS_INDEX32 : 0) ); g_caps.maxTextureSize = uint16_t(bx::uint32_min(m_caps.MaxTextureWidth, m_caps.MaxTextureHeight) ); +// g_caps.maxVertexIndex = m_caps.MaxVertexIndex; m_caps.NumSimultaneousRTs = uint8_t(bx::uint32_min(m_caps.NumSimultaneousRTs, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) ); g_caps.maxFBAttachments = uint8_t(m_caps.NumSimultaneousRTs); @@ -668,9 +671,9 @@ namespace bgfx { namespace d3d9 return BGFX_RENDERER_DIRECT3D9_NAME; } - void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem, uint8_t /*_flags*/) BX_OVERRIDE + void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem, uint8_t _flags) BX_OVERRIDE { - m_indexBuffers[_handle.idx].create(_mem->size, _mem->data); + m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags); } void destroyIndexBuffer(IndexBufferHandle _handle) BX_OVERRIDE @@ -698,9 +701,9 @@ namespace bgfx { namespace d3d9 m_vertexBuffers[_handle.idx].destroy(); } - void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint8_t /*_flags*/) BX_OVERRIDE + void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint8_t _flags) BX_OVERRIDE { - m_indexBuffers[_handle.idx].create(_size, NULL); + m_indexBuffers[_handle.idx].create(_size, NULL, _flags); } void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) BX_OVERRIDE @@ -1762,13 +1765,14 @@ namespace bgfx { namespace d3d9 s_renderD3D9 = NULL; } - void IndexBufferD3D9::create(uint32_t _size, void* _data) + void IndexBufferD3D9::create(uint32_t _size, void* _data, uint8_t _flags) { - m_size = _size; + m_size = _size; + m_flags = _flags; m_dynamic = NULL == _data; uint32_t usage = D3DUSAGE_WRITEONLY; - D3DPOOL pool = s_renderD3D9->m_pool; + D3DPOOL pool = s_renderD3D9->m_pool; if (m_dynamic) { @@ -1776,9 +1780,14 @@ namespace bgfx { namespace d3d9 pool = D3DPOOL_DEFAULT; } + const D3DFORMAT format = 0 == (_flags & BGFX_BUFFER_INDEX32) + ? D3DFMT_INDEX16 + : D3DFMT_INDEX32 + ; + DX_CHECK(s_renderD3D9->m_device->CreateIndexBuffer(m_size , usage - , D3DFMT_INDEX16 + , format , pool , &m_ptr , NULL @@ -1802,9 +1811,14 @@ namespace bgfx { namespace d3d9 { if (m_dynamic) { + const D3DFORMAT format = 0 == (m_flags & BGFX_BUFFER_INDEX32) + ? D3DFMT_INDEX16 + : D3DFMT_INDEX32 + ; + DX_CHECK(s_renderD3D9->m_device->CreateIndexBuffer(m_size , D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC - , D3DFMT_INDEX16 + , format , D3DPOOL_DEFAULT , &m_ptr , NULL @@ -3325,7 +3339,9 @@ namespace bgfx { namespace d3d9 { if (UINT32_MAX == draw.m_numIndices) { - numIndices = m_indexBuffers[draw.m_indexBuffer.idx].m_size/2; + const IndexBufferD3D9& ib = m_indexBuffers[draw.m_indexBuffer.idx]; + const uint32_t indexSize = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32) ? 2 : 4; + numIndices = ib.m_size/indexSize; numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub; numInstances = draw.m_numInstances; numPrimsRendered = numPrimsSubmitted*draw.m_numInstances; diff --git a/src/renderer_d3d9.h b/src/renderer_d3d9.h index 5ff37625..429721fa 100644 --- a/src/renderer_d3d9.h +++ b/src/renderer_d3d9.h @@ -129,11 +129,13 @@ namespace bgfx { namespace d3d9 { IndexBufferD3D9() : m_ptr(NULL) + , m_size(0) + , m_flags(BGFX_BUFFER_NONE) , m_dynamic(false) { } - void create(uint32_t _size, void* _data); + void create(uint32_t _size, void* _data, uint8_t _flags); void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false) { void* buffer; @@ -162,6 +164,7 @@ namespace bgfx { namespace d3d9 IDirect3DIndexBuffer9* m_ptr; uint32_t m_size; + uint8_t m_flags; bool m_dynamic; }; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 86a0c06f..19d20e9e 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -479,6 +479,7 @@ namespace bgfx { namespace gl OES_depth24, OES_depth32, OES_depth_texture, + OES_element_index_uint, OES_fragment_precision_high, OES_get_program_binary, OES_required_internalformat, @@ -666,6 +667,7 @@ namespace bgfx { namespace gl { "OES_depth24", false, true }, { "OES_depth32", false, true }, { "OES_depth_texture", false, true }, + { "OES_element_index_uint", false, true }, { "OES_fragment_precision_high", false, true }, { "OES_get_program_binary", false, true }, { "OES_required_internalformat", false, true }, @@ -1330,19 +1332,23 @@ namespace bgfx { namespace gl g_caps.formats[ii] = s_textureFormat[ii].m_supported ? 1 : 0; } - g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL || BGFX_CONFIG_RENDERER_OPENGLES >= 30) || s_extension[Extension::OES_texture_3D].m_supported + g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL || BGFX_CONFIG_RENDERER_OPENGLES >= 30) + || s_extension[Extension::OES_texture_3D].m_supported ? BGFX_CAPS_TEXTURE_3D : 0 ; - g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL || BGFX_CONFIG_RENDERER_OPENGLES >= 30) || s_extension[Extension::EXT_shadow_samplers].m_supported + g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL || BGFX_CONFIG_RENDERER_OPENGLES >= 30) + || s_extension[Extension::EXT_shadow_samplers].m_supported ? BGFX_CAPS_TEXTURE_COMPARE_ALL : 0 ; - g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL || BGFX_CONFIG_RENDERER_OPENGLES >= 30) || s_extension[Extension::OES_vertex_half_float].m_supported + g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL || BGFX_CONFIG_RENDERER_OPENGLES >= 30) + || s_extension[Extension::OES_vertex_half_float].m_supported ? BGFX_CAPS_VERTEX_ATTRIB_HALF : 0 ; - g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL || BGFX_CONFIG_RENDERER_OPENGLES >= 30) || s_extension[Extension::EXT_frag_depth].m_supported + g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL || BGFX_CONFIG_RENDERER_OPENGLES >= 30) + || s_extension[Extension::EXT_frag_depth].m_supported ? BGFX_CAPS_FRAGMENT_DEPTH : 0 ; @@ -1354,6 +1360,11 @@ namespace bgfx { namespace gl ? BGFX_CAPS_FRAGMENT_ORDERING : 0 ; + g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL || BGFX_CONFIG_RENDERER_OPENGLES >= 30) + || s_extension[Extension::OES_element_index_uint].m_supported + ? BGFX_CAPS_INDEX32 + : 0 + ; g_caps.maxTextureSize = uint16_t(glGet(GL_MAX_TEXTURE_SIZE) ); @@ -1607,9 +1618,9 @@ namespace bgfx { namespace gl } } - void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem, uint8_t /*_flags*/) BX_OVERRIDE + void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem, uint8_t _flags) BX_OVERRIDE { - m_indexBuffers[_handle.idx].create(_mem->size, _mem->data); + m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags); } void destroyIndexBuffer(IndexBufferHandle _handle) BX_OVERRIDE @@ -1638,9 +1649,9 @@ namespace bgfx { namespace gl m_vertexBuffers[_handle.idx].destroy(); } - void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint8_t /*_flags*/) BX_OVERRIDE + void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint8_t _flags) BX_OVERRIDE { - m_indexBuffers[_handle.idx].create(_size, NULL); + m_indexBuffers[_handle.idx].create(_size, NULL, _flags); } void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) BX_OVERRIDE @@ -5253,16 +5264,24 @@ namespace bgfx { namespace gl if (isValid(draw.m_indexBuffer) ) { + const IndexBufferGL& ib = m_indexBuffers[draw.m_indexBuffer.idx]; + const bool hasIndex16 = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32); + const GLenum indexFormat = hasIndex16 + ? GL_UNSIGNED_SHORT + : GL_UNSIGNED_INT + ; + if (UINT32_MAX == draw.m_numIndices) { - numIndices = m_indexBuffers[draw.m_indexBuffer.idx].m_size/2; + const uint32_t indexSize = hasIndex16 ? 2 : 4; + numIndices = ib.m_size/indexSize; numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub; numInstances = draw.m_numInstances; numPrimsRendered = numPrimsSubmitted*draw.m_numInstances; GL_CHECK(glDrawElementsInstanced(prim.m_type , numIndices - , GL_UNSIGNED_SHORT + , indexFormat , (void*)0 , draw.m_numInstances ) ); @@ -5276,7 +5295,7 @@ namespace bgfx { namespace gl GL_CHECK(glDrawElementsInstanced(prim.m_type , numIndices - , GL_UNSIGNED_SHORT + , indexFormat , (void*)(uintptr_t)(draw.m_startIndex*2) , draw.m_numInstances ) ); diff --git a/src/renderer_gl.h b/src/renderer_gl.h index db4e1f06..d21629f7 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -780,9 +780,10 @@ namespace bgfx { namespace gl struct IndexBufferGL { - void create(uint32_t _size, void* _data) + void create(uint32_t _size, void* _data, uint8_t _flags) { - m_size = _size; + m_size = _size; + m_flags = _flags; GL_CHECK(glGenBuffers(1, &m_id) ); BX_CHECK(0 != m_id, "Failed to generate buffer id."); @@ -790,7 +791,7 @@ namespace bgfx { namespace gl GL_CHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER , _size , _data - , (NULL==_data)?GL_DYNAMIC_DRAW:GL_STATIC_DRAW + , (NULL==_data) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW ) ); GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) ); } @@ -817,6 +818,7 @@ namespace bgfx { namespace gl GLuint m_id; uint32_t m_size; VaoCacheRef m_vcref; + uint8_t m_flags; }; struct VertexBufferGL @@ -832,7 +834,7 @@ namespace bgfx { namespace gl GL_CHECK(glBufferData(GL_ARRAY_BUFFER , _size , _data - , (NULL==_data)?GL_DYNAMIC_DRAW:GL_STATIC_DRAW + , (NULL==_data) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW ) ); GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) ); }