From 37f00de7de338db3566c415b1b7cd2506c545a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 15 Sep 2016 20:54:00 -0700 Subject: [PATCH] Fixed issue #917. --- src/bgfx.cpp | 12 +++++++ src/bgfx_p.h | 71 ++++++++++++++++++++++-------------------- src/renderer_d3d11.cpp | 4 ++- src/renderer_d3d9.cpp | 4 ++- src/renderer_gl.cpp | 9 ++++-- src/renderer_mtl.mm | 8 +++-- 6 files changed, 69 insertions(+), 39 deletions(-) diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 1dfe0c6d1..4a03b4a10 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -898,6 +898,18 @@ namespace bgfx m_draw.m_constEnd = m_uniformEnd; m_draw.m_stateFlags |= m_stateFlags; + uint32_t numVertices = UINT32_MAX; + for (uint32_t idx = 0, streamMask = m_draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) + ; 0 != streamMask + ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask) + ) + { + streamMask >>= ntz; + idx += ntz; + numVertices = bx::uint32_min(numVertices, m_numVertices[idx]); + } + m_draw.m_numVertices = numVertices; + if (isValid(_occlusionQuery) ) { BX_CHECK(!isValid(m_draw.m_occlusionQuery), ""); diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 9e938e3f6..fb0c2f751 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -1267,6 +1267,15 @@ namespace bgfx } } + bool setStreamBit(uint8_t _stream, VertexBufferHandle _handle) + { + const uint8_t bit = 1<<_stream; + const uint8_t mask = m_streamMask & ~bit; + const uint8_t tmp = isValid(_handle) ? bit : 0; + m_streamMask = mask | tmp; + return 0 != tmp; + } + Binding m_bind[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; Stream m_stream[BGFX_CONFIG_MAX_VERTEX_STREAMS]; uint64_t m_stateFlags; @@ -1569,47 +1578,42 @@ namespace bgfx void setVertexBuffer(uint8_t _stream, VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _numVertices) { - const uint8_t bit = 1<<_stream; -// BX_CHECK(0 == (m_draw.m_streamMask & bit), "Vertex stream %d is already set.", _stream); - m_draw.m_streamMask |= bit; - - Stream& stream = m_draw.m_stream[_stream]; - stream.m_startVertex = _startVertex; - stream.m_handle = _handle; - stream.m_decl.idx = invalidHandle; - m_draw.m_numVertices = bx::uint32_min(m_draw.m_numVertices, _numVertices); + if (m_draw.setStreamBit(_stream, _handle) ) + { + Stream& stream = m_draw.m_stream[_stream]; + stream.m_startVertex = _startVertex; + stream.m_handle = _handle; + stream.m_decl.idx = invalidHandle; + m_numVertices[_stream] = _numVertices; + } } void setVertexBuffer(uint8_t _stream, const DynamicVertexBuffer& _dvb, uint32_t _startVertex, uint32_t _numVertices) { - const uint8_t bit = 1<<_stream; -// BX_CHECK(0 == (m_draw.m_streamMask & bit), "Vertex stream %d is already set.", _stream); - m_draw.m_streamMask |= bit; - - Stream& stream = m_draw.m_stream[_stream]; - stream.m_startVertex = _dvb.m_startVertex + _startVertex; - stream.m_handle = _dvb.m_handle; - stream.m_decl = _dvb.m_decl; - m_draw.m_numVertices = - bx::uint32_min(m_draw.m_numVertices - , bx::uint32_min(bx::uint32_imax(0, _dvb.m_numVertices - _startVertex), _numVertices) - ); + if (m_draw.setStreamBit(_stream, _dvb.m_handle) ) + { + Stream& stream = m_draw.m_stream[_stream]; + stream.m_startVertex = _dvb.m_startVertex + _startVertex; + stream.m_handle = _dvb.m_handle; + stream.m_decl = _dvb.m_decl; + m_numVertices[_stream] = + bx::uint32_min(bx::uint32_imax(0, _dvb.m_numVertices - _startVertex), _numVertices) + ; + } } void setVertexBuffer(uint8_t _stream, const TransientVertexBuffer* _tvb, uint32_t _startVertex, uint32_t _numVertices) { - const uint8_t bit = 1<<_stream; -// BX_CHECK(0 == (m_draw.m_streamMask & bit), "Vertex stream %d is already set.", _stream); - m_draw.m_streamMask |= bit; - - Stream& stream = m_draw.m_stream[_stream]; - stream.m_startVertex = _tvb->startVertex + _startVertex; - stream.m_handle = _tvb->handle; - stream.m_decl = _tvb->decl; - m_draw.m_numVertices = - bx::uint32_min(m_draw.m_numVertices - , bx::uint32_min(bx::uint32_imax(0, _tvb->size/_tvb->stride - _startVertex), _numVertices) - ); + if (m_draw.setStreamBit(_stream, _tvb->handle) ) + { + Stream& stream = m_draw.m_stream[_stream]; + stream.m_startVertex = _tvb->startVertex + _startVertex; + stream.m_handle = _tvb->handle; + stream.m_decl = _tvb->decl; + m_numVertices[_stream] = + bx::uint32_min(bx::uint32_imax(0, _tvb->size/_tvb->stride - _startVertex), _numVertices) + ; + } } void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint32_t _num) @@ -1835,6 +1839,7 @@ namespace bgfx RenderItem m_renderItem[BGFX_CONFIG_MAX_DRAW_CALLS+1]; RenderDraw m_draw; RenderCompute m_compute; + uint32_t m_numVertices[BGFX_CONFIG_MAX_VERTEX_STREAMS]; uint32_t m_blitKeys[BGFX_CONFIG_MAX_BLIT_ITEMS+1]; BlitItem m_blitItem[BGFX_CONFIG_MAX_BLIT_ITEMS+1]; uint64_t m_stateFlags; diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 014a6d101..219bb4210 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -5828,12 +5828,14 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } if (programChanged + || currentState.m_streamMask != draw.m_streamMask || currentState.m_stream[0].m_decl.idx != draw.m_stream[0].m_decl.idx || currentState.m_stream[0].m_handle.idx != draw.m_stream[0].m_handle.idx || currentState.m_instanceDataBuffer.idx != draw.m_instanceDataBuffer.idx || currentState.m_instanceDataOffset != draw.m_instanceDataOffset || currentState.m_instanceDataStride != draw.m_instanceDataStride) { + currentState.m_streamMask = draw.m_streamMask; currentState.m_stream[0].m_decl = draw.m_stream[0].m_decl; currentState.m_stream[0].m_handle = draw.m_stream[0].m_handle; currentState.m_instanceDataBuffer.idx = draw.m_instanceDataBuffer.idx; @@ -5889,7 +5891,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } - if (isValid(currentState.m_stream[0].m_handle) ) + if (0 != currentState.m_streamMask) { uint32_t numVertices = draw.m_numVertices; if (UINT32_MAX == numVertices) diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index ebd8a5b9b..bf7a6a2aa 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -4021,11 +4021,13 @@ namespace bgfx { namespace d3d9 } if (programChanged + || currentState.m_streamMask != draw.m_streamMask || currentState.m_stream[0].m_handle.idx != draw.m_stream[0].m_handle.idx || currentState.m_instanceDataBuffer.idx != draw.m_instanceDataBuffer.idx || currentState.m_instanceDataOffset != draw.m_instanceDataOffset || currentState.m_instanceDataStride != draw.m_instanceDataStride) { + currentState.m_streamMask = draw.m_streamMask; currentState.m_stream[0].m_handle = draw.m_stream[0].m_handle; currentState.m_instanceDataBuffer.idx = draw.m_instanceDataBuffer.idx; currentState.m_instanceDataOffset = draw.m_instanceDataOffset; @@ -4082,7 +4084,7 @@ namespace bgfx { namespace d3d9 } } - if (isValid(currentState.m_stream[0].m_handle) ) + if (0 != currentState.m_streamMask) { uint32_t numVertices = draw.m_numVertices; if (UINT32_MAX == numVertices) diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index a5cc47261..d85b1bf63 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -6795,6 +6795,7 @@ namespace bgfx { namespace gl { if (programChanged || baseVertex != draw.m_stream[0].m_startVertex + || currentState.m_streamMask != draw.m_streamMask || currentState.m_stream[0].m_handle.idx != draw.m_stream[0].m_handle.idx || currentState.m_indexBuffer.idx != draw.m_indexBuffer.idx || currentState.m_instanceDataOffset != draw.m_instanceDataOffset @@ -6821,6 +6822,7 @@ namespace bgfx { namespace gl murmur.add(programIdx); uint32_t hash = murmur.end(); + currentState.m_streamMask = draw.m_streamMask; currentState.m_stream[0].m_handle = stream.m_handle; baseVertex = stream.m_startVertex; @@ -6883,6 +6885,7 @@ namespace bgfx { namespace gl && 0 != currentVao) { GL_CHECK(glBindVertexArray(defaultVao) ); + currentState.m_streamMask = 0; currentState.m_stream[0].m_handle.idx = invalidHandle; currentState.m_indexBuffer.idx = invalidHandle; bindAttribs = true; @@ -6890,11 +6893,13 @@ namespace bgfx { namespace gl } if (programChanged + || currentState.m_streamMask != draw.m_streamMask || currentState.m_stream[0].m_handle.idx != draw.m_stream[0].m_handle.idx || currentState.m_instanceDataBuffer.idx != draw.m_instanceDataBuffer.idx || currentState.m_instanceDataOffset != draw.m_instanceDataOffset || currentState.m_instanceDataStride != draw.m_instanceDataStride) { + currentState.m_streamMask = draw.m_streamMask; currentState.m_stream[0].m_handle = draw.m_stream[0].m_handle; currentState.m_instanceDataBuffer.idx = draw.m_instanceDataBuffer.idx; currentState.m_instanceDataOffset = draw.m_instanceDataOffset; @@ -6929,7 +6934,7 @@ namespace bgfx { namespace gl } } - if (isValid(currentState.m_stream[0].m_handle) ) + if (0 != currentState.m_streamMask) { if (baseVertex != draw.m_stream[0].m_startVertex || bindAttribs) @@ -6948,7 +6953,7 @@ namespace bgfx { namespace gl } } - if (isValid(currentState.m_stream[0].m_handle) ) + if (0 != currentState.m_streamMask) { uint32_t numVertices = draw.m_numVertices; if (UINT32_MAX == numVertices) diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index e839c12c4..645468268 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -3382,12 +3382,14 @@ namespace bgfx { namespace mtl if (key.m_program != programIdx || (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE|BGFX_STATE_BLEND_INDEPENDENT|BGFX_STATE_MSAA|BGFX_STATE_BLEND_ALPHA_TO_COVERAGE) & changedFlags + || currentState.m_streamMask != draw.m_streamMask || currentState.m_stream[0].m_handle.idx != draw.m_stream[0].m_handle.idx || currentState.m_stream[0].m_decl.idx != draw.m_stream[0].m_decl.idx || currentState.m_instanceDataStride != draw.m_instanceDataStride || ( (blendFactor != draw.m_rgba) && !!(newFlags & BGFX_STATE_BLEND_INDEPENDENT) ) ) { programIdx = key.m_program; + currentState.m_streamMask = draw.m_streamMask; currentState.m_stream[0].m_decl = draw.m_stream[0].m_decl; currentState.m_instanceDataStride = draw.m_instanceDataStride; @@ -3500,11 +3502,13 @@ namespace bgfx { namespace mtl } } - if (currentState.m_stream[0].m_handle.idx != draw.m_stream[0].m_handle.idx + if (currentState.m_streamMask != draw.m_streamMask + || currentState.m_stream[0].m_handle.idx != draw.m_stream[0].m_handle.idx || currentState.m_stream[0].m_startVertex != draw.m_stream[0].m_startVertex || currentState.m_instanceDataBuffer.idx != draw.m_instanceDataBuffer.idx || currentState.m_instanceDataOffset != draw.m_instanceDataOffset) { + currentState.m_streamMask = draw.m_streamMask; currentState.m_stream[0].m_handle = draw.m_stream[0].m_handle; currentState.m_stream[0].m_startVertex = draw.m_stream[0].m_startVertex; currentState.m_instanceDataBuffer.idx = draw.m_instanceDataBuffer.idx; @@ -3529,7 +3533,7 @@ namespace bgfx { namespace mtl } } - if (isValid(currentState.m_stream[0].m_handle) ) + if (0 != currentState.m_streamMask) { uint32_t numVertices = draw.m_numVertices; if (UINT32_MAX == numVertices)