Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #ifndef __DEVICE_MEMORY_H__ 00020 #define __DEVICE_MEMORY_H__ 00021 00022 /* Device Memory 00023 * 00024 * This file defines data types that can be used in device memory arrays, and 00025 * a device_vector<T> type to store such arrays. 00026 * 00027 * device_vector<T> contains an STL vector, metadata about the data type, 00028 * dimensions, elements, and a device pointer. For the CPU device this is just 00029 * a pointer to the STL vector data, as no copying needs to take place. For 00030 * other devices this is a pointer to device memory, where we will copy memory 00031 * to and from. */ 00032 00033 #include "util_debug.h" 00034 #include "util_types.h" 00035 #include "util_vector.h" 00036 00037 CCL_NAMESPACE_BEGIN 00038 00039 enum MemoryType { 00040 MEM_READ_ONLY, 00041 MEM_WRITE_ONLY, 00042 MEM_READ_WRITE 00043 }; 00044 00045 /* Supported Data Types */ 00046 00047 enum DataType { 00048 TYPE_UCHAR, 00049 TYPE_UINT, 00050 TYPE_INT, 00051 TYPE_FLOAT 00052 }; 00053 00054 static inline size_t datatype_size(DataType datatype) 00055 { 00056 switch(datatype) { 00057 case TYPE_UCHAR: return sizeof(uchar); 00058 case TYPE_FLOAT: return sizeof(float); 00059 case TYPE_UINT: return sizeof(uint); 00060 case TYPE_INT: return sizeof(int); 00061 default: return 0; 00062 } 00063 } 00064 00065 /* Traits for data types */ 00066 00067 template<typename T> struct device_type_traits { 00068 static const DataType data_type = TYPE_UCHAR; 00069 static const int num_elements = 0; 00070 }; 00071 00072 template<> struct device_type_traits<uchar> { 00073 static const DataType data_type = TYPE_UCHAR; 00074 static const int num_elements = 1; 00075 }; 00076 00077 template<> struct device_type_traits<uchar2> { 00078 static const DataType data_type = TYPE_UCHAR; 00079 static const int num_elements = 2; 00080 }; 00081 00082 template<> struct device_type_traits<uchar3> { 00083 static const DataType data_type = TYPE_UCHAR; 00084 static const int num_elements = 3; 00085 }; 00086 00087 template<> struct device_type_traits<uchar4> { 00088 static const DataType data_type = TYPE_UCHAR; 00089 static const int num_elements = 4; 00090 }; 00091 00092 template<> struct device_type_traits<uint> { 00093 static const DataType data_type = TYPE_UINT; 00094 static const int num_elements = 1; 00095 }; 00096 00097 template<> struct device_type_traits<uint2> { 00098 static const DataType data_type = TYPE_UINT; 00099 static const int num_elements = 2; 00100 }; 00101 00102 template<> struct device_type_traits<uint3> { 00103 static const DataType data_type = TYPE_UINT; 00104 static const int num_elements = 3; 00105 }; 00106 00107 template<> struct device_type_traits<uint4> { 00108 static const DataType data_type = TYPE_UINT; 00109 static const int num_elements = 4; 00110 }; 00111 00112 template<> struct device_type_traits<int> { 00113 static const DataType data_type = TYPE_INT; 00114 static const int num_elements = 1; 00115 }; 00116 00117 template<> struct device_type_traits<int2> { 00118 static const DataType data_type = TYPE_INT; 00119 static const int num_elements = 2; 00120 }; 00121 00122 template<> struct device_type_traits<int3> { 00123 static const DataType data_type = TYPE_INT; 00124 static const int num_elements = 3; 00125 }; 00126 00127 template<> struct device_type_traits<int4> { 00128 static const DataType data_type = TYPE_INT; 00129 static const int num_elements = 4; 00130 }; 00131 00132 template<> struct device_type_traits<float> { 00133 static const DataType data_type = TYPE_FLOAT; 00134 static const int num_elements = 1; 00135 }; 00136 00137 template<> struct device_type_traits<float2> { 00138 static const DataType data_type = TYPE_FLOAT; 00139 static const int num_elements = 2; 00140 }; 00141 00142 template<> struct device_type_traits<float3> { 00143 static const DataType data_type = TYPE_FLOAT; 00144 static const int num_elements = 3; 00145 }; 00146 00147 template<> struct device_type_traits<float4> { 00148 static const DataType data_type = TYPE_FLOAT; 00149 static const int num_elements = 4; 00150 }; 00151 00152 /* Device Memory */ 00153 00154 class device_memory 00155 { 00156 public: 00157 size_t memory_size() { return data_size*data_elements*datatype_size(data_type); } 00158 00159 /* data information */ 00160 DataType data_type; 00161 int data_elements; 00162 device_ptr data_pointer; 00163 size_t data_size; 00164 size_t data_width; 00165 size_t data_height; 00166 00167 /* device pointer */ 00168 device_ptr device_pointer; 00169 00170 protected: 00171 device_memory() {} 00172 virtual ~device_memory() { assert(!device_pointer); } 00173 00174 /* no copying */ 00175 device_memory(const device_memory&); 00176 device_memory& operator = (const device_memory&); 00177 }; 00178 00179 /* Device Vector */ 00180 00181 template<typename T> class device_vector : public device_memory 00182 { 00183 public: 00184 device_vector() 00185 { 00186 data_type = device_type_traits<T>::data_type; 00187 data_elements = device_type_traits<T>::num_elements; 00188 data_pointer = 0; 00189 data_size = 0; 00190 data_width = 0; 00191 data_height = 0; 00192 00193 assert(data_elements > 0); 00194 00195 device_pointer = 0; 00196 } 00197 00198 virtual ~device_vector() {} 00199 00200 /* vector functions */ 00201 T *resize(size_t width, size_t height = 0) 00202 { 00203 data_size = (height == 0)? width: width*height; 00204 data.resize(data_size); 00205 data_pointer = (device_ptr)&data[0]; 00206 data_width = width; 00207 data_height = height; 00208 00209 return &data[0]; 00210 } 00211 00212 T *copy(T *ptr, size_t width, size_t height = 0) 00213 { 00214 T *mem = resize(width, height); 00215 memcpy(mem, ptr, memory_size()); 00216 return mem; 00217 } 00218 00219 void reference(T *ptr, size_t width, size_t height = 0) 00220 { 00221 data.clear(); 00222 data_size = (height == 0)? width: width*height; 00223 data_pointer = (device_ptr)ptr; 00224 data_width = width; 00225 data_height = height; 00226 } 00227 00228 void clear() 00229 { 00230 data.clear(); 00231 data_pointer = 0; 00232 data_width = 0; 00233 data_height = 0; 00234 data_size = 0; 00235 } 00236 00237 size_t size() 00238 { 00239 return data.size(); 00240 } 00241 00242 private: 00243 array<T> data; 00244 bool referenced; 00245 }; 00246 00247 CCL_NAMESPACE_END 00248 00249 #endif /* __DEVICE_MEMORY_H__ */ 00250