buffer.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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. device->memoryMonitor(this->bytes(), false);
  70. size_t b = (this->bytes()+15) & ssize_t(-16);
  71. ptr = (char*)device->malloc(b,16);
  72. }
  73. /*! frees the buffer */
  74. void free()
  75. {
  76. if (shared) return;
  77. device->free(ptr);
  78. device->memoryMonitor(-ssize_t(this->bytes()), true);
  79. ptr = nullptr;
  80. }
  81. /*! gets buffer pointer */
  82. void* data()
  83. {
  84. /* report error if buffer is not existing */
  85. if (!device)
  86. throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer specified");
  87. /* return buffer */
  88. return ptr;
  89. }
  90. /*! returns pointer to first element */
  91. __forceinline char* getPtr() const {
  92. return ptr;
  93. }
  94. /*! returns the number of bytes of the buffer */
  95. __forceinline size_t bytes() const {
  96. return numBytes;
  97. }
  98. /*! returns true of the buffer is not empty */
  99. __forceinline operator bool() const {
  100. return ptr;
  101. }
  102. public:
  103. Device* device; //!< device to report memory usage to
  104. char* ptr; //!< pointer to buffer data
  105. size_t numBytes; //!< number of bytes in the buffer
  106. bool shared; //!< set if memory is shared with application
  107. };
  108. /*! An untyped contiguous range of a buffer. This class does not own the buffer content. */
  109. class RawBufferView
  110. {
  111. public:
  112. /*! Buffer construction */
  113. RawBufferView()
  114. : ptr_ofs(nullptr), stride(0), num(0), format(RTC_FORMAT_UNDEFINED), modCounter(1), modified(true), userData(0) {}
  115. public:
  116. /*! sets the buffer view */
  117. void set(const Ref<Buffer>& buffer_in, size_t offset_in, size_t stride_in, size_t num_in, RTCFormat format_in)
  118. {
  119. if ((offset_in + stride_in * num_in) > (stride_in * buffer_in->numBytes))
  120. throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "buffer range out of bounds");
  121. ptr_ofs = buffer_in->ptr + offset_in;
  122. stride = stride_in;
  123. num = num_in;
  124. format = format_in;
  125. modCounter++;
  126. modified = true;
  127. buffer = buffer_in;
  128. }
  129. /*! returns pointer to the first element */
  130. __forceinline char* getPtr() const {
  131. return ptr_ofs;
  132. }
  133. /*! returns pointer to the i'th element */
  134. __forceinline char* getPtr(size_t i) const
  135. {
  136. assert(i<num);
  137. return ptr_ofs + i*stride;
  138. }
  139. /*! returns the number of elements of the buffer */
  140. __forceinline size_t size() const {
  141. return num;
  142. }
  143. /*! returns the number of bytes of the buffer */
  144. __forceinline size_t bytes() const {
  145. return num*stride;
  146. }
  147. /*! returns the buffer stride */
  148. __forceinline unsigned getStride() const
  149. {
  150. assert(stride <= unsigned(inf));
  151. return unsigned(stride);
  152. }
  153. /*! return the buffer format */
  154. __forceinline RTCFormat getFormat() const {
  155. return format;
  156. }
  157. /*! mark buffer as modified or unmodified */
  158. __forceinline void setModified() {
  159. modCounter++;
  160. modified = true;
  161. }
  162. /*! mark buffer as modified or unmodified */
  163. __forceinline bool isModified(unsigned int otherModCounter) const {
  164. return modCounter > otherModCounter;
  165. }
  166. /*! mark buffer as modified or unmodified */
  167. __forceinline bool isLocalModified() const {
  168. return modified;
  169. }
  170. /*! clear local modified flag */
  171. __forceinline void clearLocalModified() {
  172. modified = false;
  173. }
  174. /*! returns true of the buffer is not empty */
  175. __forceinline operator bool() const {
  176. return ptr_ofs;
  177. }
  178. /*! checks padding to 16 byte check, fails hard */
  179. __forceinline void checkPadding16() const
  180. {
  181. if (ptr_ofs && num)
  182. volatile int MAYBE_UNUSED w = *((int*)getPtr(size()-1)+3); // FIXME: is failing hard avoidable?
  183. }
  184. public:
  185. char* ptr_ofs; //!< base pointer plus offset
  186. size_t stride; //!< stride of the buffer in bytes
  187. size_t num; //!< number of elements in the buffer
  188. RTCFormat format; //!< format of the buffer
  189. unsigned int modCounter; //!< version ID of this buffer
  190. bool modified; //!< local modified data
  191. int userData; //!< special data
  192. Ref<Buffer> buffer; //!< reference to the parent buffer
  193. };
  194. /*! A typed contiguous range of a buffer. This class does not own the buffer content. */
  195. template<typename T>
  196. class BufferView : public RawBufferView
  197. {
  198. public:
  199. typedef T value_type;
  200. /*! access to the ith element of the buffer */
  201. __forceinline T& operator [](size_t i) { assert(i<num); return *(T*)(ptr_ofs + i*stride); }
  202. __forceinline const T& operator [](size_t i) const { assert(i<num); return *(T*)(ptr_ofs + i*stride); }
  203. };
  204. template<>
  205. class BufferView<Vec3fa> : public RawBufferView
  206. {
  207. public:
  208. typedef Vec3fa value_type;
  209. #if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
  210. /*! access to the ith element of the buffer */
  211. __forceinline const Vec3fa operator [](size_t i) const
  212. {
  213. assert(i<num);
  214. return Vec3fa::loadu(ptr_ofs + i*stride);
  215. }
  216. /*! writes the i'th element */
  217. __forceinline void store(size_t i, const Vec3fa& v)
  218. {
  219. assert(i<num);
  220. Vec3fa::storeu(ptr_ofs + i*stride, v);
  221. }
  222. #else
  223. /*! access to the ith element of the buffer */
  224. __forceinline const Vec3fa operator [](size_t i) const
  225. {
  226. assert(i<num);
  227. return Vec3fa(vfloat4::loadu((float*)(ptr_ofs + i*stride)));
  228. }
  229. /*! writes the i'th element */
  230. __forceinline void store(size_t i, const Vec3fa& v)
  231. {
  232. assert(i<num);
  233. vfloat4::storeu((float*)(ptr_ofs + i*stride), (vfloat4)v);
  234. }
  235. #endif
  236. };
  237. }