diff options
Diffstat (limited to 'thirdparty/embree/kernels/common/buffer.h')
| -rw-r--r-- | thirdparty/embree/kernels/common/buffer.h | 263 | 
1 files changed, 263 insertions, 0 deletions
diff --git a/thirdparty/embree/kernels/common/buffer.h b/thirdparty/embree/kernels/common/buffer.h new file mode 100644 index 0000000000..793012c04d --- /dev/null +++ b/thirdparty/embree/kernels/common/buffer.h @@ -0,0 +1,263 @@ +// Copyright 2009-2021 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>& 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<num); +      return ptr_ofs + i*stride; +    } + +    /*! returns the number of elements of the buffer */ +    __forceinline size_t size() const {  +      return num;  +    } + +    /*! returns the number of bytes of the buffer */ +    __forceinline size_t bytes() const {  +      return num*stride;  +    } +     +    /*! returns the buffer stride */ +    __forceinline unsigned getStride() const +    { +      assert(stride <= unsigned(inf)); +      return unsigned(stride); +    } + +    /*! return the buffer format */ +    __forceinline RTCFormat getFormat() const { +      return format; +    } + +    /*! mark buffer as modified or unmodified */ +    __forceinline void setModified() { +      modCounter++; +      modified = true; +    } + +    /*! mark buffer as modified or unmodified */ +    __forceinline bool isModified(unsigned int otherModCounter) const { +      return modCounter > 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> buffer; //!< reference to the parent buffer +  }; + +  /*! A typed contiguous range of a buffer. This class does not own the buffer content. */ +  template<typename T> +  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<num); return *(T*)(ptr_ofs + i*stride); } +    __forceinline const T& operator [](size_t i) const { assert(i<num); return *(T*)(ptr_ofs + i*stride); } +  }; + +  template<> +  class BufferView<Vec3fa> : 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<num); +      return Vec3fa(vfloat4::loadu((float*)(ptr_ofs + i*stride))); +    } +     +    /*! writes the i'th element */ +    __forceinline void store(size_t i, const Vec3fa& v) +    { +      assert(i<num); +      vfloat4::storeu((float*)(ptr_ofs + i*stride), (vfloat4)v); +    } +  }; +}  |