9 #ifndef hifi_gpu_Buffer_h
10 #define hifi_gpu_Buffer_h
15 #include <QtCore/QDebug>
16 #include "GPULogging.h"
23 #include "PageManager.h"
28 static ContextMetricCount _bufferCPUCount;
29 static ContextMetricSize _bufferCPUMemSize;
31 using Flag = PageManager::Flag;
35 Update(
const Buffer& buffer);
36 Update(
const Update& other);
37 Update(Update&& other);
44 PageManager::Pages dirtyPages;
45 std::vector<uint8> dirtyData;
48 static uint32_t getBufferCPUCount();
49 static Size getBufferCPUMemSize();
51 Buffer(Size pageSize = PageManager::DEFAULT_PAGE_SIZE);
52 Buffer(Size size,
const Byte* bytes, Size pageSize = PageManager::DEFAULT_PAGE_SIZE);
53 Buffer(
const Buffer& buf);
54 Buffer& operator=(
const Buffer& buf);
58 Size getSize()
const override;
60 Size getNumTypedElements()
const {
return getSize() /
sizeof(T); };
62 const Byte* getData()
const {
return getSysmem().readData(); }
66 Size resize(Size pSize);
70 Size setData(Size size,
const Byte* data);
74 Size setSubData(Size offset, Size size,
const Byte* data);
77 Size setSubData(Size index,
const T& t) {
78 Size offset = index *
sizeof(T);
79 Size size =
sizeof(T);
80 return setSubData(offset, size,
reinterpret_cast<const Byte*
>(&t));
84 Size setSubData(Size index,
const std::vector<T>& t) {
88 Size offset = index *
sizeof(T);
89 Size size = t.size() *
sizeof(T);
90 return setSubData(offset, size,
reinterpret_cast<const Byte*
>(&t[0]));
96 Size append(Size size,
const Byte* data);
99 Size append(
const T& t) {
100 return append(
sizeof(t),
reinterpret_cast<const Byte*
>(&t));
103 template <
typename T>
104 Size append(
const std::vector<T>& t) {
108 return append(
sizeof(T) * t.size(),
reinterpret_cast<const Byte*
>(&t[0]));
112 const GPUObjectPointer gpuObject {};
115 const Sysmem& getSysmem()
const {
return _sysmem; }
117 bool isDirty()
const {
118 return _pages(PageManager::DIRTY);
121 void applyUpdate(
const Update& update);
124 Update getUpdate()
const;
132 mutable PageManager _renderPages;
133 mutable Sysmem _renderSysmem;
135 mutable std::atomic<size_t> _getUpdateCount { 0 };
136 mutable std::atomic<size_t> _applyUpdateCount { 0 };
138 void markDirty(Size offset, Size bytes);
140 template <
typename T>
141 void markDirty(Size index, Size count = 1) {
142 markDirty(
sizeof(T) * index,
sizeof(T) * count);
145 Sysmem& editSysmem() {
return _sysmem; }
146 Byte* editData() {
return editSysmem().editData(); }
148 mutable PageManager _pages;
152 friend class Serializer;
153 friend class Deserializer;
154 friend class BufferView;
159 friend class gl::GLBackend;
160 friend class gl::GLBuffer;
161 friend class gl41::GL41Buffer;
162 friend class gl45::GL45Buffer;
163 friend class gles::GLESBuffer;
166 using BufferUpdates = std::vector<Buffer::Update>;
168 typedef std::shared_ptr<Buffer> BufferPointer;
169 typedef std::vector< BufferPointer > Buffers;
174 static const Resource::Size DEFAULT_OFFSET{ 0 };
175 static const Element DEFAULT_ELEMENT;
178 using Size = Resource::Size;
179 using Index = int32_t;
181 BufferPointer _buffer;
184 Element _element { DEFAULT_ELEMENT };
185 uint16 _stride { 0 };
187 BufferView(
const BufferView& view) =
default;
188 BufferView& operator=(
const BufferView& view) =
default;
191 BufferView(
const Element& element);
192 BufferView(Buffer* newBuffer,
const Element& element = DEFAULT_ELEMENT);
193 BufferView(
const BufferPointer& buffer,
const Element& element = DEFAULT_ELEMENT);
194 BufferView(
const BufferPointer& buffer, Size offset, Size size,
const Element& element = DEFAULT_ELEMENT);
195 BufferView(
const BufferPointer& buffer, Size offset, Size size, uint16 stride,
const Element& element = DEFAULT_ELEMENT);
197 Size getNumElements()
const {
return _size / _stride; }
201 class Iterator :
public std::iterator<std::random_access_iterator_tag, T, Index, T*, T&>
205 Iterator(T* ptr = NULL,
int stride =
sizeof(T)): _ptr(ptr), _stride(stride) { }
206 Iterator(
const Iterator<T>& iterator) =
default;
209 Iterator<T>& operator=(
const Iterator<T>& iterator) =
default;
210 Iterator<T>& operator=(T* ptr) {
216 operator bool()
const
224 bool operator==(
const Iterator<T>& iterator)
const {
return (_ptr == iterator.getConstPtr()); }
225 bool operator!=(
const Iterator<T>& iterator)
const {
return (_ptr != iterator.getConstPtr()); }
226 bool operator<(
const Iterator<T>& iterator)
const {
return (_ptr < iterator.getConstPtr()); }
227 bool operator>(
const Iterator<T>& iterator)
const {
return (_ptr > iterator.getConstPtr()); }
229 void movePtr(
const Index& movement) {
230 auto byteptr = ((Byte*)_ptr);
231 byteptr += _stride * movement;
235 Iterator<T>& operator+=(
const Index& movement) {
239 Iterator<T>& operator-=(
const Index& movement) {
243 Iterator<T>& operator++() {
247 Iterator<T>& operator--() {
251 Iterator<T> operator++(Index) {
256 Iterator<T> operator--(Index) {
261 Iterator<T> operator+(
const Index& movement) {
268 Iterator<T> operator-(
const Index& movement) {
276 Index operator-(
const Iterator<T>& iterator) {
return (iterator.getPtr() - this->getPtr())/
sizeof(T); }
278 T& operator*(){
return *_ptr;}
279 const T& operator*()
const{
return *_ptr;}
280 T* operator->(){
return _ptr;}
282 T* getPtr()
const{
return _ptr;}
283 const T* getConstPtr()
const{
return _ptr;}
293 template <
typename T> Iterator<T> begin() {
return Iterator<T>(&edit<T>(0), _stride); }
294 template <
typename T> Iterator<T> end() {
return Iterator<T>(&edit<T>(getNum<T>()), _stride); }
296 template <
typename T> Iterator<const T> begin()
const {
return Iterator<const T>(&get<T>(), _stride); }
297 template <
typename T> Iterator<const T> end()
const {
299 Resource::Size elementOffset = getNum<T>() * _stride + _offset;
300 return Iterator<const T>((
reinterpret_cast<const T*
> (_buffer->getData() + elementOffset)), _stride);
303 template <
typename T> Iterator<const T> cbegin()
const {
return Iterator<const T>(&get<T>(), _stride); }
304 template <
typename T> Iterator<const T> cend()
const {
306 Resource::Size elementOffset = getNum<T>() * _stride + _offset;
307 return Iterator<const T>((
reinterpret_cast<const T*
> (_buffer->getData() + elementOffset)), _stride);
311 template <
typename T> Index getNum()
const {
312 return Index(_size / _stride);
315 template <
typename T>
const T& get()
const {
318 qCDebug(gpulogging) <<
"Accessing null gpu::buffer!";
320 if (
sizeof(T) > (_buffer->getSize() - _offset)) {
321 qCDebug(gpulogging) <<
"Accessing buffer in non allocated memory, element size = " <<
sizeof(T) <<
" available space in buffer at offset is = " << (_buffer->getSize() - _offset);
323 if (
sizeof(T) > _size) {
324 qCDebug(gpulogging) <<
"Accessing buffer outside the BufferView range, element size = " <<
sizeof(T) <<
" when bufferView size = " << _size;
327 const T* t = (
reinterpret_cast<const T*
> (_buffer->getData() + _offset));
331 template <
typename T> T& edit() {
334 qCDebug(gpulogging) <<
"Accessing null gpu::buffer!";
336 if (
sizeof(T) > (_buffer->getSize() - _offset)) {
337 qCDebug(gpulogging) <<
"Accessing buffer in non allocated memory, element size = " <<
sizeof(T) <<
" available space in buffer at offset is = " << (_buffer->getSize() - _offset);
339 if (
sizeof(T) > _size) {
340 qCDebug(gpulogging) <<
"Accessing buffer outside the BufferView range, element size = " <<
sizeof(T) <<
" when bufferView size = " << _size;
343 _buffer->markDirty(_offset,
sizeof(T));
344 T* t = (
reinterpret_cast<T*
> (_buffer->editData() + _offset));
348 template <
typename T>
const T& get(
const Index index)
const {
349 Resource::Size elementOffset = index * _stride + _offset;
352 qCDebug(gpulogging) <<
"Accessing null gpu::buffer!";
354 if (
sizeof(T) > (_buffer->getSize() - elementOffset)) {
355 qCDebug(gpulogging) <<
"Accessing buffer in non allocated memory, index = " << index <<
", element size = " <<
sizeof(T) <<
" available space in buffer at offset is = " << (_buffer->getSize() - elementOffset);
357 if (index > getNum<T>()) {
358 qCDebug(gpulogging) <<
"Accessing buffer outside the BufferView range, index = " << index <<
" number elements = " << getNum<T>();
361 return *(
reinterpret_cast<const T*
> (_buffer->getData() + elementOffset));
364 template <
typename T> T& edit(
const Index index)
const {
365 Resource::Size elementOffset = index * _stride + _offset;
368 qCDebug(gpulogging) <<
"Accessing null gpu::buffer!";
370 if (
sizeof(T) > (_buffer->getSize() - elementOffset)) {
371 qCDebug(gpulogging) <<
"Accessing buffer in non allocated memory, index = " << index <<
", element size = " <<
sizeof(T) <<
" available space in buffer at offset is = " << (_buffer->getSize() - elementOffset);
373 if (index > getNum<T>()) {
374 qCDebug(gpulogging) <<
"Accessing buffer outside the BufferView range, index = " << index <<
" number elements = " << getNum<T>();
377 _buffer->markDirty(elementOffset,
sizeof(T));
378 return *(
reinterpret_cast<T*
> (_buffer->editData() + elementOffset));
383 template <
class T>
class StructBuffer :
public gpu::BufferView {
386 template <
class U>
static BufferPointer makeBuffer() {
388 return std::make_shared<gpu::Buffer>(
sizeof(U), (
const gpu::Byte*) &t,
sizeof(U));
391 StructBuffer() : gpu::BufferView(makeBuffer<T>()) {}
395 return BufferView::edit<T>(0);
397 const T& get()
const {
398 return BufferView::get<T>(0);
400 const T* operator ->()
const {
return &get(); }
Base class for resources.
Definition: ResourceCache.h:409