• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2022 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //    http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "basic_command_buffer.h"
18 #include "procs.h"
19 
20 #include <vector>
21 
22 //--------------------------------------------------------------------------
23 enum class CombufInfoTestMode
24 {
25     CITM_QUEUES = 0,
26     CITM_REF_COUNT,
27     CITM_STATE,
28     CITM_PROP_ARRAY,
29     CITM_CONTEXT,
30 };
31 
32 namespace {
33 
34 ////////////////////////////////////////////////////////////////////////////////
35 // clGetCommandBufferInfoKHR tests for cl_khr_command_buffer which handles below
36 // cases:
37 // -test case for CL_COMMAND_BUFFER_NUM_QUEUES_KHR &
38 //  CL_COMMAND_BUFFER_QUEUES_KHR queries
39 // -test case for CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR query
40 // -test case for CL_COMMAND_BUFFER_STATE_KHR query
41 // -test case for CL_COMMAND_BUFFER_PROPERTIES_ARRAY_KHR query
42 // -test case for CL_COMMAND_BUFFER_CONTEXT_KHR query
43 
44 template <CombufInfoTestMode test_mode>
45 struct CommandBufferGetCommandBufferInfo : public BasicCommandBufferTest
46 {
CommandBufferGetCommandBufferInfo__anone5ca8e470111::CommandBufferGetCommandBufferInfo47     CommandBufferGetCommandBufferInfo(cl_device_id device, cl_context context,
48                                       cl_command_queue queue)
49         : BasicCommandBufferTest(device, context, queue)
50     {}
51 
52     //--------------------------------------------------------------------------
Run__anone5ca8e470111::CommandBufferGetCommandBufferInfo53     cl_int Run() override
54     {
55         cl_int error = CL_SUCCESS;
56 
57         switch (test_mode)
58         {
59             case CombufInfoTestMode::CITM_QUEUES:
60                 error = RunQueuesInfoTest();
61                 test_error(error, "RunQueuesInfoTest failed");
62                 break;
63             case CombufInfoTestMode::CITM_REF_COUNT:
64                 error = RunRefCountInfoTest();
65                 test_error(error, "RunRefCountInfoTest failed");
66                 break;
67             case CombufInfoTestMode::CITM_STATE:
68                 error = RunStateInfoTest();
69                 test_error(error, "RunStateInfoTest failed");
70                 break;
71             case CombufInfoTestMode::CITM_PROP_ARRAY:
72                 error = RunPropArrayInfoTest();
73                 test_error(error, "RunPropArrayInfoTest failed");
74                 break;
75             case CombufInfoTestMode::CITM_CONTEXT:
76                 error = RunContextInfoTest();
77                 test_error(error, "RunContextInfoTest failed");
78                 break;
79         }
80 
81         return CL_SUCCESS;
82     }
83 
84     //--------------------------------------------------------------------------
RecordCommandBuffer__anone5ca8e470111::CommandBufferGetCommandBufferInfo85     cl_int RecordCommandBuffer()
86     {
87         cl_int error = CL_SUCCESS;
88 
89         error = clCommandNDRangeKernelKHR(
90             command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
91             nullptr, 0, nullptr, nullptr, nullptr);
92         test_error(error, "clCommandNDRangeKernelKHR failed");
93 
94         error = clFinalizeCommandBufferKHR(command_buffer);
95         test_error(error, "clFinalizeCommandBufferKHR failed");
96         return CL_SUCCESS;
97     }
98 
99     //--------------------------------------------------------------------------
RunQueuesInfoTest__anone5ca8e470111::CommandBufferGetCommandBufferInfo100     cl_int RunQueuesInfoTest()
101     {
102         cl_int error = TEST_PASS;
103 
104         // record command buffers
105         error = RecordCommandBuffer();
106         test_error(error, "RecordCommandBuffer failed");
107 
108         // vector containter added due to potential future growth, at the moment
109         // spec of cl_khr_command_buffer says command-buffer accepts only 1
110         // queue
111         std::vector<cl_command_queue> expect_queue_list = { queue };
112         cl_uint num_queues = 0;
113         size_t ret_value_size = 0;
114         error = clGetCommandBufferInfoKHR(
115             command_buffer, CL_COMMAND_BUFFER_NUM_QUEUES_KHR, sizeof(cl_uint),
116             &num_queues, &ret_value_size);
117         test_error(error, "clGetCommandBufferInfoKHR failed");
118 
119         test_assert_error(
120             ret_value_size == sizeof(cl_int),
121             "Unexpected result of CL_COMMAND_BUFFER_NUM_QUEUES_KHR query!");
122 
123         test_assert_error(num_queues == expect_queue_list.size(),
124                           "Unexpected queue list size!");
125 
126         std::vector<cl_command_queue> queue_list(num_queues);
127         size_t expect_size = queue_list.size() * sizeof(cl_command_queue);
128         error = clGetCommandBufferInfoKHR(
129             command_buffer, CL_COMMAND_BUFFER_QUEUES_KHR, expect_size,
130             &queue_list.front(), &ret_value_size);
131         test_error(error, "clGetCommandBufferInfoKHR failed");
132 
133         test_assert_error(
134             ret_value_size == expect_size,
135             "Unexpected result of CL_COMMAND_BUFFER_NUM_QUEUES_KHR query!");
136 
137         // We can not check if this is the right queue because this is an opaque
138         // object, test against NULL.
139         for (size_t i = 0; i < queue_list.size(); i++)
140         {
141             test_assert_error(
142                 queue_list[i] == queue,
143                 "clGetCommandBufferInfoKHR return values not as expected\n");
144         }
145         return TEST_PASS;
146     }
147 
148     //--------------------------------------------------------------------------
RunRefCountInfoTest__anone5ca8e470111::CommandBufferGetCommandBufferInfo149     cl_int RunRefCountInfoTest()
150     {
151         cl_int error = CL_SUCCESS;
152 
153         // record command buffer
154         error = RecordCommandBuffer();
155         test_error(error, "RecordCommandBuffer failed");
156 
157         // collect initial reference count
158         cl_uint init_ref_count = 0;
159         error = clGetCommandBufferInfoKHR(
160             command_buffer, CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR,
161             sizeof(cl_uint), &init_ref_count, nullptr);
162         test_error(error, "clGetCommandBufferInfoKHR failed");
163 
164         // increase reference count through clRetainCommandBufferKHR calls
165         const cl_int min_retain_count = 2;
166         const cl_int max_retain_count = 6;
167         cl_int retain_count = std::max(
168             min_retain_count, min_retain_count + rand() % max_retain_count);
169 
170         for (int i = 0; i < retain_count; i++)
171         {
172             error = clRetainCommandBufferKHR(command_buffer);
173             test_error(error, "clRetainCommandBufferKHR failed");
174         }
175 
176         // verify new reference count value
177         cl_uint new_ref_count = 0;
178         error = clGetCommandBufferInfoKHR(
179             command_buffer, CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR,
180             sizeof(cl_uint), &new_ref_count, nullptr);
181         test_error(error, "clGetCommandBufferInfoKHR failed");
182 
183         test_assert_error(new_ref_count == (retain_count + init_ref_count),
184                           "Unexpected result of "
185                           "CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR query!");
186 
187         // decrease reference count through clReleaseCommandBufferKHR calls
188         for (int i = 0; i < retain_count; i++)
189         {
190             error = clReleaseCommandBufferKHR(command_buffer);
191             test_error(error, "clReleaseCommandBufferKHR failed");
192         }
193 
194         // verify new reference count value
195         error = clGetCommandBufferInfoKHR(
196             command_buffer, CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR,
197             sizeof(cl_uint), &new_ref_count, nullptr);
198         test_error(error, "clGetCommandBufferInfoKHR failed");
199 
200         test_assert_error(new_ref_count == init_ref_count,
201                           "Unexpected result of "
202                           "CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR query!");
203 
204         return TEST_PASS;
205     }
206 
207     //--------------------------------------------------------------------------
RunStateInfoTest__anone5ca8e470111::CommandBufferGetCommandBufferInfo208     cl_int RunStateInfoTest()
209     {
210         cl_int error = CL_SUCCESS;
211 
212         // lambda to verify given state
213         auto verify_state = [&](const cl_command_buffer_state_khr &expected) {
214             cl_command_buffer_state_khr state = ~cl_command_buffer_state_khr(0);
215 
216             cl_int error = clGetCommandBufferInfoKHR(
217                 command_buffer, CL_COMMAND_BUFFER_STATE_KHR, sizeof(state),
218                 &state, nullptr);
219             test_error_ret(error, "clGetCommandBufferInfoKHR failed",
220                            TEST_FAIL);
221 
222             test_assert_error(
223                 state == expected,
224                 "Unexpected result of CL_COMMAND_BUFFER_STATE_KHR query!");
225 
226             return TEST_PASS;
227         };
228 
229         // verify recording state
230         error = verify_state(CL_COMMAND_BUFFER_STATE_RECORDING_KHR);
231         test_error(error, "verify_state failed");
232 
233         // record command buffer
234         error = RecordCommandBuffer();
235         test_error(error, "RecordCommandBuffer failed");
236 
237         // verify executable state
238         error = verify_state(CL_COMMAND_BUFFER_STATE_EXECUTABLE_KHR);
239         test_error(error, "verify_state failed");
240 
241         error = clEnqueueFillBuffer(queue, out_mem, &pattern, sizeof(cl_int), 0,
242                                     data_size(), 0, nullptr, nullptr);
243         test_error(error, "clEnqueueFillBuffer failed");
244 
245         clEventWrapper trigger_event = clCreateUserEvent(context, &error);
246         test_error(error, "clCreateUserEvent failed");
247 
248         clEventWrapper execute_event;
249         // enqueued command buffer blocked on user event
250         error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 1,
251                                           &trigger_event, &execute_event);
252         test_error(error, "clEnqueueCommandBufferKHR failed");
253 
254         // verify pending state
255         error = verify_state(CL_COMMAND_BUFFER_STATE_PENDING_KHR);
256 
257         // execute command buffer
258         cl_int signal_error = clSetUserEventStatus(trigger_event, CL_COMPLETE);
259 
260         test_error(error, "verify_state failed");
261 
262         test_error(signal_error, "clSetUserEventStatus failed");
263 
264         error = clWaitForEvents(1, &execute_event);
265         test_error(error, "Unable to wait for execute event");
266 
267         // verify executable state
268         error = verify_state(CL_COMMAND_BUFFER_STATE_EXECUTABLE_KHR);
269         test_error(error, "verify_state failed");
270 
271         return CL_SUCCESS;
272     }
273 
274     //--------------------------------------------------------------------------
RunPropArrayInfoTest__anone5ca8e470111::CommandBufferGetCommandBufferInfo275     cl_int RunPropArrayInfoTest()
276     {
277         cl_int error = CL_SUCCESS;
278 
279         // record command buffer
280         error = RecordCommandBuffer();
281         test_error(error, "RecordCommandBuffer failed");
282 
283         size_t ret_value_size = 0;
284         std::vector<cl_command_buffer_properties_khr> combuf_props;
285         error = clGetCommandBufferInfoKHR(
286             command_buffer, CL_COMMAND_BUFFER_PROPERTIES_ARRAY_KHR, 0, nullptr,
287             &ret_value_size);
288         test_error_ret(error, "clGetCommandBufferInfoKHR failed", TEST_FAIL);
289 
290         // command buffer created without sumultaneous use ? 0 size possible
291         if (!simultaneous_use_support && ret_value_size == 0) return TEST_PASS;
292 
293         // ... otherwise 0 size prop array is not an acceptable value
294         test_assert_error(ret_value_size != 0,
295                           "Unexpected result of "
296                           "CL_COMMAND_BUFFER_PROPERTIES_ARRAY_KHR query!");
297 
298         cl_uint num_ret_props =
299             ret_value_size / sizeof(cl_command_buffer_properties_khr);
300         test_assert_error(num_ret_props != 0,
301                           "Unexpected result of "
302                           "CL_COMMAND_BUFFER_PROPERTIES_ARRAY_KHR query!");
303 
304         combuf_props.resize(num_ret_props);
305         error = clGetCommandBufferInfoKHR(
306             command_buffer, CL_COMMAND_BUFFER_PROPERTIES_ARRAY_KHR,
307             num_ret_props * sizeof(cl_command_buffer_properties_khr),
308             combuf_props.data(), nullptr);
309         test_error_ret(error, "clGetCommandBufferInfoKHR failed", TEST_FAIL);
310 
311         if (simultaneous_use_support)
312         {
313             // in simultaneous use case at least 3 elements in array expected
314             test_assert_error(num_ret_props >= 3,
315                               "Unexpected result of "
316                               "CL_COMMAND_BUFFER_PROPERTIES_ARRAY_KHR query!");
317 
318             if (combuf_props[0] == CL_COMMAND_BUFFER_FLAGS_KHR
319                 && combuf_props[1] == CL_COMMAND_BUFFER_SIMULTANEOUS_USE_KHR
320                 && combuf_props.back() == 0)
321                 return TEST_PASS;
322         }
323         else
324         {
325             if (combuf_props.back() == 0) return TEST_PASS;
326         }
327 
328         return TEST_FAIL;
329     }
330 
RunContextInfoTest__anone5ca8e470111::CommandBufferGetCommandBufferInfo331     cl_int RunContextInfoTest()
332     {
333         cl_int error = TEST_PASS;
334 
335         // record command buffers
336         error = RecordCommandBuffer();
337         test_error(error, "RecordCommandBuffer failed");
338 
339         size_t ret_value_size = 0;
340         error = clGetCommandBufferInfoKHR(command_buffer,
341                                           CL_COMMAND_BUFFER_CONTEXT_KHR, 0,
342                                           nullptr, &ret_value_size);
343         test_error(error, "clGetCommandBufferInfoKHR failed");
344 
345         test_assert_error(
346             ret_value_size == sizeof(cl_context),
347             "Unexpected result of CL_COMMAND_BUFFER_CONTEXT_KHR query!");
348 
349         cl_context ret_context = nullptr;
350         error = clGetCommandBufferInfoKHR(
351             command_buffer, CL_COMMAND_BUFFER_CONTEXT_KHR, sizeof(cl_context),
352             &ret_context, nullptr);
353         test_error(error, "clGetCommandBufferInfoKHR failed");
354         test_assert_error(
355             ret_context != nullptr,
356             "Unexpected result of CL_COMMAND_BUFFER_CONTEXT_KHR query!");
357 
358         cl_context expected_context = nullptr;
359         error =
360             clGetCommandQueueInfo(queue, CL_QUEUE_CONTEXT, sizeof(cl_context),
361                                   &expected_context, nullptr);
362         test_error(error, "clGetCommandQueueInfo failed");
363 
364         test_assert_error(
365             ret_context == expected_context,
366             "Unexpected result of CL_COMMAND_BUFFER_CONTEXT_KHR query!");
367 
368         return TEST_PASS;
369     }
370 
371     const cl_int pattern = 0xE;
372 };
373 
374 } // anonymous namespace
375 
376 
test_info_queues(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)377 int test_info_queues(cl_device_id device, cl_context context,
378                      cl_command_queue queue, int num_elements)
379 {
380     return MakeAndRunTest<
381         CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_QUEUES>>(
382         device, context, queue, num_elements);
383 }
384 
test_info_ref_count(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)385 int test_info_ref_count(cl_device_id device, cl_context context,
386                         cl_command_queue queue, int num_elements)
387 {
388     return MakeAndRunTest<
389         CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_REF_COUNT>>(
390         device, context, queue, num_elements);
391 }
392 
test_info_state(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)393 int test_info_state(cl_device_id device, cl_context context,
394                     cl_command_queue queue, int num_elements)
395 {
396     return MakeAndRunTest<
397         CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_STATE>>(
398         device, context, queue, num_elements);
399 }
400 
test_info_prop_array(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)401 int test_info_prop_array(cl_device_id device, cl_context context,
402                          cl_command_queue queue, int num_elements)
403 {
404     return MakeAndRunTest<
405         CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_PROP_ARRAY>>(
406         device, context, queue, num_elements);
407 }
408 
test_info_context(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)409 int test_info_context(cl_device_id device, cl_context context,
410                       cl_command_queue queue, int num_elements)
411 {
412     return MakeAndRunTest<
413         CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_CONTEXT>>(
414         device, context, queue, num_elements);
415 }
416