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;
|
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;
|
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>
|
template <class T>
|
||||||
int MakeAndRunTest(cl_device_id device, cl_context context,
|
int MakeAndRunTest(cl_device_id device, cl_context context,
|
||||||
cl_command_queue queue, int num_elements)
|
cl_command_queue queue, int num_elements)
|
||||||
|
|||||||
@@ -44,3 +44,9 @@ REGISTER_TEST(explicit_flush)
|
|||||||
return MakeAndRunTest<ExplicitFlushTest>(device, context, queue,
|
return MakeAndRunTest<ExplicitFlushTest>(device, context, queue,
|
||||||
num_elements);
|
num_elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
REGISTER_TEST(enqueue_and_release)
|
||||||
|
{
|
||||||
|
return MakeAndRunTest<EnqueueAndReleaseTest>(device, context, queue,
|
||||||
|
num_elements);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user