… | |
… | |
40 | #define PREFER_1_1 1 |
40 | #define PREFER_1_1 1 |
41 | #endif |
41 | #endif |
42 | |
42 | |
43 | typedef cl_platform_id OpenCL__Platform; |
43 | typedef cl_platform_id OpenCL__Platform; |
44 | typedef cl_device_id OpenCL__Device; |
44 | typedef cl_device_id OpenCL__Device; |
|
|
45 | typedef cl_device_id OpenCL__SubDevice; |
45 | typedef cl_context OpenCL__Context; |
46 | typedef cl_context OpenCL__Context; |
46 | typedef cl_command_queue OpenCL__Queue; |
47 | typedef cl_command_queue OpenCL__Queue; |
47 | typedef cl_mem OpenCL__Memory; |
48 | typedef cl_mem OpenCL__Memory; |
48 | typedef cl_mem OpenCL__Buffer; |
49 | typedef cl_mem OpenCL__Buffer; |
49 | typedef cl_mem OpenCL__BufferObj; |
50 | typedef cl_mem OpenCL__BufferObj; |
… | |
… | |
62 | typedef SV *FUTURE; |
63 | typedef SV *FUTURE; |
63 | |
64 | |
64 | static HV |
65 | static HV |
65 | *stash_platform, |
66 | *stash_platform, |
66 | *stash_device, |
67 | *stash_device, |
|
|
68 | *stash_subdevice, |
67 | *stash_context, |
69 | *stash_context, |
68 | *stash_queue, |
70 | *stash_queue, |
69 | *stash_program, |
71 | *stash_program, |
70 | *stash_kernel, |
72 | *stash_kernel, |
71 | *stash_sampler, |
73 | *stash_sampler, |
… | |
… | |
217 | if (res) \ |
219 | if (res) \ |
218 | FAIL (name); |
220 | FAIL (name); |
219 | |
221 | |
220 | /*****************************************************************************/ |
222 | /*****************************************************************************/ |
221 | |
223 | |
|
|
224 | static SV * |
|
|
225 | new_clobj (HV *stash, IV id) |
|
|
226 | { |
|
|
227 | return sv_2mortal (sv_bless (newRV_noinc (newSViv (id)), stash)); |
|
|
228 | } |
|
|
229 | |
|
|
230 | #define PUSH_CLOBJ(stash,id) PUSHs (new_clobj ((stash), (IV)(id))) |
|
|
231 | #define XPUSH_CLOBJ(stash,id) XPUSHs (new_clobj ((stash), (IV)(id))) |
|
|
232 | |
|
|
233 | /* cl objects are either \$iv, or [$iv, ...] */ |
|
|
234 | /* they can be upgraded at runtime to the array form */ |
|
|
235 | static void * ecb_noinline |
|
|
236 | SvCLOBJ (const char *func, const char *svname, SV *sv, const char *pkg) |
|
|
237 | { |
|
|
238 | // sv_derived_from is quite slow :( |
|
|
239 | if (SvROK (sv) && sv_derived_from (sv, pkg)) |
|
|
240 | return (void *)SvIV (SvRV (sv)); |
|
|
241 | |
|
|
242 | croak ("%s: %s is not of type %s", func, svname, pkg); |
|
|
243 | } |
|
|
244 | |
|
|
245 | // the "no-inherit" version of the above |
|
|
246 | static void * ecb_noinline |
|
|
247 | SvCLOBJ_ni (const char *func, const char *svname, SV *sv, HV *stash) |
|
|
248 | { |
|
|
249 | if (SvROK (sv) && SvSTASH (SvRV (sv)) == stash) |
|
|
250 | return (void *)SvIV (SvRV (sv)); |
|
|
251 | |
|
|
252 | croak ("%s: %s is not of type %s", func, svname, HvNAME (stash)); |
|
|
253 | } |
|
|
254 | |
|
|
255 | /*****************************************************************************/ |
|
|
256 | |
222 | static cl_context_properties * ecb_noinline |
257 | static cl_context_properties * ecb_noinline |
223 | SvCONTEXTPROPERTIES (const char *func, const char *svname, SV *sv, cl_context_properties *extra, int extracount) |
258 | SvCONTEXTPROPERTIES (const char *func, const char *svname, SV *sv, cl_context_properties *extra, int extracount) |
224 | { |
259 | { |
225 | if (!sv || !SvOK (sv)) |
260 | if (!sv || !SvOK (sv)) |
226 | if (extra) |
261 | if (extra) |
… | |
… | |
234 | int i, len = av_len (av) + 1; |
269 | int i, len = av_len (av) + 1; |
235 | cl_context_properties *p = tmpbuf (sizeof (cl_context_properties) * (len + extracount + 1)); |
270 | cl_context_properties *p = tmpbuf (sizeof (cl_context_properties) * (len + extracount + 1)); |
236 | cl_context_properties *l = p; |
271 | cl_context_properties *l = p; |
237 | |
272 | |
238 | if (len & 1) |
273 | if (len & 1) |
239 | croak ("%s: %s is not a property list (must be even number of elements)", func, svname); |
274 | croak ("%s: %s is not a property list (must contain an even number of elements)", func, svname); |
240 | |
275 | |
241 | while (extracount--) |
276 | while (extracount--) |
242 | *l++ = *extra++; |
277 | *l++ = *extra++; |
243 | |
278 | |
244 | for (i = 0; i < len; i += 2) |
279 | for (i = 0; i < len; i += 2) |
… | |
… | |
247 | SV *p_sv = *av_fetch (av, i + 1, 0); |
282 | SV *p_sv = *av_fetch (av, i + 1, 0); |
248 | cl_context_properties v = SvIV (p_sv); // code below can override |
283 | cl_context_properties v = SvIV (p_sv); // code below can override |
249 | |
284 | |
250 | switch (t) |
285 | switch (t) |
251 | { |
286 | { |
|
|
287 | case CL_CONTEXT_PLATFORM: |
|
|
288 | if (SvROK (p_sv)) |
|
|
289 | v = (cl_context_properties)SvCLOBJ (func, svname, p_sv, "OpenCL::Platform"); |
|
|
290 | break; |
|
|
291 | |
252 | case CL_GLX_DISPLAY_KHR: |
292 | case CL_GLX_DISPLAY_KHR: |
253 | if (!SvOK (p_sv)) |
293 | if (!SvOK (p_sv)) |
254 | { |
294 | { |
255 | void *func = glsym ("_glXGetCurrentDisplay"); |
295 | void *func = glsym ("_glXGetCurrentDisplay"); |
256 | if (func) |
296 | if (func) |
… | |
… | |
280 | |
320 | |
281 | return p; |
321 | return p; |
282 | } |
322 | } |
283 | |
323 | |
284 | croak ("%s: %s is not a property list (either undef or [type => value, ...])", func, svname); |
324 | croak ("%s: %s is not a property list (either undef or [type => value, ...])", func, svname); |
285 | } |
|
|
286 | |
|
|
287 | /*****************************************************************************/ |
|
|
288 | |
|
|
289 | static SV * |
|
|
290 | new_clobj (HV *stash, IV id) |
|
|
291 | { |
|
|
292 | return sv_2mortal (sv_bless (newRV_noinc (newSViv (id)), stash)); |
|
|
293 | } |
|
|
294 | |
|
|
295 | #define PUSH_CLOBJ(stash,id) PUSHs (new_clobj ((stash), (IV)(id))) |
|
|
296 | #define XPUSH_CLOBJ(stash,id) XPUSHs (new_clobj ((stash), (IV)(id))) |
|
|
297 | |
|
|
298 | /* cl objects are either \$iv, or [$iv, ...] */ |
|
|
299 | /* they can be upgraded at runtime to the array form */ |
|
|
300 | static void * ecb_noinline |
|
|
301 | SvCLOBJ (const char *func, const char *svname, SV *sv, const char *pkg) |
|
|
302 | { |
|
|
303 | // sv_derived_from is quite slow :( |
|
|
304 | if (SvROK (sv) && sv_derived_from (sv, pkg)) |
|
|
305 | return (void *)SvIV (SvRV (sv)); |
|
|
306 | |
|
|
307 | croak ("%s: %s is not of type %s", func, svname, pkg); |
|
|
308 | } |
|
|
309 | |
|
|
310 | // the "no-inherit" version of the above |
|
|
311 | static void * ecb_noinline |
|
|
312 | SvCLOBJ_ni (const char *func, const char *svname, SV *sv, HV *stash) |
|
|
313 | { |
|
|
314 | if (SvROK (sv) && SvSTASH (SvRV (sv)) == stash) |
|
|
315 | return (void *)SvIV (SvRV (sv)); |
|
|
316 | |
|
|
317 | croak ("%s: %s is not of type %s", func, svname, HvNAME (stash)); |
|
|
318 | } |
325 | } |
319 | |
326 | |
320 | /*****************************************************************************/ |
327 | /*****************************************************************************/ |
321 | /* callback stuff */ |
328 | /* callback stuff */ |
322 | |
329 | |
… | |
… | |
730 | for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--) |
737 | for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--) |
731 | newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv)); |
738 | newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv)); |
732 | |
739 | |
733 | stash_platform = gv_stashpv ("OpenCL::Platform", GV_ADD); |
740 | stash_platform = gv_stashpv ("OpenCL::Platform", GV_ADD); |
734 | stash_device = gv_stashpv ("OpenCL::Device", GV_ADD); |
741 | stash_device = gv_stashpv ("OpenCL::Device", GV_ADD); |
|
|
742 | stash_subdevice = gv_stashpv ("OpenCL::SubDevice", GV_ADD); |
735 | stash_context = gv_stashpv ("OpenCL::Context", GV_ADD); |
743 | stash_context = gv_stashpv ("OpenCL::Context", GV_ADD); |
736 | stash_queue = gv_stashpv ("OpenCL::Queue", GV_ADD); |
744 | stash_queue = gv_stashpv ("OpenCL::Queue", GV_ADD); |
737 | stash_program = gv_stashpv ("OpenCL::Program", GV_ADD); |
745 | stash_program = gv_stashpv ("OpenCL::Program", GV_ADD); |
738 | stash_kernel = gv_stashpv ("OpenCL::Kernel", GV_ADD); |
746 | stash_kernel = gv_stashpv ("OpenCL::Kernel", GV_ADD); |
739 | stash_sampler = gv_stashpv ("OpenCL::Sampler", GV_ADD); |
747 | stash_sampler = gv_stashpv ("OpenCL::Sampler", GV_ADD); |
… | |
… | |
780 | list = tmpbuf (sizeof (*list) * count); |
788 | list = tmpbuf (sizeof (*list) * count); |
781 | NEED_SUCCESS (GetPlatformIDs, (count, list, 0)); |
789 | NEED_SUCCESS (GetPlatformIDs, (count, list, 0)); |
782 | |
790 | |
783 | EXTEND (SP, count); |
791 | EXTEND (SP, count); |
784 | for (i = 0; i < count; ++i) |
792 | for (i = 0; i < count; ++i) |
785 | PUSH_CLOBJ (stash_platform, (IV)list [i]); |
793 | PUSH_CLOBJ (stash_platform, list [i]); |
786 | |
794 | |
787 | void |
795 | void |
788 | context_from_type (cl_context_properties *properties = 0, cl_device_type type = CL_DEVICE_TYPE_DEFAULT, SV *notify = &PL_sv_undef) |
796 | context_from_type (cl_context_properties *properties = 0, cl_device_type type = CL_DEVICE_TYPE_DEFAULT, SV *notify = &PL_sv_undef) |
789 | PPCODE: |
797 | PPCODE: |
790 | CONTEXT_NOTIFY_CALLBACK; |
798 | CONTEXT_NOTIFY_CALLBACK; |
… | |
… | |
889 | |
897 | |
890 | void |
898 | void |
891 | info (OpenCL::Device self, cl_device_info name) |
899 | info (OpenCL::Device self, cl_device_info name) |
892 | PPCODE: |
900 | PPCODE: |
893 | INFO (Device) |
901 | INFO (Device) |
|
|
902 | |
|
|
903 | #if CL_VERSION_1_2 |
|
|
904 | |
|
|
905 | void |
|
|
906 | sub_devices (OpenCL::Device self, SV *properties) |
|
|
907 | PPCODE: |
|
|
908 | if (!SvROK (properties) || SvTYPE (SvRV (properties)) != SVt_PVAV) |
|
|
909 | croak ("OpenCL::Device::sub_devices: properties must be specified as reference to an array of property-value pairs"); |
|
|
910 | |
|
|
911 | properties = SvRV (properties); |
|
|
912 | |
|
|
913 | cl_uint count = av_len ((AV *)properties) + 1; |
|
|
914 | cl_device_partition_property *props = tmpbuf (sizeof (*props) * count + 1); |
|
|
915 | |
|
|
916 | int i; |
|
|
917 | for (i = 0; i < count; ++i) |
|
|
918 | props [i] = (cl_device_partition_property)SvIV (*av_fetch ((AV *)properties, i, 0)); |
|
|
919 | |
|
|
920 | props [count] = 0; |
|
|
921 | |
|
|
922 | cl_uint num_devices; |
|
|
923 | NEED_SUCCESS (CreateSubDevices, (self, props, 0, 0, &num_devices)); |
|
|
924 | cl_device_id *list = tmpbuf (sizeof (*list) * num_devices); |
|
|
925 | NEED_SUCCESS (CreateSubDevices, (self, props, num_devices, list, 0)); |
|
|
926 | |
|
|
927 | EXTEND (SP, num_devices); |
|
|
928 | for (i = 0; i < count; ++i) |
|
|
929 | PUSH_CLOBJ (stash_subdevice, list [i]); |
|
|
930 | |
|
|
931 | #endif |
894 | |
932 | |
895 | #BEGIN:device |
933 | #BEGIN:device |
896 | |
934 | |
897 | void |
935 | void |
898 | type (OpenCL::Device self) |
936 | type (OpenCL::Device self) |
… | |
… | |
1114 | for (i = 0; i < n; ++i) |
1152 | for (i = 0; i < n; ++i) |
1115 | PUSHs (sv_2mortal (newSVuv (value [i]))); |
1153 | PUSHs (sv_2mortal (newSVuv (value [i]))); |
1116 | |
1154 | |
1117 | #END:device |
1155 | #END:device |
1118 | |
1156 | |
|
|
1157 | MODULE = OpenCL PACKAGE = OpenCL::SubDevice |
|
|
1158 | |
|
|
1159 | #if CL_VERSION_1_2 |
|
|
1160 | |
|
|
1161 | void |
|
|
1162 | DESTROY (OpenCL::SubDevice self) |
|
|
1163 | CODE: |
|
|
1164 | clReleaseDevice (self); |
|
|
1165 | |
|
|
1166 | #endif |
|
|
1167 | |
1119 | MODULE = OpenCL PACKAGE = OpenCL::Context |
1168 | MODULE = OpenCL PACKAGE = OpenCL::Context |
1120 | |
1169 | |
1121 | void |
1170 | void |
1122 | DESTROY (OpenCL::Context context) |
1171 | DESTROY (OpenCL::Context self) |
1123 | CODE: |
1172 | CODE: |
1124 | clReleaseContext (context); |
1173 | clReleaseContext (self); |
1125 | |
1174 | |
1126 | void |
1175 | void |
1127 | info (OpenCL::Context self, cl_context_info name) |
1176 | info (OpenCL::Context self, cl_context_info name) |
1128 | PPCODE: |
1177 | PPCODE: |
1129 | INFO (Context) |
1178 | INFO (Context) |
… | |
… | |
1358 | |
1407 | |
1359 | for (i = count; i--; ) |
1408 | for (i = count; i--; ) |
1360 | av_store (av, i, newSViv (status_list [i])); |
1409 | av_store (av, i, newSViv (status_list [i])); |
1361 | } |
1410 | } |
1362 | |
1411 | |
|
|
1412 | #if CL_VERSION_1_2 |
|
|
1413 | |
|
|
1414 | void |
|
|
1415 | program_with_built_in_kernels (OpenCL::Context self, SV *devices, SV *kernel_names) |
|
|
1416 | PPCODE: |
|
|
1417 | if (!SvROK (devices) || SvTYPE (SvRV (devices)) != SVt_PVAV) |
|
|
1418 | croak ("OpenCL::Context::program_with_built_in_kernels: devices must be specified as reference to an array of device objects"); |
|
|
1419 | |
|
|
1420 | devices = SvRV (devices); |
|
|
1421 | |
|
|
1422 | int count = av_len ((AV *)devices) + 1; |
|
|
1423 | cl_device_id *device_list = tmpbuf (sizeof (*device_list) * count); |
|
|
1424 | |
|
|
1425 | int i; |
|
|
1426 | for (i = 0; i < count; ++i) |
|
|
1427 | device_list [i] = SvCLOBJ ("OpenCL::Context::program_with_built_in_kernels", "devices", *av_fetch ((AV *)devices, i, 0), "OpenCL::Device"); |
|
|
1428 | |
|
|
1429 | NEED_SUCCESS_ARG (cl_program prog, CreateProgramWithBuiltInKernels, (self, count, device_list, SvPVbyte_nolen (kernel_names), &res)); |
|
|
1430 | |
|
|
1431 | XPUSH_CLOBJ (stash_program, prog); |
|
|
1432 | |
|
|
1433 | #endif |
|
|
1434 | |
1363 | #BEGIN:context |
1435 | #BEGIN:context |
1364 | |
1436 | |
1365 | void |
1437 | void |
1366 | reference_count (OpenCL::Context self) |
1438 | reference_count (OpenCL::Context self) |
1367 | ALIAS: |
1439 | ALIAS: |
… | |
… | |
1833 | NEED_SUCCESS (EnqueueNDRangeKernel, (self, kernel, gws_len, gwo, gws, lws, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); |
1905 | NEED_SUCCESS (EnqueueNDRangeKernel, (self, kernel, gws_len, gwo, gws, lws, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); |
1834 | |
1906 | |
1835 | if (ev) |
1907 | if (ev) |
1836 | XPUSH_CLOBJ (stash_event, ev); |
1908 | XPUSH_CLOBJ (stash_event, ev); |
1837 | |
1909 | |
|
|
1910 | #if CL_VERSION_1_2 |
|
|
1911 | |
|
|
1912 | void |
|
|
1913 | migrate_mem_objects (OpenCL::Queue self, SV *objects, cl_mem_migration_flags flags, ...) |
|
|
1914 | ALIAS: |
|
|
1915 | enqueue_migrate_mem_objects = 0 |
|
|
1916 | PPCODE: |
|
|
1917 | EVENT_LIST (3); |
|
|
1918 | |
|
|
1919 | if (!SvROK (objects) || SvTYPE (SvRV (objects)) != SVt_PVAV) |
|
|
1920 | croak ("OpenCL::Queue::migrate_mem_objects: objects must be an array reference with OpenCL::Memory objects"); |
|
|
1921 | |
|
|
1922 | objects = SvRV (objects); |
|
|
1923 | |
|
|
1924 | cl_uint object_count = av_len ((AV *)objects) + 1; |
|
|
1925 | cl_mem *object_list = tmpbuf (sizeof (*object_list) * object_count); |
|
|
1926 | |
|
|
1927 | int i; |
|
|
1928 | for (i = object_count; i--; ) |
|
|
1929 | object_list [i] = SvCLOBJ ("OpenCL::Queue::migrate_mem_objects", "objects", *av_fetch ((AV *)objects, i, 0), "OpenCL::Memory"); |
|
|
1930 | |
|
|
1931 | cl_event ev = 0; |
|
|
1932 | NEED_SUCCESS (EnqueueMigrateMemObjects, (self, object_count, object_list, flags, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); |
|
|
1933 | |
|
|
1934 | if (ev) |
|
|
1935 | XPUSH_CLOBJ (stash_event, ev); |
|
|
1936 | |
|
|
1937 | #endif |
|
|
1938 | |
1838 | #if cl_apple_gl_sharing || cl_khr_gl_sharing |
1939 | #if cl_apple_gl_sharing || cl_khr_gl_sharing |
1839 | |
1940 | |
1840 | void |
1941 | void |
1841 | acquire_gl_objects (OpenCL::Queue self, SV *objects, ...) |
1942 | acquire_gl_objects (OpenCL::Queue self, SV *objects, ...) |
1842 | ALIAS: |
1943 | ALIAS: |
… | |
… | |
1850 | cl_event ev = 0; |
1951 | cl_event ev = 0; |
1851 | EVENT_LIST (2); |
1952 | EVENT_LIST (2); |
1852 | AV *av = (AV *)SvRV (objects); |
1953 | AV *av = (AV *)SvRV (objects); |
1853 | cl_uint num_objects = av_len (av) + 1; |
1954 | cl_uint num_objects = av_len (av) + 1; |
1854 | cl_mem *object_list = tmpbuf (sizeof (cl_mem) * num_objects); |
1955 | cl_mem *object_list = tmpbuf (sizeof (cl_mem) * num_objects); |
|
|
1956 | |
1855 | int i; |
1957 | int i; |
1856 | |
|
|
1857 | for (i = num_objects; i--; ) |
1958 | for (i = num_objects; i--; ) |
1858 | object_list [i] = SvCLOBJ ("OpenCL::Queue::enqueue_acquire/release_gl_objects", "objects", *av_fetch (av, i, 0), "OpenCL::Memory"); |
1959 | object_list [i] = SvCLOBJ ("OpenCL::Queue::acquire/release_gl_objects", "objects", *av_fetch (av, i, 0), "OpenCL::Memory"); |
1859 | |
1960 | |
1860 | if (ix) |
1961 | if (ix) |
1861 | NEED_SUCCESS (EnqueueReleaseGLObjects, (self, num_objects, object_list, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); |
1962 | NEED_SUCCESS (EnqueueReleaseGLObjects, (self, num_objects, object_list, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); |
1862 | else |
1963 | else |
1863 | NEED_SUCCESS (EnqueueAcquireGLObjects, (self, num_objects, object_list, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); |
1964 | NEED_SUCCESS (EnqueueAcquireGLObjects, (self, num_objects, object_list, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); |