diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 6d7a5f2545..a3bedfcba3 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -153,7 +153,7 @@ public: class GLInputFormat : public GPUObject { public: - + std::string key; GLInputFormat(); ~GLInputFormat(); @@ -358,6 +358,7 @@ protected: struct InputStageState { bool _invalidFormat = true; Stream::FormatPointer _format; + std::string _formatKey; typedef std::bitset ActivationCache; ActivationCache _attributeActivation; @@ -385,6 +386,7 @@ protected: InputStageState() : _invalidFormat(true), _format(0), + _formatKey(), _attributeActivation(0), _invalidBuffers(0), _buffers(_invalidBuffers.size(), BufferPointer(0)), diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 09ed625ef6..81e42ba9a0 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -28,6 +28,7 @@ GLBackend::GLInputFormat* GLBackend::syncGPUObject(const Stream::Format& inputFo } object = new GLInputFormat(); + object->key = inputFormat.getKey(); Backend::setGPUObject(inputFormat, object); } @@ -37,7 +38,15 @@ void GLBackend::do_setInputFormat(Batch& batch, size_t paramOffset) { if (ifo) { if (format != _input._format) { _input._format = format; - _input._invalidFormat = true; + if (format) { + if (_input._formatKey != format->getKey()) { + _input._formatKey = format->getKey(); + _input._invalidFormat = true; + } + } else { + _input._invalidFormat = true; + _input._formatKey.clear(); + } } } } @@ -295,6 +304,7 @@ void GLBackend::resetInputStage() { // Reset vertex buffer and format _input._format.reset(); + _input._formatKey.clear(); _input._invalidFormat = false; _input._attributeActivation.reset(); diff --git a/libraries/gpu/src/gpu/Stream.cpp b/libraries/gpu/src/gpu/Stream.cpp index 90f2327fc8..93601d204b 100644 --- a/libraries/gpu/src/gpu/Stream.cpp +++ b/libraries/gpu/src/gpu/Stream.cpp @@ -12,6 +12,8 @@ #include "Stream.h" #include //min max and more +#include +#include using namespace gpu; @@ -39,7 +41,18 @@ const ElementArray& getDefaultElements() { return defaultElements; } +std::string Stream::Attribute::getKey() const { + std::stringstream skey; + + skey << std::hex; + skey << std::setw(8) << std::setfill('0') << (uint32)((((uint32)_slot) << 24) | (((uint32)_channel) << 16) | ((uint32)_element.getRaw())); + skey << _offset; + skey << _frequency; + return skey.str(); +} + void Stream::Format::evaluateCache() { + _key.clear(); _channels.clear(); _elementTotalSize = 0; for(AttributeMap::iterator it = _attributes.begin(); it != _attributes.end(); it++) { @@ -49,6 +62,8 @@ void Stream::Format::evaluateCache() { channel._stride = std::max(channel._stride, attrib.getSize() + attrib._offset); channel._netSize += attrib.getSize(); _elementTotalSize += attrib.getSize(); + + _key += attrib.getKey(); } } diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index 950a713cf0..88ed70c78e 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -73,6 +73,9 @@ public: // Size of the uint32 getSize() const { return _element.getSize(); } + + // Generate a string key describing the attribute uniquely + std::string getKey() const; }; // Stream Format is describing how to feed a list of attributes from a bunch of stream buffer channels @@ -106,6 +109,8 @@ public: bool hasAttribute(Slot slot) const { return (_attributes.find(slot) != _attributes.end()); } + const std::string& getKey() const { return _key; } + const GPUObjectPointer gpuObject{}; protected: AttributeMap _attributes; @@ -113,6 +118,8 @@ public: uint32 _elementTotalSize { 0 }; void evaluateCache(); + + std::string _key; }; typedef std::shared_ptr FormatPointer;