1 module dcompute.driver.ocl.queue; 2 3 import dcompute.driver.ocl; 4 import dcompute.driver.util; 5 import std.typecons; 6 7 enum MapBufferFlags 8 { 9 read = 1 << 0, 10 write = 1 << 1, 11 writeInvaildateRegion = 1 << 2, 12 } 13 14 enum MemoryMigrationFlags 15 { 16 host = 1 << 0, 17 contentUndefined = 1 << 1, 18 } 19 20 struct Queue 21 { 22 cl_command_queue raw; 23 // constructed from context 24 25 enum Properties 26 { 27 outOfOrderExecution = 1 << 0, 28 profiling = 1 << 1 29 } 30 static struct Info 31 { 32 @(0x1090) Context context; 33 @(0x1091) Device device; 34 @(0x1092) uint referenceCount; 35 @(0x1093) Properties properties; 36 } 37 38 //mixin(generateGetInfo!(Info,clGetCommandQueueInfo)); 39 40 void retain() 41 { 42 status = cast(Status)clRetainCommandQueue(raw); 43 checkErrors(); 44 } 45 46 void release() 47 { 48 status = cast(Status)clReleaseCommandQueue(raw); 49 checkErrors(); 50 } 51 52 Event write(T)(Buffer!T buffer, T[] data, 53 Flag!"Blocking" blocking = Yes.Blocking, 54 size_t offset = 0, const Event[] waitList = null) 55 { 56 Event ret; 57 status = clEnqueueWriteBuffer(queue, buffer, blocking, offset, 58 data.memSize, data.ptr, 59 cast(uint)waitList.length, waitList.ptr, 60 &ret.raw); 61 checkErrors(); 62 return ret; 63 64 } 65 66 Event read(T)(Buffer!T buffer, T[] data, 67 Flag!"Blocking" blocking = Yes.Blocking, 68 size_t offset = 0, const Event[] waitList = null) 69 { 70 Event ret; 71 status = clEnqueueReadBuffer(queue, buffer, blocking, offset, 72 data.memSize, data.ptr, 73 cast(uint)waitList.length, waitList.ptr, 74 &ret.raw); 75 checkErrors(); 76 return ret; 77 } 78 79 auto enqueue(alias k)(const size_t[] globalWorkSize, 80 const size_t[] globalWorkOffset = null, const size_t[] localWorkSize = null, 81 const Event[] waitList = null) 82 in 83 { 84 if(globalWorkOffset) 85 assert(globalWorkSize.length == globalWorkOffset.length); 86 if(localWorkSize) 87 assert(globalWorkSize.length == localWorkSize.length); 88 } 89 body 90 { 91 static struct Call 92 { 93 Queue q; 94 const size_t[] globalWorkSize, globalWorkOffset,localWorkSize; 95 const Event[] waitList; 96 this(Queue _q,const size_t[] a, const size_t[] b, const size_t[] c, const Event[] d) 97 { 98 q = _q; 99 globalWorkSize = a; 100 globalWorkOffset = b; 101 localWorkSize = c; 102 waitList = d; 103 } 104 Event opCall(HostArgsOf!(typeof(k)) args) 105 { 106 auto kernel = Program.globalProgram.getKernel!k(); 107 foreach(uint i, a; args) 108 { 109 kernel.setArg(i,a); 110 } 111 Event e; 112 clEnqueueNDRangeKernel(q.raw, kernel.raw, 113 cast(uint)globalWorkSize.length, 114 globalWorkOffset.ptr, globalWorkSize.ptr, localWorkSize.ptr, 115 cast(uint)waitList.length, cast(cl_event*)waitList.ptr, 116 &e.raw); 117 kernel.release(); 118 return e; 119 } 120 } 121 122 return Call(this,globalWorkSize,globalWorkOffset,localWorkSize,waitList); 123 } 124 125 Queue flush() 126 { 127 clFlush(this.raw); 128 return this; 129 } 130 131 Queue finish() 132 { 133 clFinish(this.raw); 134 return this; 135 } 136 //TODO: fill, copy, marker, barrier [, rectFill, rect Copy] 137 138 139 }