diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 30e591cc60..5604fa21c7 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -107,6 +107,19 @@ void Batch::setInputFormat(const Stream::FormatPointer& format) { _params.push_back(_streamFormats.cache(format)); } +void Batch::setInputBuffer(Slot channel, const BufferPointer& buffer, Offset offset, Offset stride) { + ADD_COMMAND(setInputBuffer); + + _params.push_back(stride); + _params.push_back(offset); + _params.push_back(_buffers.cache(buffer)); + _params.push_back(channel); +} + +void Batch::setInputBuffer(Slot channel, const BufferView& view) { + setInputBuffer(channel, view._buffer, view._offset, Offset(view._stride)); +} + void Batch::setInputStream(Slot startChannel, const BufferStream& stream) { if (stream.getNumBuffers()) { const Buffers& buffers = stream.getBuffers(); @@ -118,15 +131,6 @@ void Batch::setInputStream(Slot startChannel, const BufferStream& stream) { } } -void Batch::setInputBuffer(Slot channel, const BufferPointer& buffer, Offset offset, Offset stride) { - ADD_COMMAND(setInputBuffer); - - _params.push_back(stride); - _params.push_back(offset); - _params.push_back(_buffers.cache(buffer)); - _params.push_back(channel); -} - void Batch::setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset) { ADD_COMMAND(setIndexBuffer); @@ -153,3 +157,17 @@ void Batch::setProjectionTransform(const Transform& proj) { _params.push_back(_transforms.cache(proj)); } +void Batch::setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size) { + ADD_COMMAND(setUniformBuffer); + + _params.push_back(size); + _params.push_back(offset); + _params.push_back(_buffers.cache(buffer)); + _params.push_back(slot); +} + +void Batch::setUniformBuffer(uint32 slot, const BufferView& view) { + setUniformBuffer(slot, view._buffer, view._offset, view._size); +} + + diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 601ae63a77..c3a87c8f19 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -72,8 +72,9 @@ public: // IndexBuffer void setInputFormat(const Stream::FormatPointer& format); - void setInputStream(Slot startChannel, const BufferStream& stream); // not a command, just unroll into a loop of setInputBuffer void setInputBuffer(Slot channel, const BufferPointer& buffer, Offset offset, Offset stride); + void setInputBuffer(Slot channel, const BufferView& buffer); // not a command, just a shortcut from a BufferView + void setInputStream(Slot startChannel, const BufferStream& stream); // not a command, just unroll into a loop of setInputBuffer void setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset); @@ -87,6 +88,9 @@ public: void setViewTransform(const Transform& view); void setProjectionTransform(const Transform& proj); + // Shader Stage + void setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size); + void setUniformBuffer(uint32 slot, const BufferView& view); // not a command, just a shortcut from a BufferView // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long @@ -117,6 +121,7 @@ public: void _glUseProgram(GLuint program); void _glUniform1f(GLint location, GLfloat v0); void _glUniform2f(GLint location, GLfloat v0, GLfloat v1); + void _glUniform4fv(GLint location, GLsizei count, const GLfloat* value); void _glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); void _glMatrixMode(GLenum mode); @@ -161,6 +166,8 @@ public: COMMAND_setViewTransform, COMMAND_setProjectionTransform, + COMMAND_setUniformBuffer, + // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API @@ -187,6 +194,7 @@ public: COMMAND_glUseProgram, COMMAND_glUniform1f, COMMAND_glUniform2f, + COMMAND_glUniform4fv, COMMAND_glUniformMatrix4fv, COMMAND_glMatrixMode, diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index 3a0fffb4ef..6839f9480a 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -12,7 +12,6 @@ #define hifi_gpu_Context_h #include -#include "GPUConfig.h" #include "Resource.h" diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index d216495b4c..aeeece8a62 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -12,8 +12,6 @@ #define hifi_gpu_Format_h #include -#include "GPUConfig.h" - namespace gpu { @@ -94,7 +92,8 @@ static const int DIMENSION_COUNT[NUM_DIMENSIONS] = { // Semantic of an Element // Provide information on how to use the element enum Semantic { - RGB = 0, + RAW = 0, // used as RAW memory + RGB, RGBA, XYZ, XYZW, @@ -104,6 +103,8 @@ enum Semantic { DIR_XYZ, UV, R8, + INDEX, //used by index buffer of a mesh + PART, // used by part buffer of a mesh NUM_SEMANTICS, }; @@ -119,7 +120,7 @@ public: _type(type) {} Element() : - _semantic(R8), + _semantic(RAW), _dimension(SCALAR), _type(INT8) {} diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 90639929ca..f5f998d0d9 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -31,6 +31,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_setViewTransform), (&::gpu::GLBackend::do_setProjectionTransform), + (&::gpu::GLBackend::do_setUniformBuffer), + (&::gpu::GLBackend::do_glEnable), (&::gpu::GLBackend::do_glDisable), @@ -54,6 +56,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_glUseProgram), (&::gpu::GLBackend::do_glUniform1f), (&::gpu::GLBackend::do_glUniform2f), + (&::gpu::GLBackend::do_glUniform4fv), (&::gpu::GLBackend::do_glUniformMatrix4fv), (&::gpu::GLBackend::do_glMatrixMode), @@ -483,6 +486,25 @@ void GLBackend::updateTransform() { } } +void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) { + GLuint slot = batch._params[paramOffset + 3]._uint; + BufferPointer uniformBuffer = batch._buffers.get(batch._params[paramOffset + 2]._uint); + GLintptr rangeStart = batch._params[paramOffset + 1]._uint; + GLsizeiptr rangeSize = batch._params[paramOffset + 0]._uint; +#if defined(Q_OS_MAC) + GLfloat* data = (GLfloat*) (uniformBuffer->getData() + rangeStart); + glUniform4fv(slot, rangeSize / sizeof(GLfloat[4]), data); +#else + GLuint bo = getBufferID(*uniformBuffer); + glBindBufferRange(GL_UNIFORM_BUFFER, slot, bo, rangeStart, rangeSize); + + // glUniformBufferEXT(_shader._program, slot, bo); + + //glBindBufferBase(GL_UNIFORM_BUFFER, slot, bo); +#endif + CHECK_GL_ERROR(); +} + // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API @@ -672,7 +694,10 @@ void Batch::_glUseProgram(GLuint program) { DO_IT_NOW(_glUseProgram, 1); } void GLBackend::do_glUseProgram(Batch& batch, uint32 paramOffset) { - glUseProgram(batch._params[paramOffset]._uint); + + _shader._program = batch._params[paramOffset]._uint; + glUseProgram(_shader._program); + CHECK_GL_ERROR(); } @@ -708,6 +733,25 @@ void GLBackend::do_glUniform2f(Batch& batch, uint32 paramOffset) { CHECK_GL_ERROR(); } +void Batch::_glUniform4fv(GLint location, GLsizei count, const GLfloat* value) { + ADD_COMMAND_GL(glUniform4fv); + + const int VEC4_SIZE = 4 * sizeof(float); + _params.push_back(cacheData(count * VEC4_SIZE, value)); + _params.push_back(count); + _params.push_back(location); + + DO_IT_NOW(_glUniform4fv, 3); +} +void GLBackend::do_glUniform4fv(Batch& batch, uint32 paramOffset) { + glUniform4fv( + batch._params[paramOffset + 2]._int, + batch._params[paramOffset + 1]._uint, + (const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint)); + + CHECK_GL_ERROR(); +} + void Batch::_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { ADD_COMMAND_GL(glUniformMatrix4fv); diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 5a40e9ca36..be7a0a594b 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -122,6 +122,19 @@ protected: _lastMode(GL_TEXTURE) {} } _transform; + // Shader Stage + void do_setUniformBuffer(Batch& batch, uint32 paramOffset); + + void updateShader(); + struct ShaderStageState { + + GLuint _program; + + ShaderStageState() : + _program(0) {} + } _shader; + + // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API @@ -148,6 +161,7 @@ protected: void do_glUseProgram(Batch& batch, uint32 paramOffset); void do_glUniform1f(Batch& batch, uint32 paramOffset); void do_glUniform2f(Batch& batch, uint32 paramOffset); + void do_glUniform4fv(Batch& batch, uint32 paramOffset); void do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset); void do_glMatrixMode(Batch& batch, uint32 paramOffset); diff --git a/libraries/gpu/src/gpu/Resource.cpp b/libraries/gpu/src/gpu/Resource.cpp index 3a6e47a7ba..085d97184b 100644 --- a/libraries/gpu/src/gpu/Resource.cpp +++ b/libraries/gpu/src/gpu/Resource.cpp @@ -67,6 +67,26 @@ Resource::Sysmem::Sysmem(Size size, const Byte* bytes) : } } +Resource::Sysmem::Sysmem(const Sysmem& sysmem) : + _stamp(0), + _size(0), + _data(NULL) +{ + if (sysmem.getSize() > 0) { + _size = allocateMemory(&_data, sysmem.getSize()); + if (_size >= sysmem.getSize()) { + if (sysmem.readData()) { + memcpy(_data, sysmem.readData(), sysmem.getSize()); + } + } + } +} + +Resource::Sysmem& Resource::Sysmem::operator=(const Sysmem& sysmem) { + setData(sysmem.getSize(), sysmem.readData()); + return (*this); +} + Resource::Sysmem::~Sysmem() { deallocateMemory( _data, _size ); _data = NULL; @@ -152,9 +172,25 @@ Resource::Size Resource::Sysmem::append(Size size, const Byte* bytes) { Buffer::Buffer() : Resource(), - _sysmem(NULL), + _sysmem(new Sysmem()), _gpuObject(NULL) { - _sysmem = new Sysmem(); +} + +Buffer::Buffer(Size size, const Byte* bytes) : + Resource(), + _sysmem(new Sysmem(size, bytes)), + _gpuObject(NULL) { +} + +Buffer::Buffer(const Buffer& buf) : + Resource(), + _sysmem(new Sysmem(buf.getSysmem())), + _gpuObject(NULL) { +} + +Buffer& Buffer::operator=(const Buffer& buf) { + (*_sysmem) = buf.getSysmem(); + return (*this); } Buffer::~Buffer() { diff --git a/libraries/gpu/src/gpu/Resource.h b/libraries/gpu/src/gpu/Resource.h index 6247efe675..ec528c230b 100644 --- a/libraries/gpu/src/gpu/Resource.h +++ b/libraries/gpu/src/gpu/Resource.h @@ -12,13 +12,15 @@ #define hifi_gpu_Resource_h #include -#include "GPUConfig.h" #include "Format.h" #include #include +#ifdef _DEBUG +#include +#endif namespace gpu { @@ -29,7 +31,7 @@ typedef int Stamp; class Resource { public: typedef unsigned char Byte; - typedef unsigned int Size; + typedef unsigned int Size; static const Size NOT_ALLOCATED = -1; @@ -47,6 +49,8 @@ protected: Sysmem(); Sysmem(Size size, const Byte* bytes); + Sysmem(const Sysmem& sysmem); // deep copy of the sysmem buffer + Sysmem& operator=(const Sysmem& sysmem); // deep copy of the sysmem buffer ~Sysmem(); Size getSize() const { return _size; } @@ -90,9 +94,6 @@ protected: static void deallocateMemory(Byte* memDeallocated, Size size); private: - Sysmem(const Sysmem& sysmem) {} - Sysmem &operator=(const Sysmem& other) {return *this;} - Stamp _stamp; Size _size; Byte* _data; @@ -104,12 +105,15 @@ class Buffer : public Resource { public: Buffer(); - Buffer(const Buffer& buf); + Buffer(Size size, const Byte* bytes); + Buffer(const Buffer& buf); // deep copy of the sysmem buffer + Buffer& operator=(const Buffer& buf); // deep copy of the sysmem buffer ~Buffer(); // The size in bytes of data stored in the buffer Size getSize() const { return getSysmem().getSize(); } const Byte* getData() const { return getSysmem().readData(); } + Byte* editData() { return editSysmem().editData(); } // Resize the buffer // Keep previous data [0 to min(pSize, mSize)] @@ -130,7 +134,7 @@ public: // Access the sysmem object. const Sysmem& getSysmem() const { assert(_sysmem); return (*_sysmem); } - + Sysmem& editSysmem() { assert(_sysmem); return (*_sysmem); } protected: @@ -138,8 +142,6 @@ protected: mutable GPUObject* _gpuObject; - Sysmem& editSysmem() { assert(_sysmem); return (*_sysmem); } - // This shouldn't be used by anything else than the Backend class with the proper casting. void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; } GPUObject* getGPUObject() const { return _gpuObject; } @@ -149,6 +151,281 @@ protected: typedef QSharedPointer BufferPointer; typedef std::vector< BufferPointer > Buffers; + + +class BufferView { +public: + typedef Resource::Size Size; + typedef int Index; + + BufferPointer _buffer; + Size _offset; + Size _size; + Element _element; + uint16 _stride; + + BufferView() : + _buffer(NULL), + _offset(0), + _size(0), + _element(gpu::SCALAR, gpu::UINT8, gpu::RAW), + _stride(1) + {}; + + BufferView(const Element& element) : + _buffer(NULL), + _offset(0), + _size(0), + _element(element), + _stride(uint16(element.getSize())) + {}; + + // create the BufferView and own the Buffer + BufferView(Buffer* newBuffer, const Element& element = Element(gpu::SCALAR, gpu::UINT8, gpu::RAW)) : + _buffer(newBuffer), + _offset(0), + _size(newBuffer->getSize()), + _element(element), + _stride(uint16(element.getSize())) + {}; + BufferView(const BufferPointer& buffer, const Element& element = Element(gpu::SCALAR, gpu::UINT8, gpu::RAW)) : + _buffer(buffer), + _offset(0), + _size(buffer->getSize()), + _element(element), + _stride(uint16(element.getSize())) + {}; + BufferView(const BufferPointer& buffer, Size offset, Size size, const Element& element = Element(gpu::SCALAR, gpu::UINT8, gpu::RAW)) : + _buffer(buffer), + _offset(offset), + _size(size), + _element(element), + _stride(uint16(element.getSize())) + {}; + ~BufferView() {} + BufferView(const BufferView& view) = default; + BufferView& operator=(const BufferView& view) = default; + + Size getNumElements() const { return _size / _element.getSize(); } + + //Template iterator with random access on the buffer sysmem + template + class Iterator : public std::iterator + { + public: + + Iterator(T* ptr = NULL) { _ptr = ptr; } + Iterator(const Iterator& iterator) = default; + ~Iterator() {} + + Iterator& operator=(const Iterator& iterator) = default; + Iterator& operator=(T* ptr) { + _ptr = ptr; + return (*this); + } + + operator bool() const + { + if(_ptr) + return true; + else + return false; + } + + bool operator==(const Iterator& iterator) const { return (_ptr == iterator.getConstPtr()); } + bool operator!=(const Iterator& iterator) const { return (_ptr != iterator.getConstPtr()); } + + Iterator& operator+=(const Index& movement) { + _ptr += movement; + return (*this); + } + Iterator& operator-=(const Index& movement) { + _ptr -= movement; + return (*this); + } + Iterator& operator++() { + ++_ptr; + return (*this); + } + Iterator& operator--() { + --_ptr; + return (*this); + } + Iterator operator++(Index) { + auto temp(*this); + ++_ptr; + return temp; + } + Iterator operator--(Index) { + auto temp(*this); + --_ptr; + return temp; + } + Iterator operator+(const Index& movement) { + auto oldPtr = _ptr; + _ptr += movement; + auto temp(*this); + _ptr = oldPtr; + return temp; + } + Iterator operator-(const Index& movement) { + auto oldPtr = _ptr; + _ptr -= movement; + auto temp(*this); + _ptr = oldPtr; + return temp; + } + + Index operator-(const Iterator& iterator) { return (iterator.getPtr() - this->getPtr())/sizeof(T); } + + T& operator*(){return *_ptr;} + const T& operator*()const{return *_ptr;} + T* operator->(){return _ptr;} + + T* getPtr()const{return _ptr;} + const T* getConstPtr()const{return _ptr;} + + protected: + + T* _ptr; + }; + + template Iterator begin() { return Iterator(&edit(0)); } + template Iterator end() { return Iterator(&edit(getNum())); } + template Iterator cbegin() const { return Iterator(&get(0)); } + template Iterator cend() const { return Iterator(&get(getNum())); } + + // the number of elements of the specified type fitting in the view size + template Index getNum() const { + return Index(_size / sizeof(T)); + } + + template const T& get() const { + #if _DEBUG + if (_buffer.isNull()) { + qDebug() << "Accessing null gpu::buffer!"; + } + if (sizeof(T) > (_buffer->getSize() - _offset)) { + qDebug() << "Accessing buffer in non allocated memory, element size = " << sizeof(T) << " available space in buffer at offset is = " << (_buffer->getSize() - _offset); + } + if (sizeof(T) > _size) { + qDebug() << "Accessing buffer outside the BufferView range, element size = " << sizeof(T) << " when bufferView size = " << _size; + } + #endif + const T* t = (reinterpret_cast (_buffer->getData() + _offset)); + return *(t); + } + + template T& edit() { + #if _DEBUG + if (_buffer.isNull()) { + qDebug() << "Accessing null gpu::buffer!"; + } + if (sizeof(T) > (_buffer->getSize() - _offset)) { + qDebug() << "Accessing buffer in non allocated memory, element size = " << sizeof(T) << " available space in buffer at offset is = " << (_buffer->getSize() - _offset); + } + if (sizeof(T) > _size) { + qDebug() << "Accessing buffer outside the BufferView range, element size = " << sizeof(T) << " when bufferView size = " << _size; + } + #endif + T* t = (reinterpret_cast (_buffer->editData() + _offset)); + return *(t); + } + + template const T& get(const Index index) const { + Resource::Size elementOffset = index * sizeof(T) + _offset; + #if _DEBUG + if (_buffer.isNull()) { + qDebug() << "Accessing null gpu::buffer!"; + } + if (sizeof(T) > (_buffer->getSize() - elementOffset)) { + qDebug() << "Accessing buffer in non allocated memory, index = " << index << ", element size = " << sizeof(T) << " available space in buffer at offset is = " << (_buffer->getSize() - elementOffset); + } + if (index > getNum()) { + qDebug() << "Accessing buffer outside the BufferView range, index = " << index << " number elements = " << getNum(); + } + #endif + return *(reinterpret_cast (_buffer->getData() + elementOffset)); + } + + template T& edit(const Index index) const { + Resource::Size elementOffset = index * sizeof(T) + _offset; + #if _DEBUG + if (_buffer.isNull()) { + qDebug() << "Accessing null gpu::buffer!"; + } + if (sizeof(T) > (_buffer->getSize() - elementOffset)) { + qDebug() << "Accessing buffer in non allocated memory, index = " << index << ", element size = " << sizeof(T) << " available space in buffer at offset is = " << (_buffer->getSize() - elementOffset); + } + if (index > getNum()) { + qDebug() << "Accessing buffer outside the BufferView range, index = " << index << " number elements = " << getNum(); + } + #endif + return *(reinterpret_cast (_buffer->editData() + elementOffset)); + } +}; + + + // TODO: For now TextureView works with Buffer as a place holder for the Texture. + // The overall logic should be about the same except that the Texture will be a real GL Texture under the hood +class TextureView { +public: + typedef Resource::Size Size; + typedef int Index; + + BufferPointer _buffer; + Size _offset; + Size _size; + Element _element; + uint16 _stride; + + TextureView() : + _buffer(NULL), + _offset(0), + _size(0), + _element(gpu::VEC3, gpu::UINT8, gpu::RGB), + _stride(1) + {}; + + TextureView(const Element& element) : + _buffer(NULL), + _offset(0), + _size(0), + _element(element), + _stride(uint16(element.getSize())) + {}; + + // create the BufferView and own the Buffer + TextureView(Buffer* newBuffer, const Element& element) : + _buffer(newBuffer), + _offset(0), + _size(newBuffer->getSize()), + _element(element), + _stride(uint16(element.getSize())) + {}; + TextureView(const BufferPointer& buffer, const Element& element) : + _buffer(buffer), + _offset(0), + _size(buffer->getSize()), + _element(element), + _stride(uint16(element.getSize())) + {}; + TextureView(const BufferPointer& buffer, Size offset, Size size, const Element& element) : + _buffer(buffer), + _offset(offset), + _size(size), + _element(element), + _stride(uint16(element.getSize())) + {}; + ~TextureView() {} + TextureView(const TextureView& view) = default; + TextureView& operator=(const TextureView& view) = default; +}; + }; diff --git a/libraries/gpu/src/gpu/Stream.cpp b/libraries/gpu/src/gpu/Stream.cpp index 099cbde24a..73677f715e 100644 --- a/libraries/gpu/src/gpu/Stream.cpp +++ b/libraries/gpu/src/gpu/Stream.cpp @@ -18,7 +18,7 @@ void Stream::Format::evaluateCache() { _elementTotalSize = 0; for(AttributeMap::iterator it = _attributes.begin(); it != _attributes.end(); it++) { Attribute& attrib = (*it).second; - Channel& channel = _channels[attrib._channel]; + ChannelInfo& channel = _channels[attrib._channel]; channel._slots.push_back(attrib._slot); channel._stride = std::max(channel._stride, attrib.getSize() + attrib._offset); channel._netSize += attrib.getSize(); @@ -41,7 +41,7 @@ BufferStream::BufferStream() : BufferStream::~BufferStream() { } -void BufferStream::addBuffer(BufferPointer& buffer, Offset offset, Offset stride) { +void BufferStream::addBuffer(const BufferPointer& buffer, Offset offset, Offset stride) { _buffers.push_back(buffer); _offsets.push_back(offset); _strides.push_back(stride); diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index 93abfeeca3..b1aaec665f 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -12,7 +12,6 @@ #define hifi_gpu_Stream_h #include -#include "GPUConfig.h" #include "Resource.h" #include "Format.h" @@ -83,16 +82,16 @@ public: public: typedef std::map< Slot, Attribute > AttributeMap; - class Channel { + class ChannelInfo { public: std::vector< Slot > _slots; std::vector< Offset > _offsets; Offset _stride; uint32 _netSize; - Channel() : _stride(0), _netSize(0) {} + ChannelInfo() : _stride(0), _netSize(0) {} }; - typedef std::map< Slot, Channel > ChannelMap; + typedef std::map< Slot, ChannelInfo > ChannelMap; Format() : _attributes(), @@ -104,6 +103,7 @@ public: uint8 getNumChannels() const { return _channels.size(); } const ChannelMap& getChannels() const { return _channels; } + const Offset getChannelStride(Slot channel) const { return _channels.at(channel)._stride; } uint32 getElementTotalSize() const { return _elementTotalSize; } @@ -131,7 +131,7 @@ public: BufferStream(); ~BufferStream(); - void addBuffer(BufferPointer& buffer, Offset offset, Offset stride); + void addBuffer(const BufferPointer& buffer, Offset offset, Offset stride); const Buffers& getBuffers() const { return _buffers; } const Offsets& getOffsets() const { return _offsets; }