diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index 642a5cb06..86672554a 100644 --- a/include/bgfx/bgfx.h +++ b/include/bgfx/bgfx.h @@ -1247,6 +1247,16 @@ namespace bgfx , uint32_t _numVertices ); + /// Set number of vertices for auto generated vertices use in conjuction + /// with gl_VertexID. + /// + /// @param[in] _numVertices Number of vertices. + /// + /// @attention Availability depends on: `BGFX_CAPS_VERTEX_ID`. + /// @attention C99 equivalent is `bgfx_set_vertex_count`. + /// + void setVertexCount(uint32_t _numVertices); + /// Set instance data buffer for draw primitive. /// /// @param[in] _idb Transient instance data buffer. @@ -3550,6 +3560,9 @@ namespace bgfx , uint32_t _numVertices ); + /// + void setVertexCount(uint32_t _numVertices); + /// Set instance data buffer for draw primitive. /// /// @param[in] _idb Transient instance data buffer. diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index a1cce53cb..d0d223c4e 100644 --- a/include/bgfx/c99/bgfx.h +++ b/include/bgfx/c99/bgfx.h @@ -983,6 +983,9 @@ BGFX_C_API void bgfx_set_dynamic_vertex_buffer(uint8_t _stream, bgfx_dynamic_ver /**/ BGFX_C_API void bgfx_set_transient_vertex_buffer(uint8_t _stream, const bgfx_transient_vertex_buffer_t* _tvb, uint32_t _startVertex, uint32_t _numVertices); +/**/ +BGFX_C_API void bgfx_set_vertex_count(uint32_t _numVertices); + /**/ BGFX_C_API void bgfx_set_instance_data_buffer(const bgfx_instance_data_buffer_t* _idb, uint32_t _start, uint32_t _num); @@ -1085,6 +1088,9 @@ BGFX_C_API void bgfx_encoder_set_dynamic_vertex_buffer(struct bgfx_encoder_s* _e /**/ BGFX_C_API void bgfx_encoder_set_transient_vertex_buffer(struct bgfx_encoder_s* _encoder, uint8_t _stream, const bgfx_transient_vertex_buffer_t* _tvb, uint32_t _startVertex, uint32_t _numVertices); +/**/ +BGFX_C_API void bgfx_encoder_set_vertex_count(struct bgfx_encoder_s* _encoder, uint32_t _numVertices); + /**/ BGFX_C_API void bgfx_encoder_set_instance_data_buffer(struct bgfx_encoder_s* _encoder, const bgfx_instance_data_buffer_t* _idb, uint32_t _start, uint32_t _num); diff --git a/include/bgfx/c99/platform.h b/include/bgfx/c99/platform.h index 3311bc26e..53df7e503 100644 --- a/include/bgfx/c99/platform.h +++ b/include/bgfx/c99/platform.h @@ -182,6 +182,7 @@ typedef struct bgfx_interface_vtbl void (*encoder_set_vertex_buffer)(struct bgfx_encoder_s* _encoder, uint8_t _stream, bgfx_vertex_buffer_handle_t _handle, uint32_t _startVertex, uint32_t _numVertices); void (*encoder_set_dynamic_vertex_buffer)(struct bgfx_encoder_s* _encoder, uint8_t _stream, bgfx_dynamic_vertex_buffer_handle_t _handle, uint32_t _startVertex, uint32_t _numVertices); void (*encoder_set_transient_vertex_buffer)(struct bgfx_encoder_s* _encoder, uint8_t _stream, const bgfx_transient_vertex_buffer_t* _tvb, uint32_t _startVertex, uint32_t _numVertices); + void (*encoder_set_vertex_count)(struct bgfx_encoder_s* _encoder, uint32_t _numVertices); void (*encoder_set_instance_data_buffer)(struct bgfx_encoder_s* _encoder, const bgfx_instance_data_buffer_t* _idb, uint32_t _start, uint32_t _num); void (*encoder_set_instance_data_from_vertex_buffer)(struct bgfx_encoder_s* _encoder, bgfx_vertex_buffer_handle_t _handle, uint32_t _startVertex, uint32_t _num); void (*encoder_set_instance_data_from_dynamic_vertex_buffer)(struct bgfx_encoder_s* _encoder, bgfx_dynamic_vertex_buffer_handle_t _handle, uint32_t _startVertex, uint32_t _num); diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index bcc55f606..13333973b 100644 --- a/include/bgfx/defines.h +++ b/include/bgfx/defines.h @@ -6,7 +6,7 @@ #ifndef BGFX_DEFINES_H_HEADER_GUARD #define BGFX_DEFINES_H_HEADER_GUARD -#define BGFX_API_VERSION UINT32_C(68) +#define BGFX_API_VERSION UINT32_C(69) /// Color RGB/alpha/depth write. When it's not specified write will be disabled. #define BGFX_STATE_WRITE_R UINT64_C(0x0000000000000001) //!< Enable R write. @@ -456,6 +456,7 @@ #define BGFX_CAPS_TEXTURE_READ_BACK UINT64_C(0x0000000000400000) //!< Read-back texture is supported. #define BGFX_CAPS_VERTEX_ATTRIB_HALF UINT64_C(0x0000000000800000) //!< Vertex attribute half-float is supported. #define BGFX_CAPS_VERTEX_ATTRIB_UINT10 UINT64_C(0x0000000000800000) //!< Vertex attribute 10_10_10_2 is supported. +#define BGFX_CAPS_VERTEX_ID UINT64_C(0x0000000001000000) //!< Rendering with VertexID only is supported. /// #define BGFX_CAPS_FORMAT_TEXTURE_NONE UINT16_C(0x0000) //!< Texture format is not supported. diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 80336c13f..5a07d8098 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -932,17 +932,25 @@ namespace bgfx m_draw.m_uniformBegin = m_uniformBegin; m_draw.m_uniformEnd = m_uniformEnd; - 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) - ) + if (UINT8_MAX != m_draw.m_streamMask) { - streamMask >>= ntz; - idx += ntz; - numVertices = bx::min(numVertices, m_numVertices[idx]); + 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::min(numVertices, m_numVertices[idx]); + } + + m_draw.m_numVertices = numVertices; + } + else + { + m_draw.m_numVertices = m_numVertices[0]; } - m_draw.m_numVertices = numVertices; if (isValid(_occlusionQuery) ) { @@ -1167,6 +1175,7 @@ namespace bgfx CAPS_FLAGS(BGFX_CAPS_TEXTURE_READ_BACK), CAPS_FLAGS(BGFX_CAPS_VERTEX_ATTRIB_HALF), CAPS_FLAGS(BGFX_CAPS_VERTEX_ATTRIB_UINT10), + CAPS_FLAGS(BGFX_CAPS_VERTEX_ID), #undef CAPS_FLAGS }; @@ -3119,6 +3128,12 @@ error: setVertexBuffer(_stream, _tvb, 0, UINT32_MAX); } + void Encoder::setVertexCount(uint32_t _numVertices) + { + BGFX_CHECK_CAPS(BGFX_CAPS_VERTEX_ID, "Auto generated vertices are not supported!"); + BGFX_ENCODER(setVertexCount(_numVertices) ); + } + void Encoder::setInstanceDataBuffer(const InstanceDataBuffer* _idb) { setInstanceDataBuffer(_idb, 0, UINT32_MAX); @@ -4286,6 +4301,12 @@ error: setVertexBuffer(_stream, _tvb, 0, UINT32_MAX); } + void setVertexCount(uint32_t _numVertices) + { + BGFX_CHECK_API_THREAD(); + s_ctx->m_encoder0->setVertexCount(_numVertices); + } + void setInstanceDataBuffer(const InstanceDataBuffer* _idb) { BGFX_CHECK_API_THREAD(); @@ -5391,6 +5412,11 @@ BGFX_C_API void bgfx_set_transient_vertex_buffer(uint8_t _stream, const bgfx_tra bgfx::setVertexBuffer(_stream, (const bgfx::TransientVertexBuffer*)_tvb, _startVertex, _numVertices); } +BGFX_C_API void bgfx_set_vertex_count(uint32_t _numVertices) +{ + bgfx::setVertexCount(_numVertices); +} + BGFX_C_API void bgfx_set_instance_data_buffer(const bgfx_instance_data_buffer_t* _idb, uint32_t _start, uint32_t _num) { bgfx::setInstanceDataBuffer( (const bgfx::InstanceDataBuffer*)_idb, _start, _num); @@ -5589,6 +5615,11 @@ BGFX_C_API void bgfx_encoder_set_transient_vertex_buffer(bgfx_encoder_s* _encode BGFX_ENCODER(setVertexBuffer(_stream, (const bgfx::TransientVertexBuffer*)_tvb, _startVertex, _numVertices) ); } +BGFX_C_API void bgfx_encoder_set_vertex_count(bgfx_encoder_s* _encoder, uint32_t _numVertices) +{ + BGFX_ENCODER(setVertexCount(_numVertices) ); +} + BGFX_C_API void bgfx_encoder_set_instance_data_buffer(bgfx_encoder_s* _encoder, const bgfx_instance_data_buffer_t* _idb, uint32_t _start, uint32_t _num) { BGFX_ENCODER(setInstanceDataBuffer( (const bgfx::InstanceDataBuffer*)_idb, _start, _num) ); @@ -5855,6 +5886,7 @@ BGFX_C_API bgfx_interface_vtbl_t* bgfx_get_interface(uint32_t _version) BGFX_IMPORT_FUNC(encoder_set_vertex_buffer) \ BGFX_IMPORT_FUNC(encoder_set_dynamic_vertex_buffer) \ BGFX_IMPORT_FUNC(encoder_set_transient_vertex_buffer) \ + BGFX_IMPORT_FUNC(encoder_set_vertex_count) \ BGFX_IMPORT_FUNC(encoder_set_instance_data_buffer) \ BGFX_IMPORT_FUNC(encoder_set_instance_data_from_vertex_buffer) \ BGFX_IMPORT_FUNC(encoder_set_instance_data_from_dynamic_vertex_buffer) \ diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 1a5131a6b..30ca55529 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -2194,6 +2194,7 @@ namespace bgfx void setIndexBuffer(IndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices) { + BX_CHECK(UINT8_MAX != m_draw.m_streamMask, ""); m_draw.m_startIndex = _firstIndex; m_draw.m_numIndices = _numIndices; m_draw.m_indexBuffer = _handle; @@ -2201,6 +2202,7 @@ namespace bgfx void setIndexBuffer(const DynamicIndexBuffer& _dib, uint32_t _firstIndex, uint32_t _numIndices) { + BX_CHECK(UINT8_MAX != m_draw.m_streamMask, ""); 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::min(_numIndices, _dib.m_size/indexSize); @@ -2209,6 +2211,7 @@ namespace bgfx void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _firstIndex, uint32_t _numIndices) { + BX_CHECK(UINT8_MAX != m_draw.m_streamMask, ""); const uint32_t numIndices = bx::min(_numIndices, _tib->size/2); m_draw.m_indexBuffer = _tib->handle; m_draw.m_startIndex = _tib->startIndex + _firstIndex; @@ -2218,6 +2221,7 @@ namespace bgfx void setVertexBuffer(uint8_t _stream, VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _numVertices) { + BX_CHECK(UINT8_MAX != m_draw.m_streamMask, ""); BX_CHECK(_stream < BGFX_CONFIG_MAX_VERTEX_STREAMS, "Invalid stream %d (max %d).", _stream, BGFX_CONFIG_MAX_VERTEX_STREAMS); if (m_draw.setStreamBit(_stream, _handle) ) { @@ -2231,6 +2235,7 @@ namespace bgfx void setVertexBuffer(uint8_t _stream, const DynamicVertexBuffer& _dvb, uint32_t _startVertex, uint32_t _numVertices) { + BX_CHECK(UINT8_MAX != m_draw.m_streamMask, ""); BX_CHECK(_stream < BGFX_CONFIG_MAX_VERTEX_STREAMS, "Invalid stream %d (max %d).", _stream, BGFX_CONFIG_MAX_VERTEX_STREAMS); if (m_draw.setStreamBit(_stream, _dvb.m_handle) ) { @@ -2246,6 +2251,7 @@ namespace bgfx void setVertexBuffer(uint8_t _stream, const TransientVertexBuffer* _tvb, uint32_t _startVertex, uint32_t _numVertices) { + BX_CHECK(UINT8_MAX != m_draw.m_streamMask, ""); BX_CHECK(_stream < BGFX_CONFIG_MAX_VERTEX_STREAMS, "Invalid stream %d (max %d).", _stream, BGFX_CONFIG_MAX_VERTEX_STREAMS); if (m_draw.setStreamBit(_stream, _tvb->handle) ) { @@ -2259,6 +2265,17 @@ namespace bgfx } } + void setVertexCount(uint32_t _numVertices) + { + BX_CHECK(0 == m_draw.m_streamMask, "Vertex buffer already set."); + m_draw.m_streamMask = UINT8_MAX; + Stream& stream = m_draw.m_stream[0]; + stream.m_startVertex = 0; + stream.m_handle.idx = kInvalidHandle; + stream.m_decl.idx = kInvalidHandle; + m_numVertices[0] = _numVertices; + } + void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint32_t _start, uint32_t _num) { const uint32_t start = bx::min(_start, _idb->num); diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index ee514d1de..336a61572 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -1124,6 +1124,7 @@ namespace bgfx { namespace d3d11 | BGFX_CAPS_TEXTURE_3D | BGFX_CAPS_VERTEX_ATTRIB_HALF | BGFX_CAPS_VERTEX_ATTRIB_UINT10 + | BGFX_CAPS_VERTEX_ID | BGFX_CAPS_FRAGMENT_DEPTH | (getIntelExtensions(m_device) ? BGFX_CAPS_FRAGMENT_ORDERING @@ -6093,34 +6094,38 @@ namespace bgfx { namespace d3d11 uint32_t numVertices = draw.m_numVertices; uint8_t numStreams = 0; - for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) - ; 0 != streamMask - ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask), ++numStreams - ) + + if (UINT8_MAX != draw.m_streamMask) { - streamMask >>= ntz; - idx += ntz; + for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) + ; 0 != streamMask + ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask), ++numStreams + ) + { + streamMask >>= ntz; + idx += ntz; - currentState.m_stream[idx].m_decl = draw.m_stream[idx].m_decl; - currentState.m_stream[idx].m_handle = draw.m_stream[idx].m_handle; - currentState.m_stream[idx].m_startVertex = draw.m_stream[idx].m_startVertex; + currentState.m_stream[idx].m_decl = draw.m_stream[idx].m_decl; + currentState.m_stream[idx].m_handle = draw.m_stream[idx].m_handle; + currentState.m_stream[idx].m_startVertex = draw.m_stream[idx].m_startVertex; - const uint16_t handle = draw.m_stream[idx].m_handle.idx; - const VertexBufferD3D11& vb = m_vertexBuffers[handle]; - const uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[idx].m_decl.idx : vb.m_decl.idx; - const VertexDecl& vertexDecl = m_vertexDecls[decl]; - const uint32_t stride = vertexDecl.m_stride; + const uint16_t handle = draw.m_stream[idx].m_handle.idx; + const VertexBufferD3D11& vb = m_vertexBuffers[handle]; + const uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[idx].m_decl.idx : vb.m_decl.idx; + const VertexDecl& vertexDecl = m_vertexDecls[decl]; + const uint32_t stride = vertexDecl.m_stride; - buffers[numStreams] = vb.m_ptr; - strides[numStreams] = stride; - offsets[numStreams] = draw.m_stream[idx].m_startVertex * stride; - decls[numStreams] = &vertexDecl; + buffers[numStreams] = vb.m_ptr; + strides[numStreams] = stride; + offsets[numStreams] = draw.m_stream[idx].m_startVertex * stride; + decls[numStreams] = &vertexDecl; - numVertices = bx::uint32_min(UINT32_MAX == draw.m_numVertices - ? vb.m_size/stride - : draw.m_numVertices - , numVertices - ); + numVertices = bx::uint32_min(UINT32_MAX == draw.m_numVertices + ? vb.m_size/stride + : draw.m_numVertices + , numVertices + ); + } } currentState.m_numVertices = numVertices; @@ -6132,9 +6137,9 @@ namespace bgfx { namespace d3d11 if (isValid(draw.m_instanceDataBuffer) ) { const VertexBufferD3D11& inst = m_vertexBuffers[draw.m_instanceDataBuffer.idx]; - uint32_t instStride = draw.m_instanceDataStride; + const uint32_t instStride = draw.m_instanceDataStride; deviceCtx->IASetVertexBuffers(numStreams, 1, &inst.m_ptr, &instStride, &draw.m_instanceDataOffset); - setInputLayout(numStreams, decls, m_program[programIdx], draw.m_instanceDataStride/16); + setInputLayout(numStreams, decls, m_program[programIdx], uint16_t(instStride/16) ); } else { @@ -6145,6 +6150,14 @@ namespace bgfx { namespace d3d11 else { deviceCtx->IASetVertexBuffers(0, 1, s_zero.m_buffer, s_zero.m_zero, s_zero.m_zero); + + if (isValid(draw.m_instanceDataBuffer) ) + { + const VertexBufferD3D11& inst = m_vertexBuffers[draw.m_instanceDataBuffer.idx]; + const uint32_t instStride = draw.m_instanceDataStride; + deviceCtx->IASetVertexBuffers(0, 1, &inst.m_ptr, &instStride, &draw.m_instanceDataOffset); + setInputLayout(0, NULL, m_program[programIdx], uint16_t(instStride/16) ); + } } } diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index c8a3c5fc3..6d5839ae3 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -1045,6 +1045,7 @@ namespace bgfx { namespace d3d12 | BGFX_CAPS_DRAW_INDIRECT | BGFX_CAPS_VERTEX_ATTRIB_HALF | BGFX_CAPS_VERTEX_ATTRIB_UINT10 + | BGFX_CAPS_VERTEX_ID | BGFX_CAPS_FRAGMENT_DEPTH | BGFX_CAPS_BLEND_INDEPENDENT | BGFX_CAPS_COMPUTE @@ -2643,14 +2644,17 @@ namespace bgfx { namespace d3d12 _stencil &= packStencil(~BGFX_STENCIL_FUNC_REF_MASK, ~BGFX_STENCIL_FUNC_REF_MASK); VertexDecl decl; - bx::memCopy(&decl, _vertexDecls[0], sizeof(VertexDecl) ); - const uint16_t* attrMask = program.m_vsh->m_attrMask; - - for (uint32_t ii = 0; ii < Attrib::Count; ++ii) + if (0 < _numStreams) { - uint16_t mask = attrMask[ii]; - uint16_t attr = (decl.m_attributes[ii] & mask); - decl.m_attributes[ii] = attr == 0 ? UINT16_MAX : attr == UINT16_MAX ? 0 : attr; + bx::memCopy(&decl, _vertexDecls[0], sizeof(VertexDecl) ); + const uint16_t* attrMask = program.m_vsh->m_attrMask; + + for (uint32_t ii = 0; ii < Attrib::Count; ++ii) + { + uint16_t mask = attrMask[ii]; + uint16_t attr = (decl.m_attributes[ii] & mask); + decl.m_attributes[ii] = attr == 0 ? UINT16_MAX : attr == UINT16_MAX ? 0 : attr; + } } bx::HashMurmur2A murmur; @@ -2659,6 +2663,7 @@ namespace bgfx { namespace d3d12 murmur.add(_stencil); murmur.add(program.m_vsh->m_hash); murmur.add(program.m_vsh->m_attrMask, sizeof(program.m_vsh->m_attrMask) ); + if (NULL != program.m_fsh) { murmur.add(program.m_fsh->m_hash); @@ -2668,6 +2673,7 @@ namespace bgfx { namespace d3d12 { murmur.add(_vertexDecls[ii]->m_hash); } + murmur.add(decl.m_attributes, sizeof(decl.m_attributes) ); murmur.add(m_fbh.idx); murmur.add(_numInstanceData); @@ -2785,7 +2791,10 @@ namespace bgfx { namespace d3d12 D3D12_INPUT_ELEMENT_DESC vertexElements[Attrib::Count + 1 + BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT]; desc.InputLayout.NumElements = setInputLayout(vertexElements, _numStreams, _vertexDecls, program, _numInstanceData); - desc.InputLayout.pInputElementDescs = vertexElements; + desc.InputLayout.pInputElementDescs = 0 == desc.InputLayout.NumElements + ? NULL + : vertexElements + ; uint8_t primIndex = uint8_t( (_state&BGFX_STATE_PT_MASK) >> BGFX_STATE_PT_SHIFT); desc.PrimitiveTopologyType = s_primInfo[primIndex].m_topologyType; @@ -3763,38 +3772,42 @@ namespace bgfx { namespace d3d12 return *cmd; } - uint8_t fill(ID3D12GraphicsCommandList* _commandList, D3D12_VERTEX_BUFFER_VIEW* _vbv, const RenderDraw& _draw, uint32_t& numVertices) + uint8_t fill(ID3D12GraphicsCommandList* _commandList, D3D12_VERTEX_BUFFER_VIEW* _vbv, const RenderDraw& _draw, uint32_t& _outNumVertices) { - uint8_t numStreams = 0; - numVertices = _draw.m_numVertices; - for (uint32_t idx = 0, streamMask = _draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) - ; 0 != streamMask - ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask), ++numStreams - ) + uint8_t numStreams = 0; + _outNumVertices = _draw.m_numVertices; + + if (UINT8_MAX != _draw.m_streamMask) { - streamMask >>= ntz; - idx += ntz; + for (uint32_t idx = 0, streamMask = _draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) + ; 0 != streamMask + ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask), ++numStreams + ) + { + streamMask >>= ntz; + idx += ntz; - const Stream& stream = _draw.m_stream[idx]; + const Stream& stream = _draw.m_stream[idx]; - uint16_t handle = stream.m_handle.idx; - VertexBufferD3D12& vb = s_renderD3D12->m_vertexBuffers[handle]; - vb.setState(_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); + uint16_t handle = stream.m_handle.idx; + VertexBufferD3D12& vb = s_renderD3D12->m_vertexBuffers[handle]; + vb.setState(_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - uint16_t decl = !isValid(vb.m_decl) ? stream.m_decl.idx : vb.m_decl.idx; - const VertexDecl& vertexDecl = s_renderD3D12->m_vertexDecls[decl]; - uint32_t stride = vertexDecl.m_stride; + uint16_t decl = !isValid(vb.m_decl) ? stream.m_decl.idx : vb.m_decl.idx; + const VertexDecl& vertexDecl = s_renderD3D12->m_vertexDecls[decl]; + uint32_t stride = vertexDecl.m_stride; - D3D12_VERTEX_BUFFER_VIEW& vbv = _vbv[numStreams]; - vbv.BufferLocation = vb.m_gpuVA + stream.m_startVertex * stride; - vbv.StrideInBytes = vertexDecl.m_stride; - vbv.SizeInBytes = vb.m_size; + D3D12_VERTEX_BUFFER_VIEW& vbv = _vbv[numStreams]; + vbv.BufferLocation = vb.m_gpuVA + stream.m_startVertex * stride; + vbv.StrideInBytes = vertexDecl.m_stride; + vbv.SizeInBytes = vb.m_size; - numVertices = bx::uint32_min(UINT32_MAX == _draw.m_numVertices - ? vb.m_size/stride - : _draw.m_numVertices - , numVertices - ); + _outNumVertices = bx::uint32_min(UINT32_MAX == _draw.m_numVertices + ? vb.m_size/stride + : _draw.m_numVertices + , _outNumVertices + ); + } } return numStreams; @@ -6005,25 +6018,28 @@ namespace bgfx { namespace d3d12 const VertexDecl* decls[BGFX_CONFIG_MAX_VERTEX_STREAMS]; - uint8_t numStreams = 0; - for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) - ; 0 != streamMask - ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask), ++numStreams - ) + uint8_t numStreams = 0; + if (UINT8_MAX != draw.m_streamMask) { - streamMask >>= ntz; - idx += ntz; + for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) + ; 0 != streamMask + ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask), ++numStreams + ) + { + streamMask >>= ntz; + idx += ntz; - currentState.m_stream[idx].m_decl = draw.m_stream[idx].m_decl; - currentState.m_stream[idx].m_handle = draw.m_stream[idx].m_handle; - currentState.m_stream[idx].m_startVertex = draw.m_stream[idx].m_startVertex; + currentState.m_stream[idx].m_decl = draw.m_stream[idx].m_decl; + currentState.m_stream[idx].m_handle = draw.m_stream[idx].m_handle; + currentState.m_stream[idx].m_startVertex = draw.m_stream[idx].m_startVertex; - uint16_t handle = draw.m_stream[idx].m_handle.idx; - const VertexBufferD3D12& vb = m_vertexBuffers[handle]; - uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[idx].m_decl.idx : vb.m_decl.idx; - const VertexDecl& vertexDecl = m_vertexDecls[decl]; + uint16_t handle = draw.m_stream[idx].m_handle.idx; + const VertexBufferD3D12& vb = m_vertexBuffers[handle]; + uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[idx].m_decl.idx : vb.m_decl.idx; + const VertexDecl& vertexDecl = m_vertexDecls[decl]; - decls[numStreams] = &vertexDecl; + decls[numStreams] = &vertexDecl; + } } ID3D12PipelineState* pso =