From d727e3b493f013d1e0defd67f24d498c59e12ce3 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 20 Apr 2016 19:09:31 -0700 Subject: [PATCH] Trying to explore the bug with separate vertex format --- .../RenderableParticleEffectEntityItem.cpp | 2 +- libraries/gpu/src/gpu/GLBackend.h | 3 +- libraries/gpu/src/gpu/GLBackendInput.cpp | 94 +++++++++++++------ libraries/gpu/src/gpu/GLBackendTransform.cpp | 31 ++++-- libraries/gpu/src/gpu/Stream.cpp | 1 + 5 files changed, 90 insertions(+), 41 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index a199c6b10e..8f5bb49a1b 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -106,7 +106,7 @@ public: batch.setInputBuffer(0, _particleBuffer, 0, sizeof(ParticlePrimitive)); auto numParticles = _particleBuffer->getSize() / sizeof(ParticlePrimitive); - batch.drawInstanced((gpu::uint32)numParticles, gpu::TRIANGLE_STRIP, (gpu::uint32)VERTEX_PER_PARTICLE); + // batch.drawInstanced((gpu::uint32)numParticles, gpu::TRIANGLE_STRIP, (gpu::uint32)VERTEX_PER_PARTICLE); } protected: diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index a156e7be8b..803cefb585 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -366,6 +366,7 @@ protected: typedef std::bitset BuffersState; BuffersState _invalidBuffers; + BuffersState _attribBindingBuffers; Buffers _buffers; Offsets _bufferOffsets; @@ -383,7 +384,7 @@ protected: Offset _indirectBufferStride{ 0 }; GLuint _defaultVAO; - + InputStageState() : _invalidFormat(true), _format(0), diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 81e42ba9a0..0f00fec712 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -133,41 +133,67 @@ void GLBackend::updateInput() { // Assign the vertex format required if (_input._format) { - for (auto& it : _input._format->getAttributes()) { - const Stream::Attribute& attrib = (it).second; + _input._attribBindingBuffers.reset(); - GLuint slot = attrib._slot; - GLuint count = attrib._element.getLocationScalarCount(); - uint8_t locationCount = attrib._element.getLocationCount(); - GLenum type = _elementTypeToGLType[attrib._element.getType()]; - GLuint offset = attrib._offset;; - GLboolean isNormalized = attrib._element.isNormalized(); + const Stream::Format::AttributeMap& attributes = _input._format->getAttributes(); + auto& inputChannels = _input._format->getChannels(); + for (auto& channelIt : inputChannels) { + auto bufferChannelNum = (channelIt).first; + const Stream::Format::ChannelMap::value_type::second_type& channel = (channelIt).second; + _input._attribBindingBuffers.set(bufferChannelNum); - GLenum perLocationSize = attrib._element.getLocationSize(); + GLuint frequency = 0; + for (unsigned int i = 0; i < channel._slots.size(); i++) { + const Stream::Attribute& attrib = attributes.at(channel._slots[i]); - for (size_t locNum = 0; locNum < locationCount; ++locNum) { - newActivation.set(slot + locNum); - glVertexAttribFormat(slot + locNum, count, type, isNormalized, offset + locNum * perLocationSize); - glVertexAttribBinding(slot + locNum, attrib._channel); + GLuint slot = attrib._slot; + GLuint count = attrib._element.getLocationScalarCount(); + uint8_t locationCount = attrib._element.getLocationCount(); + GLenum type = _elementTypeToGLType[attrib._element.getType()]; + + GLuint offset = attrib._offset;; + GLboolean isNormalized = attrib._element.isNormalized(); + + GLenum perLocationSize = attrib._element.getLocationSize(); + for (size_t locNum = 0; locNum < locationCount; ++locNum) { + auto attriNum = slot + locNum; + newActivation.set(attriNum); + if (!_input._attributeActivation[attriNum]) { + _input._attributeActivation.set(attriNum); + glEnableVertexAttribArray(attriNum); + } + glVertexAttribFormat(attriNum, count, type, isNormalized, offset + locNum * perLocationSize); + // TODO: Support properly the IAttrib version + glVertexAttribBinding(attriNum, attrib._channel); + } + + if (i == 0) { + frequency = attrib._frequency; + } else { + assert(frequency == attrib._frequency); + } + + (void)CHECK_GL_ERROR(); } - glVertexBindingDivisor(attrib._channel, attrib._frequency); + glVertexBindingDivisor(bufferChannelNum, frequency); } - (void) CHECK_GL_ERROR(); + + // Manage Activation what was and what is expected now + // This should only disable VertexAttribs since the one in use have been disabled above + for (size_t i = 0; i < newActivation.size(); i++) { + bool newState = newActivation[i]; + if (newState != _input._attributeActivation[i]) { + if (newState) { + glEnableVertexAttribArray(i); + } else { + glDisableVertexAttribArray(i); + } + _input._attributeActivation.flip(i); + } + } + (void)CHECK_GL_ERROR(); } - // Manage Activation what was and what is expected now - for (size_t i = 0; i < newActivation.size(); i++) { - bool newState = newActivation[i]; - if (newState != _input._attributeActivation[i]) { - if (newState) { - glEnableVertexAttribArray(i); - } else { - glDisableVertexAttribArray(i); - } - _input._attributeActivation.flip(i); - } - } - (void) CHECK_GL_ERROR(); _input._invalidFormat = false; _stats._ISNumFormatChanges++; @@ -294,13 +320,21 @@ void GLBackend::resetInputStage() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); (void) CHECK_GL_ERROR(); +#if defined(SUPPORT_VERTEX_ATTRIB_FORMAT) + glBindBuffer(GL_ARRAY_BUFFER, 0); + for (uint32_t i = 0; i < _input._attributeActivation.size(); i++) { + glDisableVertexAttribArray(i); + } + for (uint32_t i = 0; i < _input._attribBindingBuffers.size(); i++) { + glBindVertexBuffer(i, 0, 0, 0); + } +#else glBindBuffer(GL_ARRAY_BUFFER, 0); - - for (uint32_t i = 0; i < _input._attributeActivation.size(); i++) { glDisableVertexAttribArray(i); glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0); } +#endif // Reset vertex buffer and format _input._format.reset(); diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 80b7b226f7..bf236cd904 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -92,6 +92,9 @@ void GLBackend::syncTransformStateCache() { Mat4 modelView; auto modelViewInv = glm::inverse(modelView); _transform._view.evalFromRawMatrix(modelViewInv); + + glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); + _transform._enabledDrawcallInfoBuffer = false; } void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const StereoState& stereo) { @@ -200,6 +203,12 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta (void)CHECK_GL_ERROR(); } +#if(GPU_INPUT_PROFILE == GPU_CORE_41) +#define NO_SUPPORT_VERTEX_ATTRIB_FORMAT +#else +#define SUPPORT_VERTEX_ATTRIB_FORMAT +#endif + void GLBackend::updateTransform(const Batch& batch) { _transform.update(_commandIndex, _stereo); @@ -212,22 +221,26 @@ void GLBackend::updateTransform(const Batch& batch) { } glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); } else { +#if defined(SUPPORT_VERTEX_ATTRIB_FORMAT) if (!_transform._enabledDrawcallInfoBuffer) { glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled - // glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer); - /* glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, - _transform._drawCallInfoOffsets[batch._currentNamedCall]); - glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 1); - */ - glVertexAttribIFormat(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0); glVertexAttribBinding(gpu::Stream::DRAW_CALL_INFO, gpu::Stream::DRAW_CALL_INFO); glVertexBindingDivisor(gpu::Stream::DRAW_CALL_INFO, 1); _transform._enabledDrawcallInfoBuffer = true; } - glBindVertexBuffer(gpu::Stream::DRAW_CALL_INFO, _transform._drawCallInfoBuffer, (GLintptr) _transform._drawCallInfoOffsets[batch._currentNamedCall], 0); - // _transform._drawCallInfoOffsets[batch._currentNamedCall]); - + glBindVertexBuffer(gpu::Stream::DRAW_CALL_INFO, _transform._drawCallInfoBuffer, (GLintptr)_transform._drawCallInfoOffsets[batch._currentNamedCall], 0); + +#else + if (!_transform._enabledDrawcallInfoBuffer) { + glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled + glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer); + glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 1); + _transform._enabledDrawcallInfoBuffer = true; + } + glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, _transform._drawCallInfoOffsets[batch._currentNamedCall]); +#endif + } (void)CHECK_GL_ERROR(); diff --git a/libraries/gpu/src/gpu/Stream.cpp b/libraries/gpu/src/gpu/Stream.cpp index 93601d204b..cdb972d8bf 100644 --- a/libraries/gpu/src/gpu/Stream.cpp +++ b/libraries/gpu/src/gpu/Stream.cpp @@ -55,6 +55,7 @@ void Stream::Format::evaluateCache() { _key.clear(); _channels.clear(); _elementTotalSize = 0; + for(AttributeMap::iterator it = _attributes.begin(); it != _attributes.end(); it++) { Attribute& attrib = (*it).second; ChannelInfo& channel = _channels[attrib._channel];