diff options
Diffstat (limited to 'intern/cycles/device/memory.cpp')
-rw-r--r-- | intern/cycles/device/memory.cpp | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/intern/cycles/device/memory.cpp b/intern/cycles/device/memory.cpp new file mode 100644 index 00000000000..f162b00d9f7 --- /dev/null +++ b/intern/cycles/device/memory.cpp @@ -0,0 +1,285 @@ +/* + * Copyright 2011-2017 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "device/memory.h" +#include "device/device.h" + +CCL_NAMESPACE_BEGIN + +/* Device Memory */ + +device_memory::device_memory(Device *device, const char *name, MemoryType type) + : data_type(device_type_traits<uchar>::data_type), + data_elements(device_type_traits<uchar>::num_elements_cpu), + data_size(0), + device_size(0), + data_width(0), + data_height(0), + data_depth(0), + type(type), + name(name), + device(device), + device_pointer(0), + host_pointer(0), + shared_pointer(0), + shared_counter(0), + original_device_ptr(0), + original_device_size(0), + original_device(0), + need_realloc_(false), + modified(false) +{ +} + +device_memory::device_memory(device_memory &&other) noexcept + : data_type(other.data_type), + data_elements(other.data_elements), + data_size(other.data_size), + device_size(other.device_size), + data_width(other.data_width), + data_height(other.data_height), + data_depth(other.data_depth), + type(other.type), + name(other.name), + device(other.device), + device_pointer(other.device_pointer), + host_pointer(other.host_pointer), + shared_pointer(other.shared_pointer), + shared_counter(other.shared_counter), + original_device_ptr(other.original_device_ptr), + original_device_size(other.original_device_size), + original_device(other.original_device), + need_realloc_(other.need_realloc_), + modified(other.modified) +{ + other.data_elements = 0; + other.data_size = 0; + other.device_size = 0; + other.data_width = 0; + other.data_height = 0; + other.data_depth = 0; + other.device = 0; + other.device_pointer = 0; + other.host_pointer = 0; + other.shared_pointer = 0; + other.shared_counter = 0; + other.original_device_ptr = 0; + other.original_device_size = 0; + other.original_device = 0; + other.need_realloc_ = false; + other.modified = false; +} + +device_memory::~device_memory() +{ + assert(shared_pointer == 0); + assert(shared_counter == 0); +} + +void *device_memory::host_alloc(size_t size) +{ + if (!size) { + return 0; + } + + void *ptr = util_aligned_malloc(size, MIN_ALIGNMENT_CPU_DATA_TYPES); + + if (ptr) { + util_guarded_mem_alloc(size); + } + else { + throw std::bad_alloc(); + } + + return ptr; +} + +void device_memory::host_free() +{ + if (host_pointer) { + util_guarded_mem_free(memory_size()); + util_aligned_free((void *)host_pointer); + host_pointer = 0; + } +} + +void device_memory::device_alloc() +{ + assert(!device_pointer && type != MEM_TEXTURE && type != MEM_GLOBAL); + device->mem_alloc(*this); +} + +void device_memory::device_free() +{ + if (device_pointer) { + device->mem_free(*this); + } +} + +void device_memory::device_copy_to() +{ + if (host_pointer) { + device->mem_copy_to(*this); + } +} + +void device_memory::device_copy_from(size_t y, size_t w, size_t h, size_t elem) +{ + assert(type != MEM_TEXTURE && type != MEM_READ_ONLY && type != MEM_GLOBAL); + device->mem_copy_from(*this, y, w, h, elem); +} + +void device_memory::device_zero() +{ + if (data_size) { + device->mem_zero(*this); + } +} + +bool device_memory::device_is_cpu() +{ + return (device->info.type == DEVICE_CPU); +} + +void device_memory::swap_device(Device *new_device, + size_t new_device_size, + device_ptr new_device_ptr) +{ + original_device = device; + original_device_size = device_size; + original_device_ptr = device_pointer; + + device = new_device; + device_size = new_device_size; + device_pointer = new_device_ptr; +} + +void device_memory::restore_device() +{ + device = original_device; + device_size = original_device_size; + device_pointer = original_device_ptr; +} + +bool device_memory::is_resident(Device *sub_device) const +{ + return device->is_resident(device_pointer, sub_device); +} + +/* Device Sub Ptr */ + +device_sub_ptr::device_sub_ptr(device_memory &mem, size_t offset, size_t size) : device(mem.device) +{ + ptr = device->mem_alloc_sub_ptr(mem, offset, size); +} + +device_sub_ptr::~device_sub_ptr() +{ + device->mem_free_sub_ptr(ptr); +} + +/* Device Texture */ + +device_texture::device_texture(Device *device, + const char *name, + const uint slot, + ImageDataType image_data_type, + InterpolationType interpolation, + ExtensionType extension) + : device_memory(device, name, MEM_TEXTURE), slot(slot) +{ + switch (image_data_type) { + case IMAGE_DATA_TYPE_FLOAT4: + data_type = TYPE_FLOAT; + data_elements = 4; + break; + case IMAGE_DATA_TYPE_FLOAT: + data_type = TYPE_FLOAT; + data_elements = 1; + break; + case IMAGE_DATA_TYPE_BYTE4: + data_type = TYPE_UCHAR; + data_elements = 4; + break; + case IMAGE_DATA_TYPE_BYTE: + case IMAGE_DATA_TYPE_NANOVDB_FLOAT: + case IMAGE_DATA_TYPE_NANOVDB_FLOAT3: + data_type = TYPE_UCHAR; + data_elements = 1; + break; + case IMAGE_DATA_TYPE_HALF4: + data_type = TYPE_HALF; + data_elements = 4; + break; + case IMAGE_DATA_TYPE_HALF: + data_type = TYPE_HALF; + data_elements = 1; + break; + case IMAGE_DATA_TYPE_USHORT4: + data_type = TYPE_UINT16; + data_elements = 4; + break; + case IMAGE_DATA_TYPE_USHORT: + data_type = TYPE_UINT16; + data_elements = 1; + break; + case IMAGE_DATA_NUM_TYPES: + assert(0); + return; + } + + memset(&info, 0, sizeof(info)); + info.data_type = image_data_type; + info.interpolation = interpolation; + info.extension = extension; +} + +device_texture::~device_texture() +{ + device_free(); + host_free(); +} + +/* Host memory allocation. */ +void *device_texture::alloc(const size_t width, const size_t height, const size_t depth) +{ + const size_t new_size = size(width, height, depth); + + if (new_size != data_size) { + device_free(); + host_free(); + host_pointer = host_alloc(data_elements * datatype_size(data_type) * new_size); + assert(device_pointer == 0); + } + + data_size = new_size; + data_width = width; + data_height = height; + data_depth = depth; + + info.width = width; + info.height = height; + info.depth = depth; + + return host_pointer; +} + +void device_texture::copy_to_device() +{ + device_copy_to(); +} + +CCL_NAMESPACE_END |