1 module dcl.memory; 2 3 import std.traits; 4 5 import dcl.base; 6 import dcl.context; 7 import dcl.event; 8 import dcl.commandqueue; 9 10 /// 11 class CLMemory : CLObject 12 { 13 protected: 14 /// 15 this( cl_mem id ) 16 { 17 enforce( id !is null, new CLException( "can't create memobject with null id" ) ); 18 this.id = id; 19 20 _flags = parseFlags!Flag( flagMask ); 21 } 22 23 private Flag[] _flags; 24 25 public: 26 /// 27 cl_mem id; 28 29 /// 30 enum Type 31 { 32 BUFFER = CL_MEM_OBJECT_BUFFER, /// 33 IMAGE2D = CL_MEM_OBJECT_IMAGE2D, /// 34 IMAGE3D = CL_MEM_OBJECT_IMAGE3D, /// 35 IMAGE2D_ARRAY = CL_MEM_OBJECT_IMAGE2D_ARRAY, /// 36 IMAGE1D = CL_MEM_OBJECT_IMAGE1D, /// 37 IMAGE1D_ARRAY = CL_MEM_OBJECT_IMAGE1D_ARRAY, /// 38 IMAGE1D_BUFFER = CL_MEM_OBJECT_IMAGE1D_BUFFER, /// 39 } 40 41 /// 42 enum Flag 43 { 44 READ_WRITE = CL_MEM_READ_WRITE, /// `CL_MEM_READ_WRITE` 45 WRITE_ONLY = CL_MEM_WRITE_ONLY, /// `CL_MEM_WRITE_ONLY` 46 READ_ONLY = CL_MEM_READ_ONLY, /// `CL_MEM_READ_ONLY` 47 USE_HOST_PTR = CL_MEM_USE_HOST_PTR, /// `CL_MEM_USE_HOST_PTR` 48 ALLOC_HOST_PTR = CL_MEM_ALLOC_HOST_PTR, /// `CL_MEM_ALLOC_HOST_PTR` 49 COPY_HOST_PTR = CL_MEM_COPY_HOST_PTR /// `CL_MEM_COPY_HOST_PTR` 50 } 51 52 /// 53 const(Flag[]) flags() @property const { return _flags; } 54 55 /// 56 static CLMemory createBuffer( CLContext context, Flag[] flags, size_t size, void* host_ptr=null ) 57 { 58 auto id = checkCode!clCreateBuffer( context.id, buildFlags(flags), size, host_ptr ); 59 60 return new CLMemory( id ); 61 } 62 63 // TODO: Image 64 65 /// 66 void readTo( CLCommandQueue queue, void[] buffer, size_t offset=0, bool blocking=true, 67 CLEvent[] wait_list=[], CLEvent* event=null ) 68 { 69 enforce( type == Type.BUFFER ); // TODO: images 70 71 checkCallWL!clEnqueueReadBuffer( queue.id, id, 72 blocking, offset, 73 buffer.length, buffer.ptr, wait_list, event ); 74 } 75 76 /// 77 void[] read( CLCommandQueue queue, size_t size, size_t offset=0, bool blocking=true, 78 CLEvent[] wait_list=[], CLEvent* event=null ) 79 { 80 auto buffer = new void[](size); 81 readTo( queue, buffer, offset, blocking, wait_list, event ); 82 return buffer; 83 } 84 85 /// 86 void write( CLCommandQueue queue, void[] buffer, size_t offset=0, bool blocking=true, 87 CLEvent[] wait_list=[], CLEvent* event=null ) 88 { 89 assert( type == Type.BUFFER ); // TODO: images 90 91 checkCallWL!clEnqueueWriteBuffer( queue.id, id, 92 blocking, offset, 93 buffer.length, buffer.ptr, 94 wait_list, event ); 95 } 96 97 /// 98 static struct MemoryMap 99 { 100 /// 101 static struct Array { size_t len; void *ptr; } 102 103 CLMemory memory; 104 CLCommandQueue map_queue; 105 106 union { Array arr; void[] data; } 107 108 this( void* ptr, size_t len, CLMemory mem, CLCommandQueue mcq ) 109 { 110 arr.ptr = ptr; 111 arr.len = len; 112 memory = mem; 113 map_queue = mcq; 114 } 115 116 bool valid() const @property { return arr.ptr !is null; } 117 118 void unmap( CLCommandQueue queue=null, 119 CLEvent[] wait_list=[], CLEvent* event=null ) 120 { 121 if( arr.ptr is null ) return; 122 123 if( queue is null ) queue = map_queue; 124 checkCallWL!clEnqueueUnmapMemObject( queue.id, 125 memory.id, arr.ptr, 126 wait_list, event ); 127 128 arr.ptr = null; 129 } 130 } 131 132 enum MapFlag 133 { 134 READ = CL_MAP_READ, /// 135 WRITE = CL_MAP_WRITE, /// 136 READ_WRITE = READ | WRITE /// 137 } 138 139 // TODO: Image 140 141 MemoryMap mapBuffer( CLCommandQueue queue, 142 MapFlag mode=MapFlag.READ_WRITE, 143 size_t offset=0, size_t cb=0, 144 bool blocking=true, CLEvent[] wait_list=[], 145 CLEvent* event=null ) 146 { 147 if( cb == 0 ) cb = size; // dynamic property 148 149 auto ptr = checkCodeWL!clEnqueueMapBuffer( queue.id, 150 id, blocking, mode, offset, cb, 151 wait_list, event ); 152 153 return MemoryMap( ptr, cb, this, queue ); 154 } 155 156 enum string[] info_list = 157 [ 158 "cl_mem_object_type:Type type", 159 "cl_mem_flags flags:flagMask", 160 "size_t size", 161 "size_t offset", 162 "void* host_ptr", 163 "uint map_count", 164 "uint reference_count:refcount", 165 "cl_context:CLContext context", 166 ]; 167 168 mixin( infoMixin( "mem_object", "mem", info_list ) ); 169 170 protected: 171 override void selfDestroy() { checkCall!clReleaseMemObject(id); } 172 }