1 module dcompute.driver.ocl.context;
2 
3 import dcompute.driver.ocl;
4 import std.typecons;
5 
6 import std.experimental.allocator.typed;
7 
8 struct Context
9 {
10     cl_context raw;
11     
12     enum Properties
13     {
14         platform        = 0x1084,
15         interopUserSync = 0x1085,
16     }
17     
18     static struct Info
19     {
20         @(0x1080) uint referenceCount;
21         @(0x1081) Device* _devices;
22         @(0x1082) Context.Properties* properties;
23         @(0x1083) uint numDevices;
24         ArrayAccesssor!(_devices,numDevices) devices;
25         // Extensions
26         //@(0x2010) khrTerminate;
27         //@(0x200E) khrMemoryInitialise;
28         //@(0x4014) CONTEXT_D3D10_DEVICE_KHR
29         //@(0x402C) CONTEXT_D3D10_PREFER_SHARED_RESOURCES_KHR
30         //@(0x401D) CONTEXT_D3D11_DEVICE_KHR
31         //@(0x402D) CONTEXT_D3D11_PREFER_SHARED_RESOURCES_KHR
32         //@(0x2025) CONTEXT_ADAPTER_D3D9_KHR
33         //@(0x2026) CONTEXT_ADAPTER_D3D9EX_KHR
34         //@(0x2027) CONTEXT_ADAPTER_DXVA_KHR
35         //@(0x2008) GL_CONTEXT_KHR
36         //@(0x2009) EGL_DISPLAY_KHR
37         //@(0x200A) GLX_DISPLAY_KHR
38         //@(0x200B) WGL_HDC_KHR
39         //@(0x200C) CGL_SHAREGROUP_KHR
40 
41     }
42     //mixin(generateGetInfo!(Info,clGetContextInfo));
43     
44     this(Device[] devs,const Properties[] props)
45     {
46         raw = clCreateContext(cast(const cl_context_properties*)props.ptr,
47                               cast(uint)devs.length,cast(const cl_device_id*)devs.ptr,
48                               null,null,
49                               cast(int*)&status);
50         checkErrors();
51     }
52     
53     this(Device.Type type,const Properties[] props)
54     {
55         raw = clCreateContextFromType(cast(const cl_context_properties*)props.ptr,
56                                       cast(cl_device_type)type,
57                                       null,null,
58                                       cast(int*)&status);
59         checkErrors();
60     }
61     void retain()
62     {
63         status = cast(Status)clRetainContext(raw);
64         checkErrors();
65     }
66     
67     void release()
68     {
69         status = cast(Status)clReleaseContext(raw);
70         checkErrors();
71     }
72     
73     Queue createQueue(Device dev,Queue.Properties prop)
74     {
75         Queue ret;
76         ret.raw = clCreateCommandQueue(this.raw,
77                                        dev.raw,
78                                        cast(cl_command_queue_properties)prop,
79                                        cast(int*)&status);
80         checkErrors();
81         return ret;
82     }
83     
84     Buffer!T createBuffer(T)(T[] arr,Memory.Flags flags = (Memory.Flags.useHostPointer | Memory.Flags.readWrite))
85     {
86         import std.stdio;
87         Buffer!T ret;
88         auto len = memSize(arr);
89         ret.raw = clCreateBuffer(raw,flags,len,arr.ptr,cast(int*)&status);
90         ret.hostMemory = arr;
91         checkErrors();
92         return ret;
93     }
94     
95     /*Image.Format[] supportedImageFormats(A)(A allocator, Memory.Flags f,Memory.Type t)
96     {
97         //Double call
98         clGetSupportedImageFormats
99     }*/
100     
101     Sampler createSampler(Flag!"normalisedCoordinates" f,
102                           Sampler.AddressingMode aMode,
103                           Sampler.FilterMode fMode)
104     {
105         Sampler ret;
106         ret.raw = clCreateSampler(this.raw,
107                                   cast(cl_bool)f,
108                                   cast(cl_addressing_mode)aMode,
109                                   cast(cl_filter_mode)fMode,
110                                   cast(int*)&status);
111         checkErrors();
112         return ret;
113     }
114     
115     /**Program createProgramFromSource(string[][] sources)
116      {
117         clCreateProgramWithSource
118      }
119     */
120     
121     Program createProgramFromSPIR(A)(A a, Device[] devices,ubyte[] spir)
122     {
123         auto allocator = TypedAllocator!(A)(a);
124         auto lengths = allocator.makeArray!(size_t)(devices.length);
125         lengths[]    = spir.length;
126         auto ptrs  = allocator.makeArray!(ubyte*)(devices.length);
127         ptrs[]       = spir.ptr;
128         Program ret;
129 
130         ret.raw = clCreateProgramWithBinary(
131                                 this.raw,
132                                 cast(uint)devices.length, cast(cl_device_id*)devices.ptr,
133                                 lengths.ptr,ptrs.ptr,
134                                 null, // TODO report individual errors
135                                 cast(int*)&status);
136         allocator.dispose(lengths);
137         allocator.dispose(ptrs);
138         return ret;
139     }
140     Program createProgram(void[] spirv)
141     {
142         Program ret;
143 
144         ret.raw = clCreateProgramWithIL(this.raw,
145 										spirv.ptr,
146 										spirv.length,
147 										cast(int*)&status);
148         return ret;
149     }
150     
151     /*Program createProgramFromBuiltinKernels(Device[] devices, string kernelNames)
152     {
153         clCreateProgramWithBuiltInKernels
154     }*/
155 }