Blender V2.61 - r43446

device_memory.h

Go to the documentation of this file.
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