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 }