buffer.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "default.h"
  5. #include "device.h"
  6. namespace embree
  7. {
  8. /*! Implements an API data buffer object. This class may or may not own the data. */
  9. class Buffer : public RefCount
  10. {
  11. public:
  12. /*! Buffer construction */
  13. Buffer()
  14. : device(nullptr), ptr(nullptr), numBytes(0), shared(false) {}
  15. /*! Buffer construction */
  16. Buffer(Device* device, size_t numBytes_in, void* ptr_in = nullptr)
  17. : device(device), numBytes(numBytes_in)
  18. {
  19. device->refInc();
  20. if (ptr_in)
  21. {
  22. shared = true;
  23. ptr = (char*)ptr_in;
  24. }
  25. else
  26. {
  27. shared = false;
  28. alloc();
  29. }
  30. }
  31. /*! Buffer destruction */
  32. ~Buffer() {
  33. free();
  34. device->refDec();
  35. }
  36. /*! this class is not copyable */
  37. private:
  38. Buffer(const Buffer& other) DELETED; // do not implement
  39. Buffer& operator =(const Buffer& other) DELETED; // do not implement
  40. public:
  41. /* inits and allocates the buffer */
  42. void create(Device* device_in, size_t numBytes_in)
  43. {
  44. init(device_in, numBytes_in);
  45. alloc();
  46. }
  47. /* inits the buffer */
  48. void init(Device* device_in, size_t numBytes_in)
  49. {
  50. free();
  51. device = device_in;
  52. ptr = nullptr;
  53. numBytes = numBytes_in;
  54. shared = false;
  55. }
  56. /*! sets shared buffer */
  57. void set(Device* device_in, void* ptr_in, size_t numBytes_in)
  58. {
  59. free();
  60. device = device_in;
  61. ptr = (char*)ptr_in;
  62. if (numBytes_in != (size_t)-1)
  63. numBytes = numBytes_in;
  64. shared = true;
  65. }
  66. /*! allocated buffer */
  67. void alloc()
  68. {
  69. if (device)
  70. device->memoryMonitor(this->bytes(), false);
  71. size_t b = (this->bytes()+15) & ssize_t(-16);
  72. ptr = (char*)alignedMalloc(b,16);
  73. }
  74. /*! frees the buffer */
  75. void free()
  76. {
  77. if (shared) return;
  78. alignedFree(ptr);
  79. if (device)
  80. device->memoryMonitor(-ssize_t(this->bytes()), true);
  81. ptr = nullptr;
  82. }
  83. /*! gets buffer pointer */
  84. void* data()
  85. {
  86. /* report error if buffer is not existing */
  87. if (!device)
  88. throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer specified");
  89. /* return buffer */
  90. return ptr;
  91. }
  92. /*! returns pointer to first element */
  93. __forceinline char* getPtr() const {
  94. return ptr;
  95. }
  96. /*! returns the number of bytes of the buffer */
  97. __forceinline size_t bytes() const {
  98. return numBytes;
  99. }
  100. /*! returns true of the buffer is not empty */
  101. __forceinline operator bool() const {
  102. return ptr;
  103. }
  104. public:
  105. Device* device; //!< device to report memory usage to
  106. char* ptr; //!< pointer to buffer data
  107. size_t numBytes; //!< number of bytes in the buffer
  108. bool shared; //!< set if memory is shared with application
  109. };
  110. /*! An untyped contiguous range of a buffer. This class does not own the buffer content. */
  111. class RawBufferView
  112. {
  113. public:
  114. /*! Buffer construction */
  115. RawBufferView()
  116. : ptr_ofs(nullptr), stride(0), num(0), format(RTC_FORMAT_UNDEFINED), modCounter(1), modified(true), userData(0) {}
  117. public:
  118. /*! sets the buffer view */
  119. void set(const Ref<Buffer>& buffer_in, size_t offset_in, size_t stride_in, size_t num_in, RTCFormat format_in)
  120. {
  121. if ((offset_in + stride_in * num_in) > (stride_in * buffer_in->numBytes))
  122. throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "buffer range out of bounds");
  123. ptr_ofs = buffer_in->ptr + offset_in;
  124. stride = stride_in;
  125. num = num_in;
  126. format = format_in;
  127. modCounter++;
  128. modified = true;
  129. buffer = buffer_in;
  130. }
  131. /*! returns pointer to the first element */
  132. __forceinline char* getPtr() const {
  133. return ptr_ofs;
  134. }
  135. /*! returns pointer to the i'th element */
  136. __forceinline char* getPtr(size_t i) const
  137. {
  138. assert(i<num);
  139. return ptr_ofs + i*stride;
  140. }
  141. /*! returns the number of elements of the buffer */
  142. __forceinline size_t size() const {
  143. return num;
  144. }
  145. /*! returns the number of bytes of the buffer */
  146. __forceinline size_t bytes() const {
  147. return num*stride;
  148. }
  149. /*! returns the buffer stride */
  150. __forceinline unsigned getStride() const
  151. {
  152. assert(stride <= unsigned(inf));
  153. return unsigned(stride);
  154. }
  155. /*! return the buffer format */
  156. __forceinline RTCFormat getFormat() const {
  157. return format;
  158. }
  159. /*! mark buffer as modified or unmodified */
  160. __forceinline void setModified() {
  161. modCounter++;
  162. modified = true;
  163. }
  164. /*! mark buffer as modified or unmodified */
  165. __forceinline bool isModified(unsigned int otherModCounter) const {
  166. return modCounter > otherModCounter;
  167. }
  168. /*! mark buffer as modified or unmodified */
  169. __forceinline bool isLocalModified() const {
  170. return modified;
  171. }
  172. /*! clear local modified flag */
  173. __forceinline void clearLocalModified() {
  174. modified = false;
  175. }
  176. /*! returns true of the buffer is not empty */
  177. __forceinline operator bool() const {
  178. return ptr_ofs;
  179. }
  180. /*! checks padding to 16 byte check, fails hard */
  181. __forceinline void checkPadding16() const
  182. {
  183. if (ptr_ofs && num)
  184. volatile int MAYBE_UNUSED w = *((int*)getPtr(size()-1)+3); // FIXME: is failing hard avoidable?
  185. }
  186. public:
  187. char* ptr_ofs; //!< base pointer plus offset
  188. size_t stride; //!< stride of the buffer in bytes
  189. size_t num; //!< number of elements in the buffer
  190. RTCFormat format; //!< format of the buffer
  191. unsigned int modCounter; //!< version ID of this buffer
  192. bool modified; //!< local modified data
  193. int userData; //!< special data
  194. Ref<Buffer> buffer; //!< reference to the parent buffer
  195. };
  196. /*! A typed contiguous range of a buffer. This class does not own the buffer content. */
  197. template<typename T>
  198. class BufferView : public RawBufferView
  199. {
  200. public:
  201. typedef T value_type;
  202. /*! access to the ith element of the buffer */
  203. __forceinline T& operator [](size_t i) { assert(i<num); return *(T*)(ptr_ofs + i*stride); }
  204. __forceinline const T& operator [](size_t i) const { assert(i<num); return *(T*)(ptr_ofs + i*stride); }
  205. };
  206. template<>
  207. class BufferView<Vec3fa> : public RawBufferView
  208. {
  209. public:
  210. typedef Vec3fa value_type;
  211. /*! access to the ith element of the buffer */
  212. __forceinline const Vec3fa operator [](size_t i) const
  213. {
  214. assert(i<num);
  215. return Vec3fa(vfloat4::loadu((float*)(ptr_ofs + i*stride)));
  216. }
  217. /*! writes the i'th element */
  218. __forceinline void store(size_t i, const Vec3fa& v)
  219. {
  220. assert(i<num);
  221. vfloat4::storeu((float*)(ptr_ofs + i*stride), (vfloat4)v);
  222. }
  223. };
  224. }