// Copyright 2009-2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "default.h" #include "device.h" namespace embree { /*! Implements an API data buffer object. This class may or may not own the data. */ class Buffer : public RefCount { public: /*! Buffer construction */ Buffer() : device(nullptr), ptr(nullptr), numBytes(0), shared(false) {} /*! Buffer construction */ Buffer(Device* device, size_t numBytes_in, void* ptr_in = nullptr) : device(device), numBytes(numBytes_in) { device->refInc(); if (ptr_in) { shared = true; ptr = (char*)ptr_in; } else { shared = false; alloc(); } } /*! Buffer destruction */ ~Buffer() { free(); device->refDec(); } /*! this class is not copyable */ private: Buffer(const Buffer& other) DELETED; // do not implement Buffer& operator =(const Buffer& other) DELETED; // do not implement public: /* inits and allocates the buffer */ void create(Device* device_in, size_t numBytes_in) { init(device_in, numBytes_in); alloc(); } /* inits the buffer */ void init(Device* device_in, size_t numBytes_in) { free(); device = device_in; ptr = nullptr; numBytes = numBytes_in; shared = false; } /*! sets shared buffer */ void set(Device* device_in, void* ptr_in, size_t numBytes_in) { free(); device = device_in; ptr = (char*)ptr_in; if (numBytes_in != (size_t)-1) numBytes = numBytes_in; shared = true; } /*! allocated buffer */ void alloc() { if (device) device->memoryMonitor(this->bytes(), false); size_t b = (this->bytes()+15) & ssize_t(-16); ptr = (char*)alignedMalloc(b,16); } /*! frees the buffer */ void free() { if (shared) return; alignedFree(ptr); if (device) device->memoryMonitor(-ssize_t(this->bytes()), true); ptr = nullptr; } /*! gets buffer pointer */ void* data() { /* report error if buffer is not existing */ if (!device) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer specified"); /* return buffer */ return ptr; } /*! returns pointer to first element */ __forceinline char* getPtr() const { return ptr; } /*! returns the number of bytes of the buffer */ __forceinline size_t bytes() const { return numBytes; } /*! returns true of the buffer is not empty */ __forceinline operator bool() const { return ptr; } public: Device* device; //!< device to report memory usage to char* ptr; //!< pointer to buffer data size_t numBytes; //!< number of bytes in the buffer bool shared; //!< set if memory is shared with application }; /*! An untyped contiguous range of a buffer. This class does not own the buffer content. */ class RawBufferView { public: /*! Buffer construction */ RawBufferView() : ptr_ofs(nullptr), stride(0), num(0), format(RTC_FORMAT_UNDEFINED), modCounter(1), modified(true), userData(0) {} public: /*! sets the buffer view */ void set(const Ref& buffer_in, size_t offset_in, size_t stride_in, size_t num_in, RTCFormat format_in) { if ((offset_in + stride_in * num_in) > (stride_in * buffer_in->numBytes)) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "buffer range out of bounds"); ptr_ofs = buffer_in->ptr + offset_in; stride = stride_in; num = num_in; format = format_in; modCounter++; modified = true; buffer = buffer_in; } /*! returns pointer to the first element */ __forceinline char* getPtr() const { return ptr_ofs; } /*! returns pointer to the i'th element */ __forceinline char* getPtr(size_t i) const { assert(i otherModCounter; } /*! mark buffer as modified or unmodified */ __forceinline bool isLocalModified() const { return modified; } /*! clear local modified flag */ __forceinline void clearLocalModified() { modified = false; } /*! returns true of the buffer is not empty */ __forceinline operator bool() const { return ptr_ofs; } /*! checks padding to 16 byte check, fails hard */ __forceinline void checkPadding16() const { if (ptr_ofs && num) volatile int MAYBE_UNUSED w = *((int*)getPtr(size()-1)+3); // FIXME: is failing hard avoidable? } public: char* ptr_ofs; //!< base pointer plus offset size_t stride; //!< stride of the buffer in bytes size_t num; //!< number of elements in the buffer RTCFormat format; //!< format of the buffer unsigned int modCounter; //!< version ID of this buffer bool modified; //!< local modified data int userData; //!< special data Ref buffer; //!< reference to the parent buffer }; /*! A typed contiguous range of a buffer. This class does not own the buffer content. */ template class BufferView : public RawBufferView { public: typedef T value_type; /*! access to the ith element of the buffer */ __forceinline T& operator [](size_t i) { assert(i class BufferView : public RawBufferView { public: typedef Vec3fa value_type; /*! access to the ith element of the buffer */ __forceinline const Vec3fa operator [](size_t i) const { assert(i