32-bit indices support WIP.

This commit is contained in:
Branimir Karadžić 2015-04-08 19:59:48 -07:00
parent 1824a3f5bd
commit 23114a821c
9 changed files with 100 additions and 42 deletions

View File

@ -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)

View File

@ -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
};

View File

@ -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;
}

View File

@ -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) );
@ -2366,6 +2367,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
{
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
{

View File

@ -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;
};

View File

@ -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,9 +1765,10 @@ 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_flags = _flags;
m_dynamic = NULL == _data;
uint32_t usage = D3DUSAGE_WRITEONLY;
@ -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;

View File

@ -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;
};

View File

@ -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
) );

View File

@ -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_flags = _flags;
GL_CHECK(glGenBuffers(1, &m_id) );
BX_CHECK(0 != m_id, "Failed to generate buffer id.");
@ -817,6 +818,7 @@ namespace bgfx { namespace gl
GLuint m_id;
uint32_t m_size;
VaoCacheRef m_vcref;
uint8_t m_flags;
};
struct VertexBufferGL