mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
Test releasing a command-buffer after submission but before execution has finished (#2414)
Add cl_khr_command_buffer test that is it valid to release a command-buffer after it has been enqueued but before execution is finished. This stresses the semantics from [clReleaseCommandBufferKHR](https://registry.khronos.org/OpenCL/sdk/3.0/docs/man/html/clReleaseCommandBufferKHR.html#_description) that: "After the command_buffer reference count becomes zero **and has finished execution**, the command-buffer is deleted"
This commit is contained in:
@@ -435,3 +435,40 @@ bool InterleavedEnqueueTest::Skip()
|
||||
{
|
||||
return BasicCommandBufferTest::Skip() || !simultaneous_use_support;
|
||||
}
|
||||
|
||||
cl_int EnqueueAndReleaseTest::Run()
|
||||
{
|
||||
cl_int error = clCommandNDRangeKernelKHR(
|
||||
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
|
||||
nullptr, 0, nullptr, nullptr, nullptr);
|
||||
test_error(error, "clCommandNDRangeKernelKHR failed");
|
||||
|
||||
error = clFinalizeCommandBufferKHR(command_buffer);
|
||||
test_error(error, "clFinalizeCommandBufferKHR failed");
|
||||
|
||||
cl_int pattern = 42;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
|
||||
data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
|
||||
nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
// Calls release on cl_command_buffer_khr handle inside wrapper class, and
|
||||
// sets the handle to nullptr, so that release doesn't get called again at
|
||||
// end of test when wrapper object is destroyed.
|
||||
command_buffer.reset();
|
||||
|
||||
std::vector<cl_int> output_data(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
|
||||
output_data.data(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (size_t i = 0; i < num_elements; i++)
|
||||
{
|
||||
CHECK_VERIFICATION_ERROR(pattern, output_data[i], i);
|
||||
}
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -128,6 +128,15 @@ struct InterleavedEnqueueTest : public BasicCommandBufferTest
|
||||
bool Skip() override;
|
||||
};
|
||||
|
||||
// Test releasing a command-buffer after it has been submitted for execution,
|
||||
// but before the user has waited on completion of the enqueue.
|
||||
struct EnqueueAndReleaseTest : public BasicCommandBufferTest
|
||||
{
|
||||
using BasicCommandBufferTest::BasicCommandBufferTest;
|
||||
|
||||
cl_int Run() override;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
int MakeAndRunTest(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
|
||||
@@ -44,3 +44,9 @@ REGISTER_TEST(explicit_flush)
|
||||
return MakeAndRunTest<ExplicitFlushTest>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
REGISTER_TEST(enqueue_and_release)
|
||||
{
|
||||
return MakeAndRunTest<EnqueueAndReleaseTest>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user