clover: Move down canonicalization of memory object flags into validate_flags().
[mesa.git] / src / gallium / state_trackers / clover / api / context.cpp
1 //
2 // Copyright 2012 Francisco Jerez
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
21 //
22
23 #include "api/util.hpp"
24 #include "core/context.hpp"
25 #include "core/platform.hpp"
26
27 using namespace clover;
28
29 CLOVER_API cl_context
30 clCreateContext(const cl_context_properties *d_props, cl_uint num_devs,
31 const cl_device_id *d_devs,
32 void (CL_CALLBACK *pfn_notify)(const char *, const void *,
33 size_t, void *),
34 void *user_data, cl_int *r_errcode) try {
35 auto props = obj<property_list_tag>(d_props);
36 auto devs = objs(d_devs, num_devs);
37
38 if (!pfn_notify && user_data)
39 throw error(CL_INVALID_VALUE);
40
41 for (auto &prop : props) {
42 if (prop.first == CL_CONTEXT_PLATFORM)
43 obj(prop.second.as<cl_platform_id>());
44 else
45 throw error(CL_INVALID_PROPERTY);
46 }
47
48 ret_error(r_errcode, CL_SUCCESS);
49 return desc(new context(props, devs));
50
51 } catch (error &e) {
52 ret_error(r_errcode, e);
53 return NULL;
54 }
55
56 CLOVER_API cl_context
57 clCreateContextFromType(const cl_context_properties *d_props,
58 cl_device_type type,
59 void (CL_CALLBACK *pfn_notify)(
60 const char *, const void *, size_t, void *),
61 void *user_data, cl_int *r_errcode) try {
62 cl_platform_id d_platform;
63 cl_uint num_platforms;
64 cl_int ret;
65 std::vector<cl_device_id> devs;
66 cl_uint num_devices;
67
68 ret = clGetPlatformIDs(1, &d_platform, &num_platforms);
69 if (ret || !num_platforms)
70 throw error(CL_INVALID_PLATFORM);
71
72 ret = clGetDeviceIDs(d_platform, type, 0, NULL, &num_devices);
73 if (ret)
74 throw error(CL_DEVICE_NOT_FOUND);
75 devs.resize(num_devices);
76 ret = clGetDeviceIDs(d_platform, type, num_devices, devs.data(), 0);
77 if (ret)
78 throw error(CL_DEVICE_NOT_FOUND);
79
80 return clCreateContext(d_props, num_devices, devs.data(), pfn_notify,
81 user_data, r_errcode);
82
83 } catch (error &e) {
84 ret_error(r_errcode, e);
85 return NULL;
86 }
87
88 CLOVER_API cl_int
89 clRetainContext(cl_context d_ctx) try {
90 obj(d_ctx).retain();
91 return CL_SUCCESS;
92
93 } catch (error &e) {
94 return e.get();
95 }
96
97 CLOVER_API cl_int
98 clReleaseContext(cl_context d_ctx) try {
99 if (obj(d_ctx).release())
100 delete pobj(d_ctx);
101
102 return CL_SUCCESS;
103
104 } catch (error &e) {
105 return e.get();
106 }
107
108 CLOVER_API cl_int
109 clGetContextInfo(cl_context d_ctx, cl_context_info param,
110 size_t size, void *r_buf, size_t *r_size) try {
111 property_buffer buf { r_buf, size, r_size };
112 auto &ctx = obj(d_ctx);
113
114 switch (param) {
115 case CL_CONTEXT_REFERENCE_COUNT:
116 buf.as_scalar<cl_uint>() = ctx.ref_count();
117 break;
118
119 case CL_CONTEXT_NUM_DEVICES:
120 buf.as_scalar<cl_uint>() = ctx.devices().size();
121 break;
122
123 case CL_CONTEXT_DEVICES:
124 buf.as_vector<cl_device_id>() = descs(ctx.devices());
125 break;
126
127 case CL_CONTEXT_PROPERTIES:
128 buf.as_vector<cl_context_properties>() = desc(ctx.properties());
129 break;
130
131 default:
132 throw error(CL_INVALID_VALUE);
133 }
134
135 return CL_SUCCESS;
136
137 } catch (error &e) {
138 return e.get();
139 }