From 1123ba2b0a5bebd92c87ea336655b9a8472b4b39 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 22 Aug 2018 22:48:42 -0700 Subject: [PATCH 01/18] exploring optimization in Backend for bffer bindings --- libraries/gpu-gl-common/src/gpu/gl/GLBackend.h | 1 + .../gpu-gl-common/src/gpu/gl/GLBackendInput.cpp | 17 ++++++++++++----- .../src/gpu/gl/GLBackendPipeline.cpp | 2 ++ libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h | 14 +++++++++++++- libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 1 + .../gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp | 4 ++++ libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 1 + .../gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp | 5 +++++ libraries/gpu/src/gpu/Batch.h | 4 ++-- 9 files changed, 41 insertions(+), 8 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index cadcec7a56..2fa2df5bfa 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -239,6 +239,7 @@ public: virtual GLuint getFramebufferID(const FramebufferPointer& framebuffer) = 0; virtual GLuint getTextureID(const TexturePointer& texture) final; virtual GLuint getBufferID(const Buffer& buffer) = 0; + virtual GLuint getBufferIDUnsafe(const Buffer& buffer) = 0; virtual GLuint getQueryID(const QueryPointer& query) = 0; virtual GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) = 0; diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp index 77e1f90f66..6ce25bc56c 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp @@ -11,6 +11,7 @@ #include "GLBackend.h" #include "GLShared.h" #include "GLInputFormat.h" +#include "GLBuffer.h" using namespace gpu; using namespace gpu::gl; @@ -39,14 +40,20 @@ void GLBackend::do_setInputBuffer(const Batch& batch, size_t paramOffset) { BufferPointer buffer = batch._buffers.get(batch._params[paramOffset + 2]._uint); uint32 channel = batch._params[paramOffset + 3]._uint; - if (channel < getNumInputBuffers()) { + // if (channel < getNumInputBuffers()) { bool isModified = false; if (_input._buffers[channel] != buffer) { _input._buffers[channel] = buffer; GLuint vbo = 0; if (buffer) { - vbo = getBufferID((*buffer)); + // vbo = getBufferID((*buffer)); + // vbo = getBufferIDUnsafe((*buffer)); + auto* object = Backend::getGPUObject((*buffer)); + + if (object) { + vbo = object->_buffer; + } } _input._bufferVBOs[channel] = vbo; @@ -66,7 +73,7 @@ void GLBackend::do_setInputBuffer(const Batch& batch, size_t paramOffset) { if (isModified) { _input._invalidBuffers.set(channel); } - } + // } } void GLBackend::initInput() { @@ -128,7 +135,7 @@ void GLBackend::do_setIndexBuffer(const Batch& batch, size_t paramOffset) { if (indexBuffer != _input._indexBuffer) { _input._indexBuffer = indexBuffer; if (indexBuffer) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferID(*indexBuffer)); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferIDUnsafe(*indexBuffer)); } else { // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -145,7 +152,7 @@ void GLBackend::do_setIndirectBuffer(const Batch& batch, size_t paramOffset) { if (buffer != _input._indirectBuffer) { _input._indirectBuffer = buffer; if (buffer) { - glBindBuffer(GL_DRAW_INDIRECT_BUFFER, getBufferID(*buffer)); + glBindBuffer(GL_DRAW_INDIRECT_BUFFER, getBufferIDUnsafe(*buffer)); } else { // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp index d3d2bc0938..fd67202863 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp @@ -172,6 +172,8 @@ void GLBackend::bindUniformBuffer(uint32_t slot, const BufferPointer& buffer, GL // Sync BufferObject auto* object = syncGPUObject(*bufferState.buffer); + // auto glBO = getBufferIDUnsafe(*buffer); + if (object) { glBindBufferRange(GL_UNIFORM_BUFFER, slot, object->_buffer, bufferState.offset, bufferState.size); diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h index 182014e764..8efbe03b90 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h @@ -49,13 +49,25 @@ public: } } + template + static GLuint getIdUnsafe(GLBackend& backend, const Buffer& buffer) { + GLBufferType* object = Backend::getGPUObject(buffer); + + if (object) { + return object->_buffer; + } + else { + return 0; + } + } + const GLuint& _buffer { _id }; const GLuint _size; const Stamp _stamp; ~GLBuffer(); - virtual void transfer() = 0; + virtual void transfer() {}; protected: GLBuffer(const std::weak_ptr& backend, const Buffer& buffer, GLuint id); diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index c6fbc43ae5..a09b3e9297 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -134,6 +134,7 @@ protected: GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; GLuint getBufferID(const Buffer& buffer) override; + GLuint getBufferIDUnsafe(const Buffer& buffer) override; GLuint getResourceBufferID(const Buffer& buffer); GLBuffer* syncGPUObject(const Buffer& buffer) override; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp index 62ade673b4..97ac2739eb 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp @@ -83,6 +83,10 @@ GLuint GL41Backend::getBufferID(const Buffer& buffer) { return GL41Buffer::getId(*this, buffer); } +GLuint GL41Backend::getBufferIDUnsafe(const Buffer& buffer) { + return GL41Backend::getBufferID(buffer); +} + GLuint GL41Backend::getResourceBufferID(const Buffer& buffer) { auto* object = GL41Buffer::sync(*this, buffer); if (object) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index 658bea2a3e..5da4506773 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -235,6 +235,7 @@ protected: GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; GLuint getBufferID(const Buffer& buffer) override; + GLuint getBufferIDUnsafe(const Buffer& buffer) override; GLBuffer* syncGPUObject(const Buffer& buffer) override; GLTexture* syncGPUObject(const TexturePointer& texture) override; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp index 2afbea3876..0d26f8f412 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp @@ -51,6 +51,11 @@ GLuint GL45Backend::getBufferID(const Buffer& buffer) { return GL45Buffer::getId(*this, buffer); } +GLuint GL45Backend::getBufferIDUnsafe(const Buffer& buffer) { + //return GL45Buffer::getId(*this, buffer); + return GL45Buffer::getIdUnsafe(*this, buffer); +} + GLBuffer* GL45Backend::syncGPUObject(const Buffer& buffer) { return GL45Buffer::sync(*this, buffer); } diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index bcbfe0616d..2bead507b8 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -417,10 +417,10 @@ public: } const Data& get(uint32 offset) const { - if (offset >= _items.size()) { + /* if (offset >= _items.size()) { static const Data EMPTY; return EMPTY; - } + }*/ return (_items.data() + offset)->_data; } From e8d922a56cb82adf7d9e0b17c2fe80dcfa4c952d Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 3 Sep 2018 02:48:07 -0700 Subject: [PATCH 02/18] Interleaving the attributes and relying on just 3 input buffers --- libraries/fbx/src/FBXReader_Mesh.cpp | 105 ++++++++++++++++-- .../gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 11 +- libraries/gpu/src/gpu/Stream.h | 2 + libraries/graphics/src/graphics/Geometry.cpp | 7 ++ libraries/graphics/src/graphics/Geometry.h | 3 + 5 files changed, 116 insertions(+), 12 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 801edddb06..13a2c697a0 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -585,13 +585,15 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { FBXMesh& fbxMesh = extractedMesh; graphics::MeshPointer mesh(new graphics::Mesh()); + bool blendShapes = !fbxMesh.blendshapes.empty(); + int numVerts = extractedMesh.vertices.size(); // Grab the vertices in a buffer auto vb = std::make_shared(); vb->setData(extractedMesh.vertices.size() * sizeof(glm::vec3), (const gpu::Byte*) extractedMesh.vertices.data()); gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - mesh->setVertexBuffer(vbv); + // mesh->setVertexBuffer(vbv); if (!fbxMesh.normals.empty() && fbxMesh.tangents.empty()) { // Fill with a dummy value to force tangents to be present if there are normals @@ -634,7 +636,10 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { // Normals and tangents are interleaved const int normalsOffset = 0; const int tangentsOffset = normalsOffset + sizeof(NormalType); - const int colorsOffset = normalsOffset + normalsSize + tangentsSize; + const int totalNTSize = normalsOffset + normalsSize + tangentsSize; + //const int colorsOffset = normalsOffset + normalsSize + tangentsSize; + + const int colorsOffset = 0; const int texCoordsOffset = colorsOffset + colorsSize; const int texCoords1Offset = texCoordsOffset + texCoordsSize; const int clusterIndicesOffset = texCoords1Offset + texCoords1Size; @@ -642,6 +647,10 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { const int totalAttributeSize = clusterWeightsOffset + clusterWeightsSize; // Copy all attribute data in a single attribute buffer + + auto attribNTBuffer = std::make_shared(); + attribNTBuffer->resize(totalNTSize); + auto attribBuffer = std::make_shared(); attribBuffer->resize(totalAttributeSize); @@ -665,9 +674,10 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { normalsAndTangents.push_back(packedNormal); normalsAndTangents.push_back(packedTangent); } - attribBuffer->setSubData(normalsOffset, normalsAndTangentsSize, (const gpu::Byte*) normalsAndTangents.data()); + attribNTBuffer->setSubData(normalsOffset, normalsAndTangentsSize, (const gpu::Byte*) normalsAndTangents.data()); } + if (colorsSize > 0) { #if FBX_PACK_COLORS std::vector colors; @@ -723,50 +733,123 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { } attribBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (const gpu::Byte*) fbxMesh.clusterWeights.constData()); + auto vf = std::make_shared(); + auto vbs = std::make_shared(); + + gpu::Offset buf0Offset = 12; + vf->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); + vbs->addBuffer(vb, 0, buf0Offset); + + gpu::Offset buf1Offset = 0; if (normalsSize) { - mesh->addAttribute(gpu::Stream::NORMAL, + /* mesh->addAttribute(gpu::Stream::NORMAL, graphics::BufferView(attribBuffer, normalsOffset, normalsAndTangentsSize, normalsAndTangentsStride, FBX_NORMAL_ELEMENT)); mesh->addAttribute(gpu::Stream::TANGENT, graphics::BufferView(attribBuffer, tangentsOffset, normalsAndTangentsSize, normalsAndTangentsStride, FBX_NORMAL_ELEMENT)); +*/ + vf->setAttribute(gpu::Stream::NORMAL, 1, FBX_NORMAL_ELEMENT, 0); + vf->setAttribute(gpu::Stream::TANGENT, 1, FBX_NORMAL_ELEMENT, 4); + buf1Offset = 8; + vbs->addBuffer(attribNTBuffer, 0, buf1Offset); } + + gpu::Offset buf2Offset = 0; if (colorsSize) { - mesh->addAttribute(gpu::Stream::COLOR, + /* mesh->addAttribute(gpu::Stream::COLOR, graphics::BufferView(attribBuffer, colorsOffset, colorsSize, FBX_COLOR_ELEMENT)); +*/ + vf->setAttribute(gpu::Stream::COLOR, 2, FBX_COLOR_ELEMENT, buf2Offset); + buf2Offset += 4; } if (texCoordsSize) { - mesh->addAttribute(gpu::Stream::TEXCOORD, + /* mesh->addAttribute(gpu::Stream::TEXCOORD, graphics::BufferView( attribBuffer, texCoordsOffset, texCoordsSize, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); + */ vf->setAttribute(gpu::Stream::TEXCOORD, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset); + buf2Offset += 4; } if (texCoords1Size) { - mesh->addAttribute( gpu::Stream::TEXCOORD1, + /* mesh->addAttribute( gpu::Stream::TEXCOORD1, graphics::BufferView(attribBuffer, texCoords1Offset, texCoords1Size, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); + */ vf->setAttribute(gpu::Stream::TEXCOORD1, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset); + buf2Offset += 4; } else if (texCoordsSize) { - mesh->addAttribute(gpu::Stream::TEXCOORD1, + /* mesh->addAttribute(gpu::Stream::TEXCOORD1, graphics::BufferView(attribBuffer, texCoordsOffset, texCoordsSize, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); + */ vf->setAttribute(gpu::Stream::TEXCOORD1, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset - 4); } if (clusterIndicesSize) { if (fbxMesh.clusters.size() < UINT8_MAX) { - mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, + /* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW))); +*/ + vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW), buf2Offset); + buf2Offset += 4; + } else { - mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, + /* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW))); + */ vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW), buf2Offset); + buf2Offset += 8; } } if (clusterWeightsSize) { - mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, + /* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, graphics::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize, gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW))); + */ vf->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, 2, gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW), buf2Offset); + buf2Offset += 8; } + { + auto vColorOffset = 0; + auto vColorSize = colorsSize / numVerts; + + auto vTexcoord0Offset = vColorOffset + vColorSize; + auto vTexcoord0Size = texCoordsSize / numVerts; + + auto vTexcoord1Offset = vTexcoord0Offset + vTexcoord0Size; + auto vTexcoord1Size = texCoords1Size / numVerts; + + auto vClusterIndiceOffset = vTexcoord1Offset + vTexcoord1Size; + auto vClusterIndiceSize = clusterIndicesSize / numVerts; + + auto vClusterWeightOffset = vClusterIndiceOffset + vClusterIndiceSize; + auto vClusterWeightSize = clusterWeightsSize / numVerts; + + auto vStride = vClusterWeightOffset + vClusterWeightSize; + //int vStride = buf2Offset; + std::vector dest; + dest.resize(totalAttributeSize); + auto vDest = dest.data(); + + auto source = attribBuffer->getData(); + + + for (int i = 0; i < numVerts; i++) { + + if (vColorSize) memcpy(vDest + vColorOffset, source + colorsOffset + i * vColorSize, vColorSize); + if (vTexcoord0Size) memcpy(vDest + vTexcoord0Offset, source + texCoordsOffset + i * vTexcoord0Size, vTexcoord0Size); + if (vTexcoord1Size) memcpy(vDest + vTexcoord1Offset, source + texCoords1Offset + i * vTexcoord1Size, vTexcoord1Size); + if (vClusterIndiceSize) memcpy(vDest + vClusterIndiceOffset, source + clusterIndicesOffset + i * vClusterIndiceSize, vClusterIndiceSize); + if (vClusterWeightSize) memcpy(vDest + vClusterWeightOffset, source + clusterWeightsOffset + i * vClusterWeightSize, vClusterWeightSize); + + vDest += vStride; + } + + attribBuffer->setData(totalAttributeSize, dest.data()); + + vbs->addBuffer(attribBuffer, 0, vStride); + } + + mesh->setVertexFormatAndStream(vf, vbs); unsigned int totalIndices = 0; foreach(const FBXMeshPart& part, extractedMesh.parts) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index cc3e609bda..c914b9f84d 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -27,6 +27,8 @@ void GL45Backend::resetInputStage() { } void GL45Backend::updateInput() { + // PROFILE_RANGE(render_gpu, __FUNCTION__); + bool isStereoNow = isStereo(); // track stereo state change potentially happening wihtout changing the input format // this is a rare case requesting to invalid the format @@ -36,6 +38,7 @@ void GL45Backend::updateInput() { _input._lastUpdateStereoState = isStereoNow; if (_input._invalidFormat) { + PROFILE_RANGE(render_gpu, "bindInputFormat"); InputStageState::ActivationCache newActivation; // Assign the vertex format required @@ -128,16 +131,22 @@ void GL45Backend::updateInput() { } if (_input._invalidBuffers.any()) { + // PROFILE_RANGE(render_gpu, "bindInputBuffers"); auto vbo = _input._bufferVBOs.data(); auto offset = _input._bufferOffsets.data(); auto stride = _input._bufferStrides.data(); - for (GLuint buffer = 0; buffer < _input._buffers.size(); buffer++, vbo++, offset++, stride++) { + int numSet = 0; + auto numBuffers = _input._buffers.size(); + for (GLuint buffer = 0; buffer < numBuffers; buffer++, vbo++, offset++, stride++) { if (_input._invalidBuffers.test(buffer)) { glBindVertexBuffer(buffer, (*vbo), (*offset), (GLsizei)(*stride)); + numSet++; } } + PROFILE_COUNTER_IF_CHANGED(render_gpu, "numVBSbound", int, numSet); + _input._invalidBuffers.reset(); (void)CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index 0def1ab201..2e1ed1d83c 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -152,6 +152,8 @@ public: BufferStream makeRangedStream(uint32 offset, uint32 count = -1) const; + BufferStream& operator = (const BufferStream& src) = default; + protected: Buffers _buffers; Offsets _offsets; diff --git a/libraries/graphics/src/graphics/Geometry.cpp b/libraries/graphics/src/graphics/Geometry.cpp index d43c773249..3f5f484b08 100755 --- a/libraries/graphics/src/graphics/Geometry.cpp +++ b/libraries/graphics/src/graphics/Geometry.cpp @@ -32,6 +32,13 @@ Mesh::Mesh(const Mesh& mesh) : Mesh::~Mesh() { } +void Mesh::setVertexFormatAndStream(const gpu::Stream::FormatPointer& vf, const gpu::BufferStreamPointer& vbs) { + _vertexFormat = vf; + _vertexStream = (*vbs); + + _vertexBuffer = BufferView(vbs->getBuffers()[0], vbs->getOffsets()[0], vbs->getBuffers()[0]->getSize(), vbs->getStrides()[0], gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); +} + void Mesh::setVertexBuffer(const BufferView& buffer) { _vertexBuffer = buffer; evalVertexFormat(); diff --git a/libraries/graphics/src/graphics/Geometry.h b/libraries/graphics/src/graphics/Geometry.h index eddfdbd1b6..20018ba71b 100755 --- a/libraries/graphics/src/graphics/Geometry.h +++ b/libraries/graphics/src/graphics/Geometry.h @@ -59,6 +59,9 @@ public: void removeAttribute(Slot slot); const BufferView getAttributeBuffer(int attrib) const; + // Force vertex stream and Vertex format + void setVertexFormatAndStream(const gpu::Stream::FormatPointer& vf, const gpu::BufferStreamPointer& vbs); + // Stream format const gpu::Stream::FormatPointer getVertexFormat() const { return _vertexFormat; } From 761e8a3f957c2cff43bccd1c8f3e97b6120c5a08 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Tue, 4 Sep 2018 09:19:24 -0700 Subject: [PATCH 03/18] fixing warnings --- libraries/fbx/src/FBXReader_Mesh.cpp | 6 +++--- libraries/graphics/src/graphics/Geometry.cpp | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 13a2c697a0..e6d9321fb5 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -585,7 +585,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { FBXMesh& fbxMesh = extractedMesh; graphics::MeshPointer mesh(new graphics::Mesh()); - bool blendShapes = !fbxMesh.blendshapes.empty(); + // bool blendShapes = !fbxMesh.blendshapes.empty(); int numVerts = extractedMesh.vertices.size(); // Grab the vertices in a buffer @@ -619,7 +619,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { qWarning() << "Unexpected tangents in " << url; } const auto normalsAndTangentsSize = normalsSize + tangentsSize; - const int normalsAndTangentsStride = 2 * sizeof(NormalType); + // const int normalsAndTangentsStride = 2 * sizeof(NormalType); const int colorsSize = fbxMesh.colors.size() * sizeof(ColorType); // Texture coordinates are stored in 2 half floats const int texCoordsSize = fbxMesh.texCoords.size() * sizeof(vec2h); @@ -635,7 +635,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { // Normals and tangents are interleaved const int normalsOffset = 0; - const int tangentsOffset = normalsOffset + sizeof(NormalType); + // const int tangentsOffset = normalsOffset + sizeof(NormalType); const int totalNTSize = normalsOffset + normalsSize + tangentsSize; //const int colorsOffset = normalsOffset + normalsSize + tangentsSize; diff --git a/libraries/graphics/src/graphics/Geometry.cpp b/libraries/graphics/src/graphics/Geometry.cpp index 3f5f484b08..2fbe3708fd 100755 --- a/libraries/graphics/src/graphics/Geometry.cpp +++ b/libraries/graphics/src/graphics/Geometry.cpp @@ -36,7 +36,9 @@ void Mesh::setVertexFormatAndStream(const gpu::Stream::FormatPointer& vf, const _vertexFormat = vf; _vertexStream = (*vbs); - _vertexBuffer = BufferView(vbs->getBuffers()[0], vbs->getOffsets()[0], vbs->getBuffers()[0]->getSize(), vbs->getStrides()[0], gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); + auto attrib = _vertexFormat->getAttribute(gpu::Stream::POSITION); + _vertexBuffer = BufferView(vbs->getBuffers()[attrib._channel], vbs->getOffsets()[attrib._channel], vbs->getBuffers()[attrib._channel]->getSize(), + (gpu::uint16) vbs->getStrides()[attrib._channel], attrib._element); } void Mesh::setVertexBuffer(const BufferView& buffer) { From adcabf52c5f2945ce368a39b194190a86f698902 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Tue, 4 Sep 2018 17:33:18 -0700 Subject: [PATCH 04/18] Refactoring the FBXReader_MEsh.cpp for better interleaving --- libraries/fbx/src/FBXReader_Mesh.cpp | 226 +++++++++++++-------------- 1 file changed, 110 insertions(+), 116 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index e6d9321fb5..4ecca2b234 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -585,16 +585,9 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { FBXMesh& fbxMesh = extractedMesh; graphics::MeshPointer mesh(new graphics::Mesh()); - // bool blendShapes = !fbxMesh.blendshapes.empty(); + bool hasBlendShapes = !fbxMesh.blendshapes.empty(); int numVerts = extractedMesh.vertices.size(); - // Grab the vertices in a buffer - auto vb = std::make_shared(); - vb->setData(extractedMesh.vertices.size() * sizeof(glm::vec3), - (const gpu::Byte*) extractedMesh.vertices.data()); - gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - // mesh->setVertexBuffer(vbv); - if (!fbxMesh.normals.empty() && fbxMesh.tangents.empty()) { // Fill with a dummy value to force tangents to be present if there are normals fbxMesh.tangents.reserve(fbxMesh.normals.size()); @@ -609,50 +602,61 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { } } - // evaluate all attribute channels sizes - const int normalsSize = fbxMesh.normals.size() * sizeof(NormalType); - const int tangentsSize = fbxMesh.tangents.size() * sizeof(NormalType); + // evaluate all attribute elements and data sizes + + // Position is a vec3 + const auto positionElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ); + const int positionsSize = numVerts * positionElement.getSize(); + + // Normal and tangent are always there together packed in normalized xyz32bits word (times 2) + const auto normalElement = FBX_NORMAL_ELEMENT; + const int normalsSize = fbxMesh.normals.size() * normalElement.getSize(); + const int tangentsSize = fbxMesh.tangents.size() * normalElement.getSize(); // If there are normals then there should be tangents - assert(normalsSize <= tangentsSize); if (tangentsSize > normalsSize) { qWarning() << "Unexpected tangents in " << url; } const auto normalsAndTangentsSize = normalsSize + tangentsSize; - // const int normalsAndTangentsStride = 2 * sizeof(NormalType); - const int colorsSize = fbxMesh.colors.size() * sizeof(ColorType); + const int normalsAndTangentsStride = 2 * normalElement.getSize(); + + // Color attrib + const auto colorElement = FBX_COLOR_ELEMENT; + const int colorsSize = fbxMesh.colors.size() * colorElement.getSize(); + // Texture coordinates are stored in 2 half floats - const int texCoordsSize = fbxMesh.texCoords.size() * sizeof(vec2h); - const int texCoords1Size = fbxMesh.texCoords1.size() * sizeof(vec2h); + const auto texCoordsElement = gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV); + const int texCoordsSize = fbxMesh.texCoords.size() * texCoordsElement.getSize(); + const int texCoords1Size = fbxMesh.texCoords1.size() * texCoordsElement.getSize(); - int clusterIndicesSize = fbxMesh.clusterIndices.size() * sizeof(uint8_t); - if (fbxMesh.clusters.size() > UINT8_MAX) { - // we need 16 bits instead of just 8 for clusterIndices - clusterIndicesSize *= 2; - } + // Support for 4 skinning clusters: + // 4 Indices are uint8 ideally, uint16 if more than 256. + const auto clusterIndiceElement = (fbxMesh.clusters.size() < UINT8_MAX ? gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW) : gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW)); + // 4 Weights are normalized 16bits + const auto clusterWeightElement = gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW); - const int clusterWeightsSize = fbxMesh.clusterWeights.size() * sizeof(uint16_t); + // Cluster indices and weights must be the same sizes + const int NUM_CLUSTERS_PER_VERT = 4; + const int numVertClusters = (fbxMesh.clusterIndices.size() == fbxMesh.clusterWeights.size() ? fbxMesh.clusterIndices.size() / NUM_CLUSTERS_PER_VERT : 0); + const int clusterIndicesSize = numVertClusters * clusterIndiceElement.getSize(); + const int clusterWeightsSize = numVertClusters * clusterWeightElement.getSize(); - // Normals and tangents are interleaved - const int normalsOffset = 0; - // const int tangentsOffset = normalsOffset + sizeof(NormalType); - const int totalNTSize = normalsOffset + normalsSize + tangentsSize; - //const int colorsOffset = normalsOffset + normalsSize + tangentsSize; - - const int colorsOffset = 0; + // Decide on where to put what seequencially in a big buffer: + const int positionsOffset = 0; + const int normalsAndTangentsOffset = positionsOffset + positionsSize; + const int colorsOffset = normalsAndTangentsOffset + normalsAndTangentsSize; const int texCoordsOffset = colorsOffset + colorsSize; const int texCoords1Offset = texCoordsOffset + texCoordsSize; const int clusterIndicesOffset = texCoords1Offset + texCoords1Size; const int clusterWeightsOffset = clusterIndicesOffset + clusterIndicesSize; - const int totalAttributeSize = clusterWeightsOffset + clusterWeightsSize; + const int totalVertsSize = clusterWeightsOffset + clusterWeightsSize; - // Copy all attribute data in a single attribute buffer + // Copy all vertex data in a single buffer + auto vertBuffer = std::make_shared(); + vertBuffer->resize(totalVertsSize); - auto attribNTBuffer = std::make_shared(); - attribNTBuffer->resize(totalNTSize); - - auto attribBuffer = std::make_shared(); - attribBuffer->resize(totalAttributeSize); + // First positions + vertBuffer->setSubData(positionsOffset, positionsSize, (const gpu::Byte*) extractedMesh.vertices.data()); // Interleave normals and tangents if (normalsSize > 0) { @@ -660,8 +664,8 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { normalsAndTangents.reserve(fbxMesh.normals.size() + fbxMesh.tangents.size()); for (auto normalIt = fbxMesh.normals.constBegin(), tangentIt = fbxMesh.tangents.constBegin(); - normalIt != fbxMesh.normals.constEnd(); - ++normalIt, ++tangentIt) { + normalIt != fbxMesh.normals.constEnd(); + ++normalIt, ++tangentIt) { #if FBX_PACK_NORMALS const auto normal = normalizeDirForPacking(*normalIt); const auto tangent = normalizeDirForPacking(*tangentIt); @@ -674,10 +678,10 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { normalsAndTangents.push_back(packedNormal); normalsAndTangents.push_back(packedTangent); } - attribNTBuffer->setSubData(normalsOffset, normalsAndTangentsSize, (const gpu::Byte*) normalsAndTangents.data()); + vertBuffer->setSubData(normalsAndTangentsOffset, normalsAndTangentsSize, (const gpu::Byte*) normalsAndTangents.data()); } - + // Pack colors if (colorsSize > 0) { #if FBX_PACK_COLORS std::vector colors; @@ -686,12 +690,13 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { for (const auto& color : fbxMesh.colors) { colors.push_back(glm::packUnorm4x8(glm::vec4(color, 1.0f))); } - attribBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) colors.data()); + vertBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) colors.data()); #else - attribBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) fbxMesh.colors.constData()); + vertBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) fbxMesh.colors.constData()); #endif } + // Pack Texcoords 0 and 1 (if exists) if (texCoordsSize > 0) { QVector texCoordData; texCoordData.reserve(fbxMesh.texCoords.size()); @@ -702,9 +707,8 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { texCoordVec2h.y = glm::detail::toFloat16(texCoordVec2f.y); texCoordData.push_back(texCoordVec2h); } - attribBuffer->setSubData(texCoordsOffset, texCoordsSize, (const gpu::Byte*) texCoordData.constData()); + vertBuffer->setSubData(texCoordsOffset, texCoordsSize, (const gpu::Byte*) texCoordData.constData()); } - if (texCoords1Size > 0) { QVector texCoordData; texCoordData.reserve(fbxMesh.texCoords1.size()); @@ -715,100 +719,91 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { texCoordVec2h.y = glm::detail::toFloat16(texCoordVec2f.y); texCoordData.push_back(texCoordVec2h); } - attribBuffer->setSubData(texCoords1Offset, texCoords1Size, (const gpu::Byte*) texCoordData.constData()); + vertBuffer->setSubData(texCoords1Offset, texCoords1Size, (const gpu::Byte*) texCoordData.constData()); } - if (fbxMesh.clusters.size() < UINT8_MAX) { - // yay! we can fit the clusterIndices within 8-bits - int32_t numIndices = fbxMesh.clusterIndices.size(); - QVector clusterIndices; - clusterIndices.resize(numIndices); - for (int32_t i = 0; i < numIndices; ++i) { - assert(fbxMesh.clusterIndices[i] <= UINT8_MAX); - clusterIndices[i] = (uint8_t)(fbxMesh.clusterIndices[i]); + // Clusters data + if (clusterIndicesSize > 0) { + if (fbxMesh.clusters.size() < UINT8_MAX) { + // yay! we can fit the clusterIndices within 8-bits + int32_t numIndices = fbxMesh.clusterIndices.size(); + QVector clusterIndices; + clusterIndices.resize(numIndices); + for (int32_t i = 0; i < numIndices; ++i) { + assert(fbxMesh.clusterIndices[i] <= UINT8_MAX); + clusterIndices[i] = (uint8_t)(fbxMesh.clusterIndices[i]); + } + vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) clusterIndices.constData()); + } + else { + vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) fbxMesh.clusterIndices.constData()); } - attribBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) clusterIndices.constData()); - } else { - attribBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) fbxMesh.clusterIndices.constData()); } - attribBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (const gpu::Byte*) fbxMesh.clusterWeights.constData()); + if (clusterWeightsSize > 0) { + vertBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (const gpu::Byte*) fbxMesh.clusterWeights.constData()); + } + + // Now we decide on how to interleave the attributes and provide the vertices among bufers: + // Aka the Vertex format auto vf = std::make_shared(); - auto vbs = std::make_shared(); - - gpu::Offset buf0Offset = 12; - vf->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - vbs->addBuffer(vb, 0, buf0Offset); + gpu::Offset buf0Offset = 0; + vf->setAttribute(gpu::Stream::POSITION, 0, positionElement); + buf0Offset += positionElement.getSize(); gpu::Offset buf1Offset = 0; if (normalsSize) { - /* mesh->addAttribute(gpu::Stream::NORMAL, - graphics::BufferView(attribBuffer, normalsOffset, normalsAndTangentsSize, - normalsAndTangentsStride, FBX_NORMAL_ELEMENT)); - mesh->addAttribute(gpu::Stream::TANGENT, - graphics::BufferView(attribBuffer, tangentsOffset, normalsAndTangentsSize, - normalsAndTangentsStride, FBX_NORMAL_ELEMENT)); -*/ - vf->setAttribute(gpu::Stream::NORMAL, 1, FBX_NORMAL_ELEMENT, 0); - vf->setAttribute(gpu::Stream::TANGENT, 1, FBX_NORMAL_ELEMENT, 4); - buf1Offset = 8; - vbs->addBuffer(attribNTBuffer, 0, buf1Offset); + vf->setAttribute(gpu::Stream::NORMAL, 1, normalElement, buf1Offset); + buf1Offset = normalElement.getSize(); + vf->setAttribute(gpu::Stream::TANGENT, 1, normalElement, buf1Offset); + buf1Offset = normalElement.getSize(); } - gpu::Offset buf2Offset = 0; + gpu::Offset buf2Offset = (0); if (colorsSize) { - /* mesh->addAttribute(gpu::Stream::COLOR, - graphics::BufferView(attribBuffer, colorsOffset, colorsSize, FBX_COLOR_ELEMENT)); -*/ - vf->setAttribute(gpu::Stream::COLOR, 2, FBX_COLOR_ELEMENT, buf2Offset); - buf2Offset += 4; + vf->setAttribute(gpu::Stream::COLOR, 2, colorElement, buf2Offset); + buf2Offset += colorElement.getSize(); } if (texCoordsSize) { - /* mesh->addAttribute(gpu::Stream::TEXCOORD, - graphics::BufferView( attribBuffer, texCoordsOffset, texCoordsSize, - gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); - */ vf->setAttribute(gpu::Stream::TEXCOORD, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset); - buf2Offset += 4; + vf->setAttribute(gpu::Stream::TEXCOORD, 2, texCoordsElement, buf2Offset); + buf2Offset += texCoordsElement.getSize(); } if (texCoords1Size) { - /* mesh->addAttribute( gpu::Stream::TEXCOORD1, - graphics::BufferView(attribBuffer, texCoords1Offset, texCoords1Size, - gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); - */ vf->setAttribute(gpu::Stream::TEXCOORD1, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset); - buf2Offset += 4; - } else if (texCoordsSize) { - /* mesh->addAttribute(gpu::Stream::TEXCOORD1, - graphics::BufferView(attribBuffer, texCoordsOffset, texCoordsSize, - gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); - */ vf->setAttribute(gpu::Stream::TEXCOORD1, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset - 4); + vf->setAttribute(gpu::Stream::TEXCOORD1, 2, texCoordsElement, buf2Offset); + buf2Offset += texCoordsElement.getSize(); + } + else if (texCoordsSize) { + vf->setAttribute(gpu::Stream::TEXCOORD1, 2, texCoordsElement, buf2Offset - texCoordsElement.getSize()); } - if (clusterIndicesSize) { - if (fbxMesh.clusters.size() < UINT8_MAX) { - /* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, - graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, - gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW))); -*/ - vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW), buf2Offset); - buf2Offset += 4; - - } else { - /* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, - graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, - gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW))); - */ vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW), buf2Offset); - buf2Offset += 8; - } + vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, clusterIndiceElement, buf2Offset); + buf2Offset += clusterIndiceElement.getSize(); } if (clusterWeightsSize) { - /* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, - graphics::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize, - gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW))); - */ vf->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, 2, gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW), buf2Offset); - buf2Offset += 8; + vf->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, 2, clusterWeightElement, buf2Offset); + buf2Offset += clusterWeightElement.getSize(); } + auto vbs = std::make_shared(); + + + auto vb = std::make_shared(); + vb->setData(extractedMesh.vertices.size() * sizeof(glm::vec3), + (const gpu::Byte*) extractedMesh.vertices.data()); + gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); + vbs->addBuffer(vb, 0, buf0Offset); + + auto attribNTBuffer = std::make_shared(); + attribNTBuffer->resize(totalNTSize); + + auto attribBuffer = std::make_shared(); + attribBuffer->resize(totalAttributeSize); + + + { + vbs->addBuffer(attribNTBuffer, 0, buf1Offset); + auto vColorOffset = 0; auto vColorSize = colorsSize / numVerts; @@ -848,7 +843,6 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { vbs->addBuffer(attribBuffer, 0, vStride); } - mesh->setVertexFormatAndStream(vf, vbs); unsigned int totalIndices = 0; From 8344cb9affebbf01e4da273817d00c64869a4b83 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Wed, 5 Sep 2018 11:07:04 -0700 Subject: [PATCH 05/18] REfactor the FBXReader_Mesh for different vertex formats --- libraries/fbx/src/FBXReader_Mesh.cpp | 154 ++++++++++++++++++--------- 1 file changed, 104 insertions(+), 50 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 4ecca2b234..ce80dfb592 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -745,66 +745,116 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { // Now we decide on how to interleave the attributes and provide the vertices among bufers: - // Aka the Vertex format - auto vf = std::make_shared(); - gpu::Offset buf0Offset = 0; - vf->setAttribute(gpu::Stream::POSITION, 0, positionElement); - buf0Offset += positionElement.getSize(); + // Aka the Vertex format and the vertexBufferStream + auto vertexFormat = std::make_shared(); + auto vertexBufferStream = std::make_shared(); - gpu::Offset buf1Offset = 0; - if (normalsSize) { - vf->setAttribute(gpu::Stream::NORMAL, 1, normalElement, buf1Offset); - buf1Offset = normalElement.getSize(); - vf->setAttribute(gpu::Stream::TANGENT, 1, normalElement, buf1Offset); - buf1Offset = normalElement.getSize(); + // Decision time: + // if blendshapes then keep position and normals/tangents as separated channel buffers from interleaved attributes + // else everything is interleaved in one buffer + + // Default case is no blend shapes + gpu::BufferPointer attribBuffer; + int totalAttribBufferSize = totalVertsSize; + gpu::uint8 posChannel = 0; + gpu::uint8 tangentChannel = posChannel; + gpu::uint8 attribChannel = posChannel; + bool interleavePositions = true; + bool interleaveNormalsTangents = true; + + // If has blend shapes allocate and assign buffers for pos and tangents now + if (hasBlendShapes) { + + auto posBuffer = std::make_shared(); + posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); + vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); + + auto tangentBuffer = std::make_shared(); + tangentBuffer->setData(normalsAndTangentsSize, (const gpu::Byte*) vertBuffer->getData() + normalsAndTangentsOffset); + vertexBufferStream->addBuffer(tangentBuffer, 0, normalsAndTangentsStride); + + // update channels and attribBuffer size accordingly + interleavePositions = false; + interleaveNormalsTangents = false; + + tangentChannel = 1; + attribChannel = 2; + + totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize; + } else { +/* + auto posBuffer = std::make_shared(); + posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); + vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); + + // update channels and attribBuffer size accordingly + interleavePositions = false; + + auto tangentBuffer = std::make_shared(); + tangentBuffer->setData(normalsAndTangentsSize, (const gpu::Byte*) vertBuffer->getData() + normalsAndTangentsOffset); + vertexBufferStream->addBuffer(tangentBuffer, 0, normalsAndTangentsStride); + + interleaveNormalsTangents = false; + + tangentChannel = 1; + attribChannel = 2; + + totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize;*/ } - gpu::Offset buf2Offset = (0); + // Define the vertex format, compute the offset for each attributes as we append them to the vertex format + gpu::Offset bufOffset = 0; + if (positionsSize) { + vertexFormat->setAttribute(gpu::Stream::POSITION, posChannel, positionElement, bufOffset); + bufOffset += positionElement.getSize(); + if (!interleavePositions) { + bufOffset = 0; + } + } + if (normalsSize) { + vertexFormat->setAttribute(gpu::Stream::NORMAL, tangentChannel, normalElement, bufOffset); + bufOffset = normalElement.getSize(); + vertexFormat->setAttribute(gpu::Stream::TANGENT, tangentChannel, normalElement, bufOffset); + bufOffset = normalElement.getSize(); + if (!interleaveNormalsTangents) { + bufOffset = 0; + } + } + + // Pack normal and Tangent with the rest of atributes if no blend shapes if (colorsSize) { - vf->setAttribute(gpu::Stream::COLOR, 2, colorElement, buf2Offset); - buf2Offset += colorElement.getSize(); + vertexFormat->setAttribute(gpu::Stream::COLOR, attribChannel, colorElement, bufOffset); + bufOffset += colorElement.getSize(); } if (texCoordsSize) { - vf->setAttribute(gpu::Stream::TEXCOORD, 2, texCoordsElement, buf2Offset); - buf2Offset += texCoordsElement.getSize(); + vertexFormat->setAttribute(gpu::Stream::TEXCOORD, attribChannel, texCoordsElement, bufOffset); + bufOffset += texCoordsElement.getSize(); } if (texCoords1Size) { - vf->setAttribute(gpu::Stream::TEXCOORD1, 2, texCoordsElement, buf2Offset); - buf2Offset += texCoordsElement.getSize(); + vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, attribChannel, texCoordsElement, bufOffset); + bufOffset += texCoordsElement.getSize(); } else if (texCoordsSize) { - vf->setAttribute(gpu::Stream::TEXCOORD1, 2, texCoordsElement, buf2Offset - texCoordsElement.getSize()); + vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, attribChannel, texCoordsElement, bufOffset - texCoordsElement.getSize()); } if (clusterIndicesSize) { - vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, clusterIndiceElement, buf2Offset); - buf2Offset += clusterIndiceElement.getSize(); + vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, attribChannel, clusterIndiceElement, bufOffset); + bufOffset += clusterIndiceElement.getSize(); } if (clusterWeightsSize) { - vf->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, 2, clusterWeightElement, buf2Offset); - buf2Offset += clusterWeightElement.getSize(); + vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, attribChannel, clusterWeightElement, bufOffset); + bufOffset += clusterWeightElement.getSize(); } - auto vbs = std::make_shared(); - - - auto vb = std::make_shared(); - vb->setData(extractedMesh.vertices.size() * sizeof(glm::vec3), - (const gpu::Byte*) extractedMesh.vertices.data()); - gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - vbs->addBuffer(vb, 0, buf0Offset); - - auto attribNTBuffer = std::make_shared(); - attribNTBuffer->resize(totalNTSize); - - auto attribBuffer = std::make_shared(); - attribBuffer->resize(totalAttributeSize); - - - + // Finally, allocate and fill the attribBuffer interleaving the attributes as needed: { - vbs->addBuffer(attribNTBuffer, 0, buf1Offset); + auto vPositionOffset = 0; + auto vPositionSize = (interleavePositions ? positionsSize / numVerts : 0); - auto vColorOffset = 0; + auto vNormalsAndTangentsOffset = vPositionOffset + vPositionSize; + auto vNormalsAndTangentsSize = (interleaveNormalsTangents ? normalsAndTangentsSize / numVerts : 0); + + auto vColorOffset = vNormalsAndTangentsOffset + vNormalsAndTangentsSize; auto vColorSize = colorsSize / numVerts; auto vTexcoord0Offset = vColorOffset + vColorSize; @@ -820,16 +870,17 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { auto vClusterWeightSize = clusterWeightsSize / numVerts; auto vStride = vClusterWeightOffset + vClusterWeightSize; - //int vStride = buf2Offset; + std::vector dest; - dest.resize(totalAttributeSize); + dest.resize(totalAttribBufferSize); auto vDest = dest.data(); - auto source = attribBuffer->getData(); - + auto source = vertBuffer->getData(); for (int i = 0; i < numVerts; i++) { + if (vPositionSize) memcpy(vDest + vPositionOffset, source + positionsOffset + i * vPositionSize, vPositionSize); + if (vNormalsAndTangentsSize) memcpy(vDest + vNormalsAndTangentsOffset, source + normalsAndTangentsOffset + i * vNormalsAndTangentsSize, vNormalsAndTangentsSize); if (vColorSize) memcpy(vDest + vColorOffset, source + colorsOffset + i * vColorSize, vColorSize); if (vTexcoord0Size) memcpy(vDest + vTexcoord0Offset, source + texCoordsOffset + i * vTexcoord0Size, vTexcoord0Size); if (vTexcoord1Size) memcpy(vDest + vTexcoord1Offset, source + texCoords1Offset + i * vTexcoord1Size, vTexcoord1Size); @@ -839,12 +890,15 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { vDest += vStride; } - attribBuffer->setData(totalAttributeSize, dest.data()); - - vbs->addBuffer(attribBuffer, 0, vStride); + auto attribBuffer = std::make_shared(); + attribBuffer->setData(totalAttribBufferSize, dest.data()); + vertexBufferStream->addBuffer(attribBuffer, 0, vStride); } - mesh->setVertexFormatAndStream(vf, vbs); + // MEsh vertex format and vertex stream is ready + mesh->setVertexFormatAndStream(vertexFormat, vertexBufferStream); + + // Index and Part Buffers unsigned int totalIndices = 0; foreach(const FBXMeshPart& part, extractedMesh.parts) { totalIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size()); From ce86e94e6f7b8c41fe5623d69b68eb1b66ed73ed Mon Sep 17 00:00:00 2001 From: sam gateau Date: Wed, 5 Sep 2018 11:34:33 -0700 Subject: [PATCH 06/18] Add simple optim and instrumentation for tthe number of input buffer changes per frame" --- libraries/fbx/src/FBXReader_Mesh.cpp | 25 +++---------------- .../src/gpu/gl/GLBackendInput.cpp | 9 +++++++ .../gpu-gl/src/gpu/gl41/GL41BackendInput.cpp | 5 +++- .../gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 15 ++++++----- 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index ce80dfb592..ef2fcc23b4 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -781,25 +781,6 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { attribChannel = 2; totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize; - } else { -/* - auto posBuffer = std::make_shared(); - posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); - vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); - - // update channels and attribBuffer size accordingly - interleavePositions = false; - - auto tangentBuffer = std::make_shared(); - tangentBuffer->setData(normalsAndTangentsSize, (const gpu::Byte*) vertBuffer->getData() + normalsAndTangentsOffset); - vertexBufferStream->addBuffer(tangentBuffer, 0, normalsAndTangentsStride); - - interleaveNormalsTangents = false; - - tangentChannel = 1; - attribChannel = 2; - - totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize;*/ } // Define the vertex format, compute the offset for each attributes as we append them to the vertex format @@ -813,9 +794,9 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { } if (normalsSize) { vertexFormat->setAttribute(gpu::Stream::NORMAL, tangentChannel, normalElement, bufOffset); - bufOffset = normalElement.getSize(); + bufOffset += normalElement.getSize(); vertexFormat->setAttribute(gpu::Stream::TANGENT, tangentChannel, normalElement, bufOffset); - bufOffset = normalElement.getSize(); + bufOffset += normalElement.getSize(); if (!interleaveNormalsTangents) { bufOffset = 0; } @@ -895,7 +876,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { vertexBufferStream->addBuffer(attribBuffer, 0, vStride); } - // MEsh vertex format and vertex stream is ready + // Mesh vertex format and vertex stream is ready mesh->setVertexFormatAndStream(vertexFormat, vertexBufferStream); // Index and Part Buffers diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp index 6ce25bc56c..21553dc2c7 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp @@ -268,9 +268,18 @@ void GLBackend::updateInput() { auto offset = _input._bufferOffsets.data(); auto stride = _input._bufferStrides.data(); + // Profile the count of buffers to update and use it to short cut the for loop + int numInvalids = _input._invalidBuffers.count(); + _stats._ISNumInputBufferChanges += numInvalids; + PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); + for (GLuint buffer = 0; buffer < _input._buffers.size(); buffer++, vbo++, offset++, stride++) { if (_input._invalidBuffers.test(buffer)) { glBindVertexBuffer(buffer, (*vbo), (*offset), (GLsizei)(*stride)); + numInvalids--; + if (numInvalids <= 0) { + break; + } } } diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp index 9dcb08f0b7..30e393630a 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp @@ -78,7 +78,10 @@ void GL41Backend::updateInput() { const Stream::Format::AttributeMap& attributes = _input._format->getAttributes(); auto& inputChannels = _input._format->getChannels(); - _stats._ISNumInputBufferChanges++; + _stats._ISNumInputBufferChanges += _input._invalidBuffers.count(); + + // Profile the count of buffers to update + PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, _input._invalidBuffers.count()); GLuint boundVBO = 0; for (auto& channelIt : inputChannels) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index c914b9f84d..de4989eb32 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -27,8 +27,6 @@ void GL45Backend::resetInputStage() { } void GL45Backend::updateInput() { - // PROFILE_RANGE(render_gpu, __FUNCTION__); - bool isStereoNow = isStereo(); // track stereo state change potentially happening wihtout changing the input format // this is a rare case requesting to invalid the format @@ -131,21 +129,26 @@ void GL45Backend::updateInput() { } if (_input._invalidBuffers.any()) { - // PROFILE_RANGE(render_gpu, "bindInputBuffers"); auto vbo = _input._bufferVBOs.data(); auto offset = _input._bufferOffsets.data(); auto stride = _input._bufferStrides.data(); - int numSet = 0; + // Profile the count of buffers to update and use it to short cut the for loop + int numInvalids = _input._invalidBuffers.count(); + _stats._ISNumInputBufferChanges += numInvalids; + PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); + auto numBuffers = _input._buffers.size(); for (GLuint buffer = 0; buffer < numBuffers; buffer++, vbo++, offset++, stride++) { if (_input._invalidBuffers.test(buffer)) { glBindVertexBuffer(buffer, (*vbo), (*offset), (GLsizei)(*stride)); - numSet++; + numInvalids--; + if (numInvalids <= 0) { + break; + } } } - PROFILE_COUNTER_IF_CHANGED(render_gpu, "numVBSbound", int, numSet); _input._invalidBuffers.reset(); (void)CHECK_GL_ERROR(); From 1feaf286b43e27f5d077946232a449fa56c96f37 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Wed, 5 Sep 2018 14:35:50 -0700 Subject: [PATCH 07/18] keeping position separated from the other attributes --- libraries/fbx/src/FBXReader_Mesh.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index ef2fcc23b4..bb95fb42f7 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -763,8 +763,8 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { bool interleaveNormalsTangents = true; // If has blend shapes allocate and assign buffers for pos and tangents now + hasBlendShapes = true; if (hasBlendShapes) { - auto posBuffer = std::make_shared(); posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); @@ -781,6 +781,19 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { attribChannel = 2; totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize; + } else { + auto posBuffer = std::make_shared(); + posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); + vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); + + // update channels and attribBuffer size accordingly + interleavePositions = false; + interleaveNormalsTangents = true; + + tangentChannel = 1; + attribChannel = 1; + + totalAttribBufferSize = totalVertsSize - positionsSize; } // Define the vertex format, compute the offset for each attributes as we append them to the vertex format From 21f65d8a78d8dbba1608797a9d758bc1f93556f5 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Wed, 5 Sep 2018 17:50:06 -0700 Subject: [PATCH 08/18] position are used correctly for evaluting bounds in the Mesh --- libraries/fbx/src/FBXReader_Mesh.cpp | 4 ++-- libraries/graphics/src/graphics/Geometry.cpp | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index bb95fb42f7..7b83e74ebc 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -781,7 +781,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { attribChannel = 2; totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize; - } else { + } /*else { auto posBuffer = std::make_shared(); posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); @@ -794,7 +794,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { attribChannel = 1; totalAttribBufferSize = totalVertsSize - positionsSize; - } + }*/ // Define the vertex format, compute the offset for each attributes as we append them to the vertex format gpu::Offset bufOffset = 0; diff --git a/libraries/graphics/src/graphics/Geometry.cpp b/libraries/graphics/src/graphics/Geometry.cpp index 2fbe3708fd..f71dcbe27d 100755 --- a/libraries/graphics/src/graphics/Geometry.cpp +++ b/libraries/graphics/src/graphics/Geometry.cpp @@ -120,7 +120,8 @@ Box Mesh::evalPartBound(int partNum) const { for (;index != endIndex; index++) { // skip primitive restart indices if ((*index) != PRIMITIVE_RESTART_INDEX) { - box += vertices[(*index)]; + // box += vertices[(*index)]; + box += _vertexBuffer.get(part._baseVertex + (*index)); } } } @@ -137,11 +138,12 @@ Box Mesh::evalPartsBound(int partStart, int partEnd) const { Box partBound; auto index = _indexBuffer.cbegin() + (*part)._startIndex; auto endIndex = index + (*part)._numIndices; - auto vertices = &_vertexBuffer.get((*part)._baseVertex); + //auto vertices = &_vertexBuffer.get((*part)._baseVertex); for (;index != endIndex; index++) { // skip primitive restart indices if ((*index) != (uint) PRIMITIVE_RESTART_INDEX) { - partBound += vertices[(*index)]; + //partBound += vertices[(*index)]; + partBound += _vertexBuffer.get((*part)._baseVertex + (*index)); } } From 5aa45b64d2b7aede39a48d3997d017742c49d21d Mon Sep 17 00:00:00 2001 From: sam gateau Date: Thu, 6 Sep 2018 11:24:13 -0700 Subject: [PATCH 09/18] Adressing build warnings --- libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp | 2 +- libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp | 5 +++-- libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp index 21553dc2c7..9fe1aa4029 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp @@ -269,7 +269,7 @@ void GLBackend::updateInput() { auto stride = _input._bufferStrides.data(); // Profile the count of buffers to update and use it to short cut the for loop - int numInvalids = _input._invalidBuffers.count(); + int numInvalids = (int) _input._invalidBuffers.count(); _stats._ISNumInputBufferChanges += numInvalids; PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp index 30e393630a..cedb18c87a 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp @@ -78,10 +78,11 @@ void GL41Backend::updateInput() { const Stream::Format::AttributeMap& attributes = _input._format->getAttributes(); auto& inputChannels = _input._format->getChannels(); - _stats._ISNumInputBufferChanges += _input._invalidBuffers.count(); + int numInvalids = (int)_input._invalidBuffers.count(); + _stats._ISNumInputBufferChanges += numInvalids; // Profile the count of buffers to update - PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, _input._invalidBuffers.count()); + PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); GLuint boundVBO = 0; for (auto& channelIt : inputChannels) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index de4989eb32..4a8bdc43f3 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -134,7 +134,7 @@ void GL45Backend::updateInput() { auto stride = _input._bufferStrides.data(); // Profile the count of buffers to update and use it to short cut the for loop - int numInvalids = _input._invalidBuffers.count(); + int numInvalids = (int) _input._invalidBuffers.count(); _stats._ISNumInputBufferChanges += numInvalids; PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); From e428248472c13a67e7ea73785437379d68477327 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Thu, 6 Sep 2018 11:33:26 -0700 Subject: [PATCH 10/18] Adressing build warnings --- libraries/graphics/src/graphics/Geometry.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/graphics/src/graphics/Geometry.cpp b/libraries/graphics/src/graphics/Geometry.cpp index f71dcbe27d..5a374ae8d0 100755 --- a/libraries/graphics/src/graphics/Geometry.cpp +++ b/libraries/graphics/src/graphics/Geometry.cpp @@ -116,7 +116,6 @@ Box Mesh::evalPartBound(int partNum) const { index += part._startIndex; auto endIndex = index; endIndex += part._numIndices; - auto vertices = &_vertexBuffer.get(part._baseVertex); for (;index != endIndex; index++) { // skip primitive restart indices if ((*index) != PRIMITIVE_RESTART_INDEX) { @@ -138,7 +137,6 @@ Box Mesh::evalPartsBound(int partStart, int partEnd) const { Box partBound; auto index = _indexBuffer.cbegin() + (*part)._startIndex; auto endIndex = index + (*part)._numIndices; - //auto vertices = &_vertexBuffer.get((*part)._baseVertex); for (;index != endIndex; index++) { // skip primitive restart indices if ((*index) != (uint) PRIMITIVE_RESTART_INDEX) { From 38bfee7b723704a3a92d988b389b923b87c173ef Mon Sep 17 00:00:00 2001 From: sam gateau Date: Thu, 6 Sep 2018 13:54:21 -0700 Subject: [PATCH 11/18] Fix compilation on android and add the simple getBufferIDUnsynced in bindUniformBuffer --- .../gpu-gl-common/src/gpu/gl/GLBackend.h | 2 +- .../src/gpu/gl/GLBackendInput.cpp | 22 +++++-------------- .../src/gpu/gl/GLBackendPipeline.cpp | 13 +++++------ libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h | 6 ++--- libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 2 +- .../gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp | 4 ++-- libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 2 +- .../gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp | 5 ++--- libraries/gpu-gles/src/gpu/gles/GLESBackend.h | 1 + .../src/gpu/gles/GLESBackendBuffer.cpp | 4 ++++ 10 files changed, 25 insertions(+), 36 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index 2fa2df5bfa..9b3a28e6fd 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -239,7 +239,7 @@ public: virtual GLuint getFramebufferID(const FramebufferPointer& framebuffer) = 0; virtual GLuint getTextureID(const TexturePointer& texture) final; virtual GLuint getBufferID(const Buffer& buffer) = 0; - virtual GLuint getBufferIDUnsafe(const Buffer& buffer) = 0; + virtual GLuint getBufferIDUnsynced(const Buffer& buffer) = 0; virtual GLuint getQueryID(const QueryPointer& query) = 0; virtual GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) = 0; diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp index 9fe1aa4029..f326ef39b9 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp @@ -40,23 +40,11 @@ void GLBackend::do_setInputBuffer(const Batch& batch, size_t paramOffset) { BufferPointer buffer = batch._buffers.get(batch._params[paramOffset + 2]._uint); uint32 channel = batch._params[paramOffset + 3]._uint; - // if (channel < getNumInputBuffers()) { + if (channel < getNumInputBuffers()) { bool isModified = false; if (_input._buffers[channel] != buffer) { _input._buffers[channel] = buffer; - - GLuint vbo = 0; - if (buffer) { - // vbo = getBufferID((*buffer)); - // vbo = getBufferIDUnsafe((*buffer)); - auto* object = Backend::getGPUObject((*buffer)); - - if (object) { - vbo = object->_buffer; - } - } - _input._bufferVBOs[channel] = vbo; - + _input._bufferVBOs[channel] = getBufferIDUnsynced((*buffer)); isModified = true; } @@ -73,7 +61,7 @@ void GLBackend::do_setInputBuffer(const Batch& batch, size_t paramOffset) { if (isModified) { _input._invalidBuffers.set(channel); } - // } + } } void GLBackend::initInput() { @@ -135,7 +123,7 @@ void GLBackend::do_setIndexBuffer(const Batch& batch, size_t paramOffset) { if (indexBuffer != _input._indexBuffer) { _input._indexBuffer = indexBuffer; if (indexBuffer) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferIDUnsafe(*indexBuffer)); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferIDUnsynced(*indexBuffer)); } else { // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -152,7 +140,7 @@ void GLBackend::do_setIndirectBuffer(const Batch& batch, size_t paramOffset) { if (buffer != _input._indirectBuffer) { _input._indirectBuffer = buffer; if (buffer) { - glBindBuffer(GL_DRAW_INDIRECT_BUFFER, getBufferIDUnsafe(*buffer)); + glBindBuffer(GL_DRAW_INDIRECT_BUFFER, getBufferIDUnsynced(*buffer)); } else { // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp index fd67202863..05ded3eece 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp @@ -85,6 +85,8 @@ void GLBackend::do_setPipeline(const Batch& batch, size_t paramOffset) { auto& cameraCorrectionBuffer = _transform._viewCorrectionEnabled ? _pipeline._cameraCorrectionBuffer._buffer : _pipeline._cameraCorrectionBufferIdentity._buffer; + // Because we don't sync Buffers in the bindUniformBuffer, let s force this buffer synced + getBufferID(*cameraCorrectionBuffer); bindUniformBuffer(gpu::slot::buffer::CameraCorrection, cameraCorrectionBuffer, 0, sizeof(CameraCorrection)); } (void)CHECK_GL_ERROR(); @@ -170,13 +172,10 @@ void GLBackend::bindUniformBuffer(uint32_t slot, const BufferPointer& buffer, GL return; } - // Sync BufferObject - auto* object = syncGPUObject(*bufferState.buffer); - // auto glBO = getBufferIDUnsafe(*buffer); - - if (object) { - glBindBufferRange(GL_UNIFORM_BUFFER, slot, object->_buffer, bufferState.offset, bufferState.size); - + // Grab the true gl Buffer object + auto glBO = getBufferIDUnsynced(*buffer); + if (glBO) { + glBindBufferRange(GL_UNIFORM_BUFFER, slot, glBO, bufferState.offset, bufferState.size); _uniform._buffers[slot] = bufferState; (void)CHECK_GL_ERROR(); } else { diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h index 8efbe03b90..b9fe125c8d 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h @@ -50,13 +50,11 @@ public: } template - static GLuint getIdUnsafe(GLBackend& backend, const Buffer& buffer) { + static GLuint getIdUnsynced(GLBackend& backend, const Buffer& buffer) { GLBufferType* object = Backend::getGPUObject(buffer); - if (object) { return object->_buffer; - } - else { + } else { return 0; } } diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index a09b3e9297..f4078f5479 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -134,7 +134,7 @@ protected: GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; GLuint getBufferID(const Buffer& buffer) override; - GLuint getBufferIDUnsafe(const Buffer& buffer) override; + GLuint getBufferIDUnsynced(const Buffer& buffer) override; GLuint getResourceBufferID(const Buffer& buffer); GLBuffer* syncGPUObject(const Buffer& buffer) override; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp index 97ac2739eb..ac5d5ee0c9 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp @@ -83,8 +83,8 @@ GLuint GL41Backend::getBufferID(const Buffer& buffer) { return GL41Buffer::getId(*this, buffer); } -GLuint GL41Backend::getBufferIDUnsafe(const Buffer& buffer) { - return GL41Backend::getBufferID(buffer); +GLuint GL41Backend::getBufferIDUnsynced(const Buffer& buffer) { + return GL41Buffer::getIdUnsynced(*this, buffer); } GLuint GL41Backend::getResourceBufferID(const Buffer& buffer) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index 5da4506773..a100faf432 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -235,7 +235,7 @@ protected: GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; GLuint getBufferID(const Buffer& buffer) override; - GLuint getBufferIDUnsafe(const Buffer& buffer) override; + GLuint getBufferIDUnsynced(const Buffer& buffer) override; GLBuffer* syncGPUObject(const Buffer& buffer) override; GLTexture* syncGPUObject(const TexturePointer& texture) override; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp index 0d26f8f412..6d17923ebd 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp @@ -51,9 +51,8 @@ GLuint GL45Backend::getBufferID(const Buffer& buffer) { return GL45Buffer::getId(*this, buffer); } -GLuint GL45Backend::getBufferIDUnsafe(const Buffer& buffer) { - //return GL45Buffer::getId(*this, buffer); - return GL45Buffer::getIdUnsafe(*this, buffer); +GLuint GL45Backend::getBufferIDUnsynced(const Buffer& buffer) { + return GL45Buffer::getIdUnsynced(*this, buffer); } GLBuffer* GL45Backend::syncGPUObject(const Buffer& buffer) { diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackend.h b/libraries/gpu-gles/src/gpu/gles/GLESBackend.h index 785f4c3ef9..c757de0a72 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackend.h +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackend.h @@ -130,6 +130,7 @@ protected: GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; GLuint getBufferID(const Buffer& buffer) override; + GLuint getBufferIDUnsynced(const Buffer& buffer) override; GLuint getResourceBufferID(const Buffer& buffer); GLBuffer* syncGPUObject(const Buffer& buffer) override; diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendBuffer.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendBuffer.cpp index 17fdad8377..7dd08df409 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendBuffer.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendBuffer.cpp @@ -64,6 +64,10 @@ GLuint GLESBackend::getBufferID(const Buffer& buffer) { return GLESBuffer::getId(*this, buffer); } +GLuint GLESBackend::getBufferIDUnsynced(const Buffer& buffer) { + return GLESBuffer::getIdUnsynced(*this, buffer); +} + GLBuffer* GLESBackend::syncGPUObject(const Buffer& buffer) { return GLESBuffer::sync(*this, buffer); } From 6544e9f0b004cb9c6b43da5405e2f2f1c98fbd46 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Thu, 6 Sep 2018 13:58:03 -0700 Subject: [PATCH 12/18] Removing the commented debug code --- libraries/fbx/src/FBXReader_Mesh.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 7b83e74ebc..19bd99ec5d 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -781,20 +781,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { attribChannel = 2; totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize; - } /*else { - auto posBuffer = std::make_shared(); - posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); - vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); - - // update channels and attribBuffer size accordingly - interleavePositions = false; - interleaveNormalsTangents = true; - - tangentChannel = 1; - attribChannel = 1; - - totalAttribBufferSize = totalVertsSize - positionsSize; - }*/ + } // Define the vertex format, compute the offset for each attributes as we append them to the vertex format gpu::Offset bufOffset = 0; From 734956211151b4ee4566732e743f5b86bc87dea1 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Thu, 6 Sep 2018 15:50:31 -0700 Subject: [PATCH 13/18] Removing commented code --- libraries/gpu/src/gpu/Batch.h | 5 +---- libraries/graphics/src/graphics/Geometry.cpp | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 2bead507b8..bb38379a66 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -417,10 +417,7 @@ public: } const Data& get(uint32 offset) const { - /* if (offset >= _items.size()) { - static const Data EMPTY; - return EMPTY; - }*/ + assert((offset >= _items.size())); return (_items.data() + offset)->_data; } diff --git a/libraries/graphics/src/graphics/Geometry.cpp b/libraries/graphics/src/graphics/Geometry.cpp index 5a374ae8d0..a983ba07b4 100755 --- a/libraries/graphics/src/graphics/Geometry.cpp +++ b/libraries/graphics/src/graphics/Geometry.cpp @@ -119,7 +119,6 @@ Box Mesh::evalPartBound(int partNum) const { for (;index != endIndex; index++) { // skip primitive restart indices if ((*index) != PRIMITIVE_RESTART_INDEX) { - // box += vertices[(*index)]; box += _vertexBuffer.get(part._baseVertex + (*index)); } } @@ -140,7 +139,6 @@ Box Mesh::evalPartsBound(int partStart, int partEnd) const { for (;index != endIndex; index++) { // skip primitive restart indices if ((*index) != (uint) PRIMITIVE_RESTART_INDEX) { - //partBound += vertices[(*index)]; partBound += _vertexBuffer.get((*part)._baseVertex + (*index)); } } From d979d02139158069201b489ad5a9e674a8cee951 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 7 Sep 2018 10:03:55 -0700 Subject: [PATCH 14/18] why did i do that? --- libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h index b9fe125c8d..6b7d3405f0 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h @@ -65,7 +65,7 @@ public: ~GLBuffer(); - virtual void transfer() {}; + virtual void transfer() = 0; protected: GLBuffer(const std::weak_ptr& backend, const Buffer& buffer, GLuint id); From fa72910ac13b7876dcfe606aa38aa262cb38f640 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 7 Sep 2018 11:14:12 -0700 Subject: [PATCH 15/18] fixing fuckeries --- libraries/fbx/src/FBXReader_Mesh.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 19bd99ec5d..72f0fc6f23 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -734,8 +734,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { clusterIndices[i] = (uint8_t)(fbxMesh.clusterIndices[i]); } vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) clusterIndices.constData()); - } - else { + } else { vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) fbxMesh.clusterIndices.constData()); } } @@ -763,15 +762,14 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { bool interleaveNormalsTangents = true; // If has blend shapes allocate and assign buffers for pos and tangents now - hasBlendShapes = true; if (hasBlendShapes) { auto posBuffer = std::make_shared(); posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); - auto tangentBuffer = std::make_shared(); - tangentBuffer->setData(normalsAndTangentsSize, (const gpu::Byte*) vertBuffer->getData() + normalsAndTangentsOffset); - vertexBufferStream->addBuffer(tangentBuffer, 0, normalsAndTangentsStride); + auto normalsAndTangentsBuffer = std::make_shared(); + normalsAndTangentsBuffer->setData(normalsAndTangentsSize, (const gpu::Byte*) vertBuffer->getData() + normalsAndTangentsOffset); + vertexBufferStream->addBuffer(normalsAndTangentsBuffer, 0, normalsAndTangentsStride); // update channels and attribBuffer size accordingly interleavePositions = false; @@ -814,8 +812,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { if (texCoords1Size) { vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, attribChannel, texCoordsElement, bufOffset); bufOffset += texCoordsElement.getSize(); - } - else if (texCoordsSize) { + } else if (texCoordsSize) { vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, attribChannel, texCoordsElement, bufOffset - texCoordsElement.getSize()); } if (clusterIndicesSize) { From 9350d6f36e5c82b142619f5ac3e8665d7802e980 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 7 Sep 2018 15:35:10 -0700 Subject: [PATCH 16/18] removing performance counters --- libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp | 1 - libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp | 5 +---- libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 3 --- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp index f326ef39b9..8d46b4c6e3 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp @@ -259,7 +259,6 @@ void GLBackend::updateInput() { // Profile the count of buffers to update and use it to short cut the for loop int numInvalids = (int) _input._invalidBuffers.count(); _stats._ISNumInputBufferChanges += numInvalids; - PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); for (GLuint buffer = 0; buffer < _input._buffers.size(); buffer++, vbo++, offset++, stride++) { if (_input._invalidBuffers.test(buffer)) { diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp index cedb18c87a..c61ffb09e5 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp @@ -80,10 +80,7 @@ void GL41Backend::updateInput() { auto& inputChannels = _input._format->getChannels(); int numInvalids = (int)_input._invalidBuffers.count(); _stats._ISNumInputBufferChanges += numInvalids; - - // Profile the count of buffers to update - PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); - + GLuint boundVBO = 0; for (auto& channelIt : inputChannels) { const Stream::Format::ChannelMap::value_type::second_type& channel = (channelIt).second; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index 4a8bdc43f3..7cd8756ead 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -36,7 +36,6 @@ void GL45Backend::updateInput() { _input._lastUpdateStereoState = isStereoNow; if (_input._invalidFormat) { - PROFILE_RANGE(render_gpu, "bindInputFormat"); InputStageState::ActivationCache newActivation; // Assign the vertex format required @@ -136,7 +135,6 @@ void GL45Backend::updateInput() { // Profile the count of buffers to update and use it to short cut the for loop int numInvalids = (int) _input._invalidBuffers.count(); _stats._ISNumInputBufferChanges += numInvalids; - PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); auto numBuffers = _input._buffers.size(); for (GLuint buffer = 0; buffer < numBuffers; buffer++, vbo++, offset++, stride++) { @@ -149,7 +147,6 @@ void GL45Backend::updateInput() { } } - _input._invalidBuffers.reset(); (void)CHECK_GL_ERROR(); } From 5140999445ffeb87a39e926d50e6c0b2e43df9a9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 7 Sep 2018 15:57:04 -0700 Subject: [PATCH 17/18] Forcing all the meshes with 3 buffers aka the blendshape layout --- libraries/fbx/src/FBXReader_Mesh.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 72f0fc6f23..e8b5abcc9c 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -761,6 +761,12 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { bool interleavePositions = true; bool interleaveNormalsTangents = true; + // TODO: We are using the same vertex format layout for all meshes because this is more efficient + // This work is going into rc73 release which is meant to be used for the SPot500 event and we are picking the format + // that works best for blendshaped and skinned meshes aka the avatars. + // We will improve this technique in a hot fix to 73. + hasBlendShapes = true; + // If has blend shapes allocate and assign buffers for pos and tangents now if (hasBlendShapes) { auto posBuffer = std::make_shared(); From 082d47d20ff3955ba6e088bc9a9028832c167b8f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 10 Sep 2018 14:31:49 -0700 Subject: [PATCH 18/18] Set the correct assert in replacment of the unecessary if branch --- libraries/gpu/src/gpu/Batch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index bb38379a66..b49d14e5a1 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -417,7 +417,7 @@ public: } const Data& get(uint32 offset) const { - assert((offset >= _items.size())); + assert((offset < _items.size())); return (_items.data() + offset)->_data; }