Importing fixes from Model branch to the gpu library

This commit is contained in:
Sam Gateau 2014-12-19 12:44:46 -08:00
parent eaad95c949
commit 096b09e8e1
10 changed files with 433 additions and 36 deletions

View file

@ -107,6 +107,19 @@ void Batch::setInputFormat(const Stream::FormatPointer& format) {
_params.push_back(_streamFormats.cache(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) { void Batch::setInputStream(Slot startChannel, const BufferStream& stream) {
if (stream.getNumBuffers()) { if (stream.getNumBuffers()) {
const Buffers& buffers = stream.getBuffers(); 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) { void Batch::setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset) {
ADD_COMMAND(setIndexBuffer); ADD_COMMAND(setIndexBuffer);
@ -153,3 +157,17 @@ void Batch::setProjectionTransform(const Transform& proj) {
_params.push_back(_transforms.cache(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);
}

View file

@ -72,8 +72,9 @@ public:
// IndexBuffer // IndexBuffer
void setInputFormat(const Stream::FormatPointer& format); 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 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); void setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset);
@ -87,6 +88,9 @@ public:
void setViewTransform(const Transform& view); void setViewTransform(const Transform& view);
void setProjectionTransform(const Transform& proj); 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 // 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 // code, we need to be able to record and batch these calls. THe long
@ -117,6 +121,7 @@ public:
void _glUseProgram(GLuint program); void _glUseProgram(GLuint program);
void _glUniform1f(GLint location, GLfloat v0); void _glUniform1f(GLint location, GLfloat v0);
void _glUniform2f(GLint location, GLfloat v0, GLfloat v1); 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 _glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
void _glMatrixMode(GLenum mode); void _glMatrixMode(GLenum mode);
@ -161,6 +166,8 @@ public:
COMMAND_setViewTransform, COMMAND_setViewTransform,
COMMAND_setProjectionTransform, COMMAND_setProjectionTransform,
COMMAND_setUniformBuffer,
// TODO: As long as we have gl calls explicitely issued from interface // 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 // 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 // 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_glUseProgram,
COMMAND_glUniform1f, COMMAND_glUniform1f,
COMMAND_glUniform2f, COMMAND_glUniform2f,
COMMAND_glUniform4fv,
COMMAND_glUniformMatrix4fv, COMMAND_glUniformMatrix4fv,
COMMAND_glMatrixMode, COMMAND_glMatrixMode,

View file

@ -12,7 +12,6 @@
#define hifi_gpu_Context_h #define hifi_gpu_Context_h
#include <assert.h> #include <assert.h>
#include "GPUConfig.h"
#include "Resource.h" #include "Resource.h"

View file

@ -12,8 +12,6 @@
#define hifi_gpu_Format_h #define hifi_gpu_Format_h
#include <assert.h> #include <assert.h>
#include "GPUConfig.h"
namespace gpu { namespace gpu {
@ -94,7 +92,8 @@ static const int DIMENSION_COUNT[NUM_DIMENSIONS] = {
// Semantic of an Element // Semantic of an Element
// Provide information on how to use the element // Provide information on how to use the element
enum Semantic { enum Semantic {
RGB = 0, RAW = 0, // used as RAW memory
RGB,
RGBA, RGBA,
XYZ, XYZ,
XYZW, XYZW,
@ -104,6 +103,8 @@ enum Semantic {
DIR_XYZ, DIR_XYZ,
UV, UV,
R8, R8,
INDEX, //used by index buffer of a mesh
PART, // used by part buffer of a mesh
NUM_SEMANTICS, NUM_SEMANTICS,
}; };
@ -119,7 +120,7 @@ public:
_type(type) _type(type)
{} {}
Element() : Element() :
_semantic(R8), _semantic(RAW),
_dimension(SCALAR), _dimension(SCALAR),
_type(INT8) _type(INT8)
{} {}

View file

@ -31,6 +31,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::GLBackend::do_setViewTransform), (&::gpu::GLBackend::do_setViewTransform),
(&::gpu::GLBackend::do_setProjectionTransform), (&::gpu::GLBackend::do_setProjectionTransform),
(&::gpu::GLBackend::do_setUniformBuffer),
(&::gpu::GLBackend::do_glEnable), (&::gpu::GLBackend::do_glEnable),
(&::gpu::GLBackend::do_glDisable), (&::gpu::GLBackend::do_glDisable),
@ -54,6 +56,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::GLBackend::do_glUseProgram), (&::gpu::GLBackend::do_glUseProgram),
(&::gpu::GLBackend::do_glUniform1f), (&::gpu::GLBackend::do_glUniform1f),
(&::gpu::GLBackend::do_glUniform2f), (&::gpu::GLBackend::do_glUniform2f),
(&::gpu::GLBackend::do_glUniform4fv),
(&::gpu::GLBackend::do_glUniformMatrix4fv), (&::gpu::GLBackend::do_glUniformMatrix4fv),
(&::gpu::GLBackend::do_glMatrixMode), (&::gpu::GLBackend::do_glMatrixMode),
@ -171,8 +174,8 @@ void GLBackend::checkGLError() {
} }
} }
//#define CHECK_GL_ERROR() ::gpu::GLBackend::checkGLError() #define CHECK_GL_ERROR() ::gpu::GLBackend::checkGLError()
#define CHECK_GL_ERROR() //#define CHECK_GL_ERROR()
void GLBackend::do_draw(Batch& batch, uint32 paramOffset) { void GLBackend::do_draw(Batch& batch, uint32 paramOffset) {
updateInput(); updateInput();
@ -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 // 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 // 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 // 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); DO_IT_NOW(_glUseProgram, 1);
} }
void GLBackend::do_glUseProgram(Batch& batch, uint32 paramOffset) { 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(); CHECK_GL_ERROR();
} }
@ -708,6 +733,25 @@ void GLBackend::do_glUniform2f(Batch& batch, uint32 paramOffset) {
CHECK_GL_ERROR(); 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) { void Batch::_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
ADD_COMMAND_GL(glUniformMatrix4fv); ADD_COMMAND_GL(glUniformMatrix4fv);

View file

@ -122,6 +122,19 @@ protected:
_lastMode(GL_TEXTURE) {} _lastMode(GL_TEXTURE) {}
} _transform; } _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 // 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 // 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 // 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_glUseProgram(Batch& batch, uint32 paramOffset);
void do_glUniform1f(Batch& batch, uint32 paramOffset); void do_glUniform1f(Batch& batch, uint32 paramOffset);
void do_glUniform2f(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_glUniformMatrix4fv(Batch& batch, uint32 paramOffset);
void do_glMatrixMode(Batch& batch, uint32 paramOffset); void do_glMatrixMode(Batch& batch, uint32 paramOffset);

View file

@ -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() { Resource::Sysmem::~Sysmem() {
deallocateMemory( _data, _size ); deallocateMemory( _data, _size );
_data = NULL; _data = NULL;
@ -152,9 +172,25 @@ Resource::Size Resource::Sysmem::append(Size size, const Byte* bytes) {
Buffer::Buffer() : Buffer::Buffer() :
Resource(), Resource(),
_sysmem(NULL), _sysmem(new Sysmem()),
_gpuObject(NULL) { _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() { Buffer::~Buffer() {

View file

@ -12,13 +12,15 @@
#define hifi_gpu_Resource_h #define hifi_gpu_Resource_h
#include <assert.h> #include <assert.h>
#include "GPUConfig.h"
#include "Format.h" #include "Format.h"
#include <vector> #include <vector>
#include <QSharedPointer> #include <QSharedPointer>
#ifdef _DEBUG
#include <QDebug>
#endif
namespace gpu { namespace gpu {
@ -29,7 +31,7 @@ typedef int Stamp;
class Resource { class Resource {
public: public:
typedef unsigned char Byte; typedef unsigned char Byte;
typedef unsigned int Size; typedef unsigned int Size;
static const Size NOT_ALLOCATED = -1; static const Size NOT_ALLOCATED = -1;
@ -47,6 +49,8 @@ protected:
Sysmem(); Sysmem();
Sysmem(Size size, const Byte* bytes); 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(); ~Sysmem();
Size getSize() const { return _size; } Size getSize() const { return _size; }
@ -90,9 +94,6 @@ protected:
static void deallocateMemory(Byte* memDeallocated, Size size); static void deallocateMemory(Byte* memDeallocated, Size size);
private: private:
Sysmem(const Sysmem& sysmem) {}
Sysmem &operator=(const Sysmem& other) {return *this;}
Stamp _stamp; Stamp _stamp;
Size _size; Size _size;
Byte* _data; Byte* _data;
@ -104,12 +105,15 @@ class Buffer : public Resource {
public: public:
Buffer(); 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(); ~Buffer();
// The size in bytes of data stored in the buffer // The size in bytes of data stored in the buffer
Size getSize() const { return getSysmem().getSize(); } Size getSize() const { return getSysmem().getSize(); }
const Byte* getData() const { return getSysmem().readData(); } const Byte* getData() const { return getSysmem().readData(); }
Byte* editData() { return editSysmem().editData(); }
// Resize the buffer // Resize the buffer
// Keep previous data [0 to min(pSize, mSize)] // Keep previous data [0 to min(pSize, mSize)]
@ -130,7 +134,7 @@ public:
// Access the sysmem object. // Access the sysmem object.
const Sysmem& getSysmem() const { assert(_sysmem); return (*_sysmem); } const Sysmem& getSysmem() const { assert(_sysmem); return (*_sysmem); }
Sysmem& editSysmem() { assert(_sysmem); return (*_sysmem); }
protected: protected:
@ -138,8 +142,6 @@ protected:
mutable GPUObject* _gpuObject; 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. // This shouldn't be used by anything else than the Backend class with the proper casting.
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; } void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
GPUObject* getGPUObject() const { return _gpuObject; } GPUObject* getGPUObject() const { return _gpuObject; }
@ -149,6 +151,281 @@ protected:
typedef QSharedPointer<Buffer> BufferPointer; typedef QSharedPointer<Buffer> BufferPointer;
typedef std::vector< BufferPointer > Buffers; 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<typename T>
class Iterator : public std::iterator<std::random_access_iterator_tag,
T,
Index,
T*,
T&>
{
public:
Iterator(T* ptr = NULL) { _ptr = ptr; }
Iterator(const Iterator<T>& iterator) = default;
~Iterator() {}
Iterator<T>& operator=(const Iterator<T>& iterator) = default;
Iterator<T>& operator=(T* ptr) {
_ptr = ptr;
return (*this);
}
operator bool() const
{
if(_ptr)
return true;
else
return false;
}
bool operator==(const Iterator<T>& iterator) const { return (_ptr == iterator.getConstPtr()); }
bool operator!=(const Iterator<T>& iterator) const { return (_ptr != iterator.getConstPtr()); }
Iterator<T>& operator+=(const Index& movement) {
_ptr += movement;
return (*this);
}
Iterator<T>& operator-=(const Index& movement) {
_ptr -= movement;
return (*this);
}
Iterator<T>& operator++() {
++_ptr;
return (*this);
}
Iterator<T>& operator--() {
--_ptr;
return (*this);
}
Iterator<T> operator++(Index) {
auto temp(*this);
++_ptr;
return temp;
}
Iterator<T> operator--(Index) {
auto temp(*this);
--_ptr;
return temp;
}
Iterator<T> operator+(const Index& movement) {
auto oldPtr = _ptr;
_ptr += movement;
auto temp(*this);
_ptr = oldPtr;
return temp;
}
Iterator<T> operator-(const Index& movement) {
auto oldPtr = _ptr;
_ptr -= movement;
auto temp(*this);
_ptr = oldPtr;
return temp;
}
Index operator-(const Iterator<T>& 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 <typename T> Iterator<T> begin() { return Iterator<T>(&edit<T>(0)); }
template <typename T> Iterator<T> end() { return Iterator<T>(&edit<T>(getNum<T>())); }
template <typename T> Iterator<const T> cbegin() const { return Iterator<const T>(&get<T>(0)); }
template <typename T> Iterator<const T> cend() const { return Iterator<const T>(&get<T>(getNum<T>())); }
// the number of elements of the specified type fitting in the view size
template <typename T> Index getNum() const {
return Index(_size / sizeof(T));
}
template <typename T> 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<const T*> (_buffer->getData() + _offset));
return *(t);
}
template <typename T> 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<T*> (_buffer->editData() + _offset));
return *(t);
}
template <typename T> 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<T>()) {
qDebug() << "Accessing buffer outside the BufferView range, index = " << index << " number elements = " << getNum<T>();
}
#endif
return *(reinterpret_cast<const T*> (_buffer->getData() + elementOffset));
}
template <typename T> 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<T>()) {
qDebug() << "Accessing buffer outside the BufferView range, index = " << index << " number elements = " << getNum<T>();
}
#endif
return *(reinterpret_cast<T*> (_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;
};
}; };

View file

@ -18,7 +18,7 @@ void Stream::Format::evaluateCache() {
_elementTotalSize = 0; _elementTotalSize = 0;
for(AttributeMap::iterator it = _attributes.begin(); it != _attributes.end(); it++) { for(AttributeMap::iterator it = _attributes.begin(); it != _attributes.end(); it++) {
Attribute& attrib = (*it).second; Attribute& attrib = (*it).second;
Channel& channel = _channels[attrib._channel]; ChannelInfo& channel = _channels[attrib._channel];
channel._slots.push_back(attrib._slot); channel._slots.push_back(attrib._slot);
channel._stride = std::max(channel._stride, attrib.getSize() + attrib._offset); channel._stride = std::max(channel._stride, attrib.getSize() + attrib._offset);
channel._netSize += attrib.getSize(); channel._netSize += attrib.getSize();
@ -41,7 +41,7 @@ BufferStream::BufferStream() :
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); _buffers.push_back(buffer);
_offsets.push_back(offset); _offsets.push_back(offset);
_strides.push_back(stride); _strides.push_back(stride);

View file

@ -12,7 +12,6 @@
#define hifi_gpu_Stream_h #define hifi_gpu_Stream_h
#include <assert.h> #include <assert.h>
#include "GPUConfig.h"
#include "Resource.h" #include "Resource.h"
#include "Format.h" #include "Format.h"
@ -83,16 +82,16 @@ public:
public: public:
typedef std::map< Slot, Attribute > AttributeMap; typedef std::map< Slot, Attribute > AttributeMap;
class Channel { class ChannelInfo {
public: public:
std::vector< Slot > _slots; std::vector< Slot > _slots;
std::vector< Offset > _offsets; std::vector< Offset > _offsets;
Offset _stride; Offset _stride;
uint32 _netSize; 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() : Format() :
_attributes(), _attributes(),
@ -104,6 +103,7 @@ public:
uint8 getNumChannels() const { return _channels.size(); } uint8 getNumChannels() const { return _channels.size(); }
const ChannelMap& getChannels() const { return _channels; } const ChannelMap& getChannels() const { return _channels; }
const Offset getChannelStride(Slot channel) const { return _channels.at(channel)._stride; }
uint32 getElementTotalSize() const { return _elementTotalSize; } uint32 getElementTotalSize() const { return _elementTotalSize; }
@ -131,7 +131,7 @@ public:
BufferStream(); BufferStream();
~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 Buffers& getBuffers() const { return _buffers; }
const Offsets& getOffsets() const { return _offsets; } const Offsets& getOffsets() const { return _offsets; }