diff options
Diffstat (limited to 'intern/cycles/device/device_memory.h')
-rw-r--r-- | intern/cycles/device/device_memory.h | 678 |
1 files changed, 339 insertions, 339 deletions
diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h index e43834bdc8d..f50184efba7 100644 --- a/intern/cycles/device/device_memory.h +++ b/intern/cycles/device/device_memory.h @@ -31,152 +31,155 @@ CCL_NAMESPACE_BEGIN class Device; -enum MemoryType { - MEM_READ_ONLY, - MEM_READ_WRITE, - MEM_DEVICE_ONLY, - MEM_TEXTURE, - MEM_PIXELS -}; +enum MemoryType { MEM_READ_ONLY, MEM_READ_WRITE, MEM_DEVICE_ONLY, MEM_TEXTURE, MEM_PIXELS }; /* Supported Data Types */ enum DataType { - TYPE_UNKNOWN, - TYPE_UCHAR, - TYPE_UINT16, - TYPE_UINT, - TYPE_INT, - TYPE_FLOAT, - TYPE_HALF, - TYPE_UINT64, + TYPE_UNKNOWN, + TYPE_UCHAR, + TYPE_UINT16, + TYPE_UINT, + TYPE_INT, + TYPE_FLOAT, + TYPE_HALF, + TYPE_UINT64, }; static inline size_t datatype_size(DataType datatype) { - switch(datatype) { - case TYPE_UNKNOWN: return 1; - case TYPE_UCHAR: return sizeof(uchar); - case TYPE_FLOAT: return sizeof(float); - case TYPE_UINT: return sizeof(uint); - case TYPE_UINT16: return sizeof(uint16_t); - case TYPE_INT: return sizeof(int); - case TYPE_HALF: return sizeof(half); - case TYPE_UINT64: return sizeof(uint64_t); - default: return 0; - } + switch (datatype) { + case TYPE_UNKNOWN: + return 1; + case TYPE_UCHAR: + return sizeof(uchar); + case TYPE_FLOAT: + return sizeof(float); + case TYPE_UINT: + return sizeof(uint); + case TYPE_UINT16: + return sizeof(uint16_t); + case TYPE_INT: + return sizeof(int); + case TYPE_HALF: + return sizeof(half); + case TYPE_UINT64: + return sizeof(uint64_t); + default: + return 0; + } } /* Traits for data types */ template<typename T> struct device_type_traits { - static const DataType data_type = TYPE_UNKNOWN; - static const int num_elements = sizeof(T); + static const DataType data_type = TYPE_UNKNOWN; + static const int num_elements = sizeof(T); }; template<> struct device_type_traits<uchar> { - static const DataType data_type = TYPE_UCHAR; - static const int num_elements = 1; + static const DataType data_type = TYPE_UCHAR; + static const int num_elements = 1; }; template<> struct device_type_traits<uchar2> { - static const DataType data_type = TYPE_UCHAR; - static const int num_elements = 2; + static const DataType data_type = TYPE_UCHAR; + static const int num_elements = 2; }; template<> struct device_type_traits<uchar3> { - static const DataType data_type = TYPE_UCHAR; - static const int num_elements = 3; + static const DataType data_type = TYPE_UCHAR; + static const int num_elements = 3; }; template<> struct device_type_traits<uchar4> { - static const DataType data_type = TYPE_UCHAR; - static const int num_elements = 4; + static const DataType data_type = TYPE_UCHAR; + static const int num_elements = 4; }; template<> struct device_type_traits<uint> { - static const DataType data_type = TYPE_UINT; - static const int num_elements = 1; + static const DataType data_type = TYPE_UINT; + static const int num_elements = 1; }; template<> struct device_type_traits<uint2> { - static const DataType data_type = TYPE_UINT; - static const int num_elements = 2; + static const DataType data_type = TYPE_UINT; + static const int num_elements = 2; }; template<> struct device_type_traits<uint3> { - static const DataType data_type = TYPE_UINT; - static const int num_elements = 3; + static const DataType data_type = TYPE_UINT; + static const int num_elements = 3; }; template<> struct device_type_traits<uint4> { - static const DataType data_type = TYPE_UINT; - static const int num_elements = 4; + static const DataType data_type = TYPE_UINT; + static const int num_elements = 4; }; template<> struct device_type_traits<int> { - static const DataType data_type = TYPE_INT; - static const int num_elements = 1; + static const DataType data_type = TYPE_INT; + static const int num_elements = 1; }; template<> struct device_type_traits<int2> { - static const DataType data_type = TYPE_INT; - static const int num_elements = 2; + static const DataType data_type = TYPE_INT; + static const int num_elements = 2; }; template<> struct device_type_traits<int3> { - static const DataType data_type = TYPE_INT; - static const int num_elements = 3; + static const DataType data_type = TYPE_INT; + static const int num_elements = 3; }; template<> struct device_type_traits<int4> { - static const DataType data_type = TYPE_INT; - static const int num_elements = 4; + static const DataType data_type = TYPE_INT; + static const int num_elements = 4; }; template<> struct device_type_traits<float> { - static const DataType data_type = TYPE_FLOAT; - static const int num_elements = 1; + static const DataType data_type = TYPE_FLOAT; + static const int num_elements = 1; }; template<> struct device_type_traits<float2> { - static const DataType data_type = TYPE_FLOAT; - static const int num_elements = 2; + static const DataType data_type = TYPE_FLOAT; + static const int num_elements = 2; }; template<> struct device_type_traits<float3> { - static const DataType data_type = TYPE_FLOAT; - static const int num_elements = 4; + static const DataType data_type = TYPE_FLOAT; + static const int num_elements = 4; }; template<> struct device_type_traits<float4> { - static const DataType data_type = TYPE_FLOAT; - static const int num_elements = 4; + static const DataType data_type = TYPE_FLOAT; + static const int num_elements = 4; }; template<> struct device_type_traits<half> { - static const DataType data_type = TYPE_HALF; - static const int num_elements = 1; + static const DataType data_type = TYPE_HALF; + static const int num_elements = 1; }; template<> struct device_type_traits<ushort4> { - static const DataType data_type = TYPE_UINT16; - static const int num_elements = 4; + static const DataType data_type = TYPE_UINT16; + static const int num_elements = 4; }; template<> struct device_type_traits<uint16_t> { - static const DataType data_type = TYPE_UINT16; - static const int num_elements = 1; + static const DataType data_type = TYPE_UINT16; + static const int num_elements = 1; }; template<> struct device_type_traits<half4> { - static const DataType data_type = TYPE_HALF; - static const int num_elements = 4; + static const DataType data_type = TYPE_HALF; + static const int num_elements = 4; }; template<> struct device_type_traits<uint64_t> { - static const DataType data_type = TYPE_UINT64; - static const int num_elements = 1; + static const DataType data_type = TYPE_UINT64; + static const int num_elements = 1; }; /* Device Memory @@ -184,64 +187,67 @@ template<> struct device_type_traits<uint64_t> { * Base class for all device memory. This should not be allocated directly, * instead the appropriate subclass can be used. */ -class device_memory -{ -public: - size_t memory_size() { return data_size*data_elements*datatype_size(data_type); } - size_t memory_elements_size(int elements) { - return elements*data_elements*datatype_size(data_type); - } - - /* Data information. */ - DataType data_type; - int data_elements; - size_t data_size; - size_t device_size; - size_t data_width; - size_t data_height; - size_t data_depth; - MemoryType type; - const char *name; - InterpolationType interpolation; - ExtensionType extension; - - /* Pointers. */ - Device *device; - device_ptr device_pointer; - void *host_pointer; - void *shared_pointer; - - virtual ~device_memory(); - - void swap_device(Device *new_device, size_t new_device_size, device_ptr new_device_ptr); - void restore_device(); - -protected: - friend class CUDADevice; - - /* Only create through subclasses. */ - device_memory(Device *device, const char *name, MemoryType type); - - /* No copying allowed. */ - device_memory(const device_memory&); - device_memory& operator = (const device_memory&); - - /* Host allocation on the device. All host_pointer memory should be - * allocated with these functions, for devices that support using - * the same pointer for host and device. */ - void *host_alloc(size_t size); - void host_free(); - - /* Device memory allocation and copying. */ - void device_alloc(); - void device_free(); - void device_copy_to(); - void device_copy_from(int y, int w, int h, int elem); - void device_zero(); - - device_ptr original_device_ptr; - size_t original_device_size; - Device *original_device; +class device_memory { + public: + size_t memory_size() + { + return data_size * data_elements * datatype_size(data_type); + } + size_t memory_elements_size(int elements) + { + return elements * data_elements * datatype_size(data_type); + } + + /* Data information. */ + DataType data_type; + int data_elements; + size_t data_size; + size_t device_size; + size_t data_width; + size_t data_height; + size_t data_depth; + MemoryType type; + const char *name; + InterpolationType interpolation; + ExtensionType extension; + + /* Pointers. */ + Device *device; + device_ptr device_pointer; + void *host_pointer; + void *shared_pointer; + + virtual ~device_memory(); + + void swap_device(Device *new_device, size_t new_device_size, device_ptr new_device_ptr); + void restore_device(); + + protected: + friend class CUDADevice; + + /* Only create through subclasses. */ + device_memory(Device *device, const char *name, MemoryType type); + + /* No copying allowed. */ + device_memory(const device_memory &); + device_memory &operator=(const device_memory &); + + /* Host allocation on the device. All host_pointer memory should be + * allocated with these functions, for devices that support using + * the same pointer for host and device. */ + void *host_alloc(size_t size); + void host_free(); + + /* Device memory allocation and copying. */ + void device_alloc(); + void device_free(); + void device_copy_to(); + void device_copy_from(int y, int w, int h, int elem); + void device_zero(); + + device_ptr original_device_ptr; + size_t original_device_size; + Device *original_device; }; /* Device Only Memory @@ -249,51 +255,49 @@ protected: * Working memory only needed by the device, with no corresponding allocation * on the host. Only used internally in the device implementations. */ -template<typename T> -class device_only_memory : public device_memory -{ -public: - device_only_memory(Device *device, const char *name) - : device_memory(device, name, MEM_DEVICE_ONLY) - { - data_type = device_type_traits<T>::data_type; - data_elements = max(device_type_traits<T>::num_elements, 1); - } - - virtual ~device_only_memory() - { - free(); - } - - void alloc_to_device(size_t num, bool shrink_to_fit = true) - { - size_t new_size = num; - bool reallocate; - - if(shrink_to_fit) { - reallocate = (data_size != new_size); - } - else { - reallocate = (data_size < new_size); - } - - if(reallocate) { - device_free(); - data_size = new_size; - device_alloc(); - } - } - - void free() - { - device_free(); - data_size = 0; - } - - void zero_to_device() - { - device_zero(); - } +template<typename T> class device_only_memory : public device_memory { + public: + device_only_memory(Device *device, const char *name) + : device_memory(device, name, MEM_DEVICE_ONLY) + { + data_type = device_type_traits<T>::data_type; + data_elements = max(device_type_traits<T>::num_elements, 1); + } + + virtual ~device_only_memory() + { + free(); + } + + void alloc_to_device(size_t num, bool shrink_to_fit = true) + { + size_t new_size = num; + bool reallocate; + + if (shrink_to_fit) { + reallocate = (data_size != new_size); + } + else { + reallocate = (data_size < new_size); + } + + if (reallocate) { + device_free(); + data_size = new_size; + device_alloc(); + } + } + + void free() + { + device_free(); + data_size = 0; + } + + void zero_to_device() + { + device_zero(); + } }; /* Device Vector @@ -307,135 +311,134 @@ public: * automatically attached to kernel globals, using the provided name * matching an entry in kernel_textures.h. */ -template<typename T> class device_vector : public device_memory -{ -public: - device_vector(Device *device, const char *name, MemoryType type) - : device_memory(device, name, type) - { - data_type = device_type_traits<T>::data_type; - data_elements = device_type_traits<T>::num_elements; - - assert(data_elements > 0); - } - - virtual ~device_vector() - { - free(); - } - - /* Host memory allocation. */ - T *alloc(size_t width, size_t height = 0, size_t depth = 0) - { - size_t new_size = size(width, height, depth); - - if(new_size != data_size) { - device_free(); - host_free(); - host_pointer = host_alloc(sizeof(T)*new_size); - assert(device_pointer == 0); - } - - data_size = new_size; - data_width = width; - data_height = height; - data_depth = depth; - - return data(); - } - - /* Host memory resize. Only use this if the original data needs to be - * preserved, it is faster to call alloc() if it can be discarded. */ - T *resize(size_t width, size_t height = 0, size_t depth = 0) - { - size_t new_size = size(width, height, depth); - - if(new_size != data_size) { - void *new_ptr = host_alloc(sizeof(T)*new_size); - - if(new_size && data_size) { - size_t min_size = ((new_size < data_size)? new_size: data_size); - memcpy((T*)new_ptr, (T*)host_pointer, sizeof(T)*min_size); - } - - device_free(); - host_free(); - host_pointer = new_ptr; - assert(device_pointer == 0); - } - - data_size = new_size; - data_width = width; - data_height = height; - data_depth = depth; - - return data(); - } - - /* Take over data from an existing array. */ - void steal_data(array<T>& from) - { - device_free(); - host_free(); - - data_size = from.size(); - data_width = 0; - data_height = 0; - data_depth = 0; - host_pointer = from.steal_pointer(); - assert(device_pointer == 0); - } - - /* Free device and host memory. */ - void free() - { - device_free(); - host_free(); - - data_size = 0; - data_width = 0; - data_height = 0; - data_depth = 0; - host_pointer = 0; - assert(device_pointer == 0); - } - - size_t size() - { - return data_size; - } - - T* data() - { - return (T*)host_pointer; - } - - T& operator[](size_t i) - { - assert(i < data_size); - return data()[i]; - } - - void copy_to_device() - { - device_copy_to(); - } - - void copy_from_device(int y, int w, int h) - { - device_copy_from(y, w, h, sizeof(T)); - } - - void zero_to_device() - { - device_zero(); - } - -protected: - size_t size(size_t width, size_t height, size_t depth) - { - return width * ((height == 0)? 1: height) * ((depth == 0)? 1: depth); - } +template<typename T> class device_vector : public device_memory { + public: + device_vector(Device *device, const char *name, MemoryType type) + : device_memory(device, name, type) + { + data_type = device_type_traits<T>::data_type; + data_elements = device_type_traits<T>::num_elements; + + assert(data_elements > 0); + } + + virtual ~device_vector() + { + free(); + } + + /* Host memory allocation. */ + T *alloc(size_t width, size_t height = 0, size_t depth = 0) + { + size_t new_size = size(width, height, depth); + + if (new_size != data_size) { + device_free(); + host_free(); + host_pointer = host_alloc(sizeof(T) * new_size); + assert(device_pointer == 0); + } + + data_size = new_size; + data_width = width; + data_height = height; + data_depth = depth; + + return data(); + } + + /* Host memory resize. Only use this if the original data needs to be + * preserved, it is faster to call alloc() if it can be discarded. */ + T *resize(size_t width, size_t height = 0, size_t depth = 0) + { + size_t new_size = size(width, height, depth); + + if (new_size != data_size) { + void *new_ptr = host_alloc(sizeof(T) * new_size); + + if (new_size && data_size) { + size_t min_size = ((new_size < data_size) ? new_size : data_size); + memcpy((T *)new_ptr, (T *)host_pointer, sizeof(T) * min_size); + } + + device_free(); + host_free(); + host_pointer = new_ptr; + assert(device_pointer == 0); + } + + data_size = new_size; + data_width = width; + data_height = height; + data_depth = depth; + + return data(); + } + + /* Take over data from an existing array. */ + void steal_data(array<T> &from) + { + device_free(); + host_free(); + + data_size = from.size(); + data_width = 0; + data_height = 0; + data_depth = 0; + host_pointer = from.steal_pointer(); + assert(device_pointer == 0); + } + + /* Free device and host memory. */ + void free() + { + device_free(); + host_free(); + + data_size = 0; + data_width = 0; + data_height = 0; + data_depth = 0; + host_pointer = 0; + assert(device_pointer == 0); + } + + size_t size() + { + return data_size; + } + + T *data() + { + return (T *)host_pointer; + } + + T &operator[](size_t i) + { + assert(i < data_size); + return data()[i]; + } + + void copy_to_device() + { + device_copy_to(); + } + + void copy_from_device(int y, int w, int h) + { + device_copy_from(y, w, h, sizeof(T)); + } + + void zero_to_device() + { + device_zero(); + } + + protected: + size_t size(size_t width, size_t height, size_t depth) + { + return width * ((height == 0) ? 1 : height) * ((depth == 0) ? 1 : depth); + } }; /* Pixel Memory @@ -443,28 +446,26 @@ protected: * Device memory to efficiently draw as pixels to the screen in interactive * rendering. Only copying pixels from the device is supported, not copying to. */ -template<typename T> class device_pixels : public device_vector<T> -{ -public: - device_pixels(Device *device, const char *name) - : device_vector<T>(device, name, MEM_PIXELS) - { - } - - void alloc_to_device(size_t width, size_t height, size_t depth = 0) - { - device_vector<T>::alloc(width, height, depth); - - if(!device_memory::device_pointer) { - device_memory::device_alloc(); - } - } - - T *copy_from_device(int y, int w, int h) - { - device_memory::device_copy_from(y, w, h, sizeof(T)); - return device_vector<T>::data(); - } +template<typename T> class device_pixels : public device_vector<T> { + public: + device_pixels(Device *device, const char *name) : device_vector<T>(device, name, MEM_PIXELS) + { + } + + void alloc_to_device(size_t width, size_t height, size_t depth = 0) + { + device_vector<T>::alloc(width, height, depth); + + if (!device_memory::device_pointer) { + device_memory::device_alloc(); + } + } + + T *copy_from_device(int y, int w, int h) + { + device_memory::device_copy_from(y, w, h, sizeof(T)); + return device_vector<T>::data(); + } }; /* Device Sub Memory @@ -476,25 +477,24 @@ public: * Note: some devices require offset and size of the sub_ptr to be properly * aligned to device->mem_address_alingment(). */ -class device_sub_ptr -{ -public: - device_sub_ptr(device_memory& mem, int offset, int size); - ~device_sub_ptr(); +class device_sub_ptr { + public: + device_sub_ptr(device_memory &mem, int offset, int size); + ~device_sub_ptr(); - device_ptr operator*() const - { - return ptr; - } + device_ptr operator*() const + { + return ptr; + } -protected: - /* No copying. */ - device_sub_ptr& operator = (const device_sub_ptr&); + protected: + /* No copying. */ + device_sub_ptr &operator=(const device_sub_ptr &); - Device *device; - device_ptr ptr; + Device *device; + device_ptr ptr; }; CCL_NAMESPACE_END -#endif /* __DEVICE_MEMORY_H__ */ +#endif /* __DEVICE_MEMORY_H__ */ |