mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
Clean up cl_khr_external_semaphore_dx_fence test (#2580)
Removes the duplicated code from the tests. Improves the Base test class.
This commit is contained in:
@@ -32,5 +32,15 @@
|
|||||||
} \
|
} \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
|
#define GET_FUNCTION_EXTENSION_ADDRESS(device, FUNC) \
|
||||||
|
FUNC = \
|
||||||
|
reinterpret_cast<FUNC##_fn>(clGetExtensionFunctionAddressForPlatform( \
|
||||||
|
getPlatformFromDevice(device), #FUNC)); \
|
||||||
|
if (FUNC == nullptr) \
|
||||||
|
{ \
|
||||||
|
log_error("ERROR: clGetExtensionFunctionAddressForPlatform failed" \
|
||||||
|
" with " #FUNC "\n"); \
|
||||||
|
return TEST_FAIL; \
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _extensionHelpers_h
|
#endif // _extensionHelpers_h
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ class DirectXWrapper {
|
|||||||
public:
|
public:
|
||||||
DirectXWrapper();
|
DirectXWrapper();
|
||||||
|
|
||||||
ID3D12Device* getDXDevice() const;
|
[[nodiscard]] ID3D12Device* getDXDevice() const;
|
||||||
ID3D12CommandQueue* getDXCommandQueue() const;
|
[[nodiscard]] ID3D12CommandQueue* getDXCommandQueue() const;
|
||||||
ID3D12CommandAllocator* getDXCommandAllocator() const;
|
[[nodiscard]] ID3D12CommandAllocator* getDXCommandAllocator() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ComPtr<ID3D12Device> dx_device = nullptr;
|
ComPtr<ID3D12Device> dx_device = nullptr;
|
||||||
@@ -39,7 +39,7 @@ protected:
|
|||||||
class DirectXFenceWrapper {
|
class DirectXFenceWrapper {
|
||||||
public:
|
public:
|
||||||
DirectXFenceWrapper(ID3D12Device* dx_device);
|
DirectXFenceWrapper(ID3D12Device* dx_device);
|
||||||
ID3D12Fence* operator*() const { return dx_fence.Get(); }
|
[[nodiscard]] ID3D12Fence* get() const { return dx_fence.Get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ComPtr<ID3D12Fence> dx_fence = nullptr;
|
ComPtr<ID3D12Fence> dx_fence = nullptr;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
int main(int argc, const char *argv[])
|
int main(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
return runTestHarness(argc, argv, test_registry::getInstance().num_tests(),
|
return runTestHarness(
|
||||||
|
argc, argv, static_cast<int>(test_registry::getInstance().num_tests()),
|
||||||
test_registry::getInstance().definitions(), false, 0);
|
test_registry::getInstance().definitions(), false, 0);
|
||||||
}
|
}
|
||||||
@@ -21,81 +21,91 @@
|
|||||||
#include "harness/errorHelpers.h"
|
#include "harness/errorHelpers.h"
|
||||||
#include "directx_wrapper.hpp"
|
#include "directx_wrapper.hpp"
|
||||||
|
|
||||||
class CLDXSemaphoreWrapper {
|
struct DXFenceTestBase
|
||||||
public:
|
|
||||||
CLDXSemaphoreWrapper(cl_device_id device, cl_context context,
|
|
||||||
ID3D12Device* dx_device)
|
|
||||||
: device(device), context(context), dx_device(dx_device){};
|
|
||||||
|
|
||||||
int createSemaphoreFromFence(ID3D12Fence* fence)
|
|
||||||
{
|
{
|
||||||
cl_int errcode = CL_SUCCESS;
|
DXFenceTestBase(cl_device_id device, cl_context context,
|
||||||
|
cl_command_queue queue, cl_int num_elems)
|
||||||
GET_PFN(device, clCreateSemaphoreWithPropertiesKHR);
|
: device(device), context(context), queue(queue), num_elems(num_elems)
|
||||||
|
{}
|
||||||
const HRESULT hr = dx_device->CreateSharedHandle(
|
virtual ~DXFenceTestBase()
|
||||||
fence, nullptr, GENERIC_ALL, nullptr, &fence_handle);
|
|
||||||
test_error(FAILED(hr), "Failed to get shared handle from D3D12 fence");
|
|
||||||
|
|
||||||
cl_semaphore_properties_khr sem_props[] = {
|
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_KHR),
|
|
||||||
static_cast<cl_semaphore_properties_khr>(
|
|
||||||
CL_SEMAPHORE_TYPE_BINARY_KHR),
|
|
||||||
static_cast<cl_semaphore_properties_khr>(
|
|
||||||
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR),
|
|
||||||
reinterpret_cast<cl_semaphore_properties_khr>(fence_handle), 0
|
|
||||||
};
|
|
||||||
semaphore =
|
|
||||||
clCreateSemaphoreWithPropertiesKHR(context, sem_props, &errcode);
|
|
||||||
test_error(errcode, "Could not create semaphore");
|
|
||||||
|
|
||||||
return CL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
~CLDXSemaphoreWrapper()
|
|
||||||
{
|
{
|
||||||
releaseSemaphore();
|
|
||||||
if (fence_handle)
|
if (fence_handle)
|
||||||
{
|
{
|
||||||
CloseHandle(fence_handle);
|
CloseHandle(fence_handle);
|
||||||
|
fence_handle = nullptr;
|
||||||
}
|
}
|
||||||
};
|
if (fence_wrapper)
|
||||||
|
|
||||||
const cl_semaphore_khr* operator&() const { return &semaphore; };
|
|
||||||
cl_semaphore_khr operator*() const { return semaphore; };
|
|
||||||
|
|
||||||
HANDLE getHandle() const { return fence_handle; };
|
|
||||||
|
|
||||||
private:
|
|
||||||
cl_semaphore_khr semaphore;
|
|
||||||
ComPtr<ID3D12Fence> fence;
|
|
||||||
HANDLE fence_handle;
|
|
||||||
cl_device_id device;
|
|
||||||
cl_context context;
|
|
||||||
ComPtr<ID3D12Device> dx_device;
|
|
||||||
|
|
||||||
int releaseSemaphore() const
|
|
||||||
{
|
{
|
||||||
GET_PFN(device, clReleaseSemaphoreKHR);
|
delete fence_wrapper;
|
||||||
|
fence_wrapper = nullptr;
|
||||||
|
}
|
||||||
if (semaphore)
|
if (semaphore)
|
||||||
{
|
{
|
||||||
clReleaseSemaphoreKHR(semaphore);
|
clReleaseSemaphoreKHR(semaphore);
|
||||||
}
|
semaphore = nullptr;
|
||||||
|
|
||||||
return CL_SUCCESS;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool
|
virtual int SetUp()
|
||||||
is_import_handle_available(cl_device_id device,
|
{
|
||||||
|
REQUIRE_EXTENSION("cl_khr_external_semaphore");
|
||||||
|
REQUIRE_EXTENSION("cl_khr_external_semaphore_dx_fence");
|
||||||
|
|
||||||
|
// Obtain pointers to semaphore's API
|
||||||
|
GET_FUNCTION_EXTENSION_ADDRESS(device,
|
||||||
|
clCreateSemaphoreWithPropertiesKHR);
|
||||||
|
GET_FUNCTION_EXTENSION_ADDRESS(device, clReleaseSemaphoreKHR);
|
||||||
|
GET_FUNCTION_EXTENSION_ADDRESS(device, clEnqueueSignalSemaphoresKHR);
|
||||||
|
GET_FUNCTION_EXTENSION_ADDRESS(device, clEnqueueWaitSemaphoresKHR);
|
||||||
|
GET_FUNCTION_EXTENSION_ADDRESS(device, clGetSemaphoreHandleForTypeKHR);
|
||||||
|
GET_FUNCTION_EXTENSION_ADDRESS(device, clRetainSemaphoreKHR);
|
||||||
|
GET_FUNCTION_EXTENSION_ADDRESS(device, clGetSemaphoreInfoKHR);
|
||||||
|
|
||||||
|
test_error(
|
||||||
|
!is_import_handle_available(CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR),
|
||||||
|
"Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between the "
|
||||||
|
"supported import types");
|
||||||
|
|
||||||
|
// Import D3D12 fence into OpenCL
|
||||||
|
fence_wrapper = new DirectXFenceWrapper(dx_wrapper.getDXDevice());
|
||||||
|
semaphore = createSemaphoreFromFence(fence_wrapper->get());
|
||||||
|
test_assert_error(!!semaphore, "Could not create semaphore");
|
||||||
|
|
||||||
|
return TEST_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual cl_int Run() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int errcode = CL_SUCCESS;
|
||||||
|
|
||||||
|
cl_device_id device = nullptr;
|
||||||
|
cl_context context = nullptr;
|
||||||
|
cl_command_queue queue = nullptr;
|
||||||
|
cl_int num_elems = 0;
|
||||||
|
DirectXWrapper dx_wrapper;
|
||||||
|
|
||||||
|
cl_semaphore_payload_khr semaphore_payload = 1;
|
||||||
|
cl_semaphore_khr semaphore = nullptr;
|
||||||
|
HANDLE fence_handle = nullptr;
|
||||||
|
DirectXFenceWrapper *fence_wrapper = nullptr;
|
||||||
|
|
||||||
|
clCreateSemaphoreWithPropertiesKHR_fn clCreateSemaphoreWithPropertiesKHR =
|
||||||
|
nullptr;
|
||||||
|
clEnqueueSignalSemaphoresKHR_fn clEnqueueSignalSemaphoresKHR = nullptr;
|
||||||
|
clEnqueueWaitSemaphoresKHR_fn clEnqueueWaitSemaphoresKHR = nullptr;
|
||||||
|
clReleaseSemaphoreKHR_fn clReleaseSemaphoreKHR = nullptr;
|
||||||
|
clGetSemaphoreInfoKHR_fn clGetSemaphoreInfoKHR = nullptr;
|
||||||
|
clRetainSemaphoreKHR_fn clRetainSemaphoreKHR = nullptr;
|
||||||
|
clGetSemaphoreHandleForTypeKHR_fn clGetSemaphoreHandleForTypeKHR = nullptr;
|
||||||
|
|
||||||
|
[[nodiscard]] bool is_import_handle_available(
|
||||||
const cl_external_memory_handle_type_khr handle_type)
|
const cl_external_memory_handle_type_khr handle_type)
|
||||||
{
|
{
|
||||||
int errcode = CL_SUCCESS;
|
|
||||||
size_t import_types_size = 0;
|
size_t import_types_size = 0;
|
||||||
errcode =
|
errcode =
|
||||||
clGetDeviceInfo(device, CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR, 0,
|
clGetDeviceInfo(device, CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR,
|
||||||
nullptr, &import_types_size);
|
0, nullptr, &import_types_size);
|
||||||
if (errcode != CL_SUCCESS)
|
if (errcode != CL_SUCCESS)
|
||||||
{
|
{
|
||||||
log_error("Could not query import semaphore handle types");
|
log_error("Could not query import semaphore handle types");
|
||||||
@@ -115,3 +125,45 @@ is_import_handle_available(cl_device_id device,
|
|||||||
return std::find(import_types.begin(), import_types.end(), handle_type)
|
return std::find(import_types.begin(), import_types.end(), handle_type)
|
||||||
!= import_types.end();
|
!= import_types.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cl_semaphore_khr createSemaphoreFromFence(ID3D12Fence *src_fence)
|
||||||
|
{
|
||||||
|
const HRESULT hr = dx_wrapper.getDXDevice()->CreateSharedHandle(
|
||||||
|
src_fence, nullptr, GENERIC_ALL, nullptr, &fence_handle);
|
||||||
|
if (FAILED(hr)) return nullptr;
|
||||||
|
|
||||||
|
const cl_semaphore_properties_khr sem_props[] = {
|
||||||
|
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_KHR),
|
||||||
|
static_cast<cl_semaphore_properties_khr>(
|
||||||
|
CL_SEMAPHORE_TYPE_BINARY_KHR),
|
||||||
|
static_cast<cl_semaphore_properties_khr>(
|
||||||
|
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR),
|
||||||
|
reinterpret_cast<cl_semaphore_properties_khr>(fence_handle), 0
|
||||||
|
};
|
||||||
|
cl_semaphore_khr tmp_semaphore =
|
||||||
|
clCreateSemaphoreWithPropertiesKHR(context, sem_props, &errcode);
|
||||||
|
if (errcode != CL_SUCCESS) return nullptr;
|
||||||
|
|
||||||
|
return tmp_semaphore;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
int MakeAndRunTest(cl_device_id device, cl_context context,
|
||||||
|
cl_command_queue queue, cl_int nelems)
|
||||||
|
{
|
||||||
|
cl_int status = TEST_PASS;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto test_fixture = T(device, context, queue, nelems);
|
||||||
|
status = test_fixture.SetUp();
|
||||||
|
if (status != TEST_PASS) return status;
|
||||||
|
status = test_fixture.Run();
|
||||||
|
} catch (const std::runtime_error &e)
|
||||||
|
{
|
||||||
|
log_error("%s", e.what());
|
||||||
|
return TEST_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
@@ -16,37 +16,17 @@
|
|||||||
|
|
||||||
#include "semaphore_dx_fence_base.h"
|
#include "semaphore_dx_fence_base.h"
|
||||||
|
|
||||||
// Confirm that a signal followed by a wait in OpenCL will complete successfully
|
struct SignalWait final : DXFenceTestBase
|
||||||
REGISTER_TEST(test_external_semaphores_signal_wait)
|
|
||||||
{
|
{
|
||||||
int errcode = CL_SUCCESS;
|
using DXFenceTestBase::DXFenceTestBase;
|
||||||
const DirectXWrapper dx_wrapper;
|
|
||||||
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore");
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore_dx_fence");
|
|
||||||
|
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(device, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(device, clReleaseSemaphoreKHR);
|
|
||||||
GET_PFN(device, clEnqueueSignalSemaphoresKHR);
|
|
||||||
GET_PFN(device, clEnqueueWaitSemaphoresKHR);
|
|
||||||
|
|
||||||
test_error(!is_import_handle_available(device,
|
|
||||||
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR),
|
|
||||||
"Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between the "
|
|
||||||
"supported import types");
|
|
||||||
|
|
||||||
// Import D3D12 fence into OpenCL
|
|
||||||
const DirectXFenceWrapper fence(dx_wrapper.getDXDevice());
|
|
||||||
CLDXSemaphoreWrapper semaphore(device, context, dx_wrapper.getDXDevice());
|
|
||||||
test_error(semaphore.createSemaphoreFromFence(*fence),
|
|
||||||
"Could not create semaphore");
|
|
||||||
|
|
||||||
|
cl_int Run() override
|
||||||
|
{
|
||||||
log_info("Calling clEnqueueSignalSemaphoresKHR\n");
|
log_info("Calling clEnqueueSignalSemaphoresKHR\n");
|
||||||
constexpr cl_semaphore_payload_khr semaphore_payload = 1;
|
|
||||||
clEventWrapper signal_event;
|
clEventWrapper signal_event;
|
||||||
errcode = clEnqueueSignalSemaphoresKHR(
|
errcode = clEnqueueSignalSemaphoresKHR(queue, 1, &semaphore,
|
||||||
queue, 1, &semaphore, &semaphore_payload, 0, nullptr, &signal_event);
|
&semaphore_payload, 0, nullptr,
|
||||||
|
&signal_event);
|
||||||
test_error(errcode, "Failed to signal semaphore");
|
test_error(errcode, "Failed to signal semaphore");
|
||||||
|
|
||||||
log_info("Calling clEnqueueWaitSemaphoresKHR\n");
|
log_info("Calling clEnqueueWaitSemaphoresKHR\n");
|
||||||
@@ -64,43 +44,28 @@ REGISTER_TEST(test_external_semaphores_signal_wait)
|
|||||||
|
|
||||||
return TEST_PASS;
|
return TEST_PASS;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Confirm that a wait in OpenCL followed by a CPU signal in DX12 will complete
|
// Confirm that a signal followed by a wait in OpenCL will complete successfully
|
||||||
// successfully
|
REGISTER_TEST(test_external_semaphores_signal_wait)
|
||||||
REGISTER_TEST(test_external_semaphores_signal_dx_cpu)
|
|
||||||
{
|
{
|
||||||
int errcode = CL_SUCCESS;
|
return MakeAndRunTest<SignalWait>(device, context, queue, num_elements);
|
||||||
const DirectXWrapper dx_wrapper;
|
}
|
||||||
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore");
|
struct SignalDXCPU final : DXFenceTestBase
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore_dx_fence");
|
{
|
||||||
|
using DXFenceTestBase::DXFenceTestBase;
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(device, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(device, clReleaseSemaphoreKHR);
|
|
||||||
GET_PFN(device, clEnqueueSignalSemaphoresKHR);
|
|
||||||
GET_PFN(device, clEnqueueWaitSemaphoresKHR);
|
|
||||||
|
|
||||||
test_error(!is_import_handle_available(device,
|
|
||||||
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR),
|
|
||||||
"Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between the "
|
|
||||||
"supported import types");
|
|
||||||
|
|
||||||
// Import D3D12 fence into OpenCL
|
|
||||||
const DirectXFenceWrapper fence(dx_wrapper.getDXDevice());
|
|
||||||
CLDXSemaphoreWrapper semaphore(device, context, dx_wrapper.getDXDevice());
|
|
||||||
test_error(semaphore.createSemaphoreFromFence(*fence),
|
|
||||||
"Could not create semaphore");
|
|
||||||
|
|
||||||
|
cl_int Run() override
|
||||||
|
{
|
||||||
log_info("Calling clEnqueueWaitSemaphoresKHR\n");
|
log_info("Calling clEnqueueWaitSemaphoresKHR\n");
|
||||||
constexpr cl_semaphore_payload_khr semaphore_payload = 1;
|
|
||||||
clEventWrapper wait_event;
|
clEventWrapper wait_event;
|
||||||
errcode = clEnqueueWaitSemaphoresKHR(
|
errcode = clEnqueueWaitSemaphoresKHR(
|
||||||
queue, 1, &semaphore, &semaphore_payload, 0, nullptr, &wait_event);
|
queue, 1, &semaphore, &semaphore_payload, 0, nullptr, &wait_event);
|
||||||
test_error(errcode, "Failed to call clEnqueueWaitSemaphoresKHR");
|
test_error(errcode, "Failed to call clEnqueueWaitSemaphoresKHR");
|
||||||
|
|
||||||
log_info("Calling d3d12_fence->Signal()\n");
|
log_info("Calling d3d12_fence->Signal()\n");
|
||||||
const HRESULT hr = (*fence)->Signal(semaphore_payload);
|
const HRESULT hr = fence_wrapper->get()->Signal(semaphore_payload);
|
||||||
test_error(FAILED(hr), "Failed to signal D3D12 fence");
|
test_error(FAILED(hr), "Failed to signal D3D12 fence");
|
||||||
|
|
||||||
errcode = clFinish(queue);
|
errcode = clFinish(queue);
|
||||||
@@ -110,44 +75,30 @@ REGISTER_TEST(test_external_semaphores_signal_dx_cpu)
|
|||||||
|
|
||||||
return TEST_PASS;
|
return TEST_PASS;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Confirm that a wait in OpenCL followed by a GPU signal in DX12 will complete
|
// Confirm that a wait in OpenCL followed by a CPU signal in DX12 will complete
|
||||||
// successfully
|
// successfully
|
||||||
REGISTER_TEST(test_external_semaphores_signal_dx_gpu)
|
REGISTER_TEST(test_external_semaphores_signal_dx_cpu)
|
||||||
{
|
{
|
||||||
int errcode = CL_SUCCESS;
|
return MakeAndRunTest<SignalDXCPU>(device, context, queue, num_elements);
|
||||||
const DirectXWrapper dx_wrapper;
|
}
|
||||||
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore");
|
struct SignalDXGPU final : DXFenceTestBase
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore_dx_fence");
|
{
|
||||||
|
using DXFenceTestBase::DXFenceTestBase;
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(device, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(device, clReleaseSemaphoreKHR);
|
|
||||||
GET_PFN(device, clEnqueueSignalSemaphoresKHR);
|
|
||||||
GET_PFN(device, clEnqueueWaitSemaphoresKHR);
|
|
||||||
|
|
||||||
test_error(!is_import_handle_available(device,
|
|
||||||
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR),
|
|
||||||
"Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between the "
|
|
||||||
"supported import types");
|
|
||||||
|
|
||||||
// Import D3D12 fence into OpenCL
|
|
||||||
const DirectXFenceWrapper fence(dx_wrapper.getDXDevice());
|
|
||||||
CLDXSemaphoreWrapper semaphore(device, context, dx_wrapper.getDXDevice());
|
|
||||||
test_error(semaphore.createSemaphoreFromFence(*fence),
|
|
||||||
"Could not create semaphore");
|
|
||||||
|
|
||||||
|
cl_int Run() override
|
||||||
|
{
|
||||||
log_info("Calling clEnqueueWaitSemaphoresKHR\n");
|
log_info("Calling clEnqueueWaitSemaphoresKHR\n");
|
||||||
constexpr cl_semaphore_payload_khr semaphore_payload = 1;
|
|
||||||
clEventWrapper wait_event;
|
clEventWrapper wait_event;
|
||||||
errcode = clEnqueueWaitSemaphoresKHR(
|
errcode = clEnqueueWaitSemaphoresKHR(
|
||||||
queue, 1, &semaphore, &semaphore_payload, 0, nullptr, &wait_event);
|
queue, 1, &semaphore, &semaphore_payload, 0, nullptr, &wait_event);
|
||||||
test_error(errcode, "Failed to call clEnqueueWaitSemaphoresKHR");
|
test_error(errcode, "Failed to call clEnqueueWaitSemaphoresKHR");
|
||||||
|
|
||||||
log_info("Calling d3d12_command_queue->Signal()\n");
|
log_info("Calling d3d12_command_queue->Signal()\n");
|
||||||
const HRESULT hr =
|
const HRESULT hr = dx_wrapper.getDXCommandQueue()->Signal(
|
||||||
dx_wrapper.getDXCommandQueue()->Signal(*fence, semaphore_payload);
|
fence_wrapper->get(), semaphore_payload);
|
||||||
test_error(FAILED(hr), "Failed to signal D3D12 fence");
|
test_error(FAILED(hr), "Failed to signal D3D12 fence");
|
||||||
|
|
||||||
errcode = clFinish(queue);
|
errcode = clFinish(queue);
|
||||||
@@ -157,48 +108,36 @@ REGISTER_TEST(test_external_semaphores_signal_dx_gpu)
|
|||||||
|
|
||||||
return TEST_PASS;
|
return TEST_PASS;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Confirm that interlocking waits between OpenCL and DX12 will complete
|
// Confirm that a wait in OpenCL followed by a GPU signal in DX12 will complete
|
||||||
// successfully
|
// successfully
|
||||||
REGISTER_TEST(test_external_semaphores_cl_dx_interlock)
|
REGISTER_TEST(test_external_semaphores_signal_dx_gpu)
|
||||||
{
|
{
|
||||||
int errcode = CL_SUCCESS;
|
return MakeAndRunTest<SignalDXGPU>(device, context, queue, num_elements);
|
||||||
const DirectXWrapper dx_wrapper;
|
}
|
||||||
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore");
|
struct CLDXInterlock final : DXFenceTestBase
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore_dx_fence");
|
{
|
||||||
|
using DXFenceTestBase::DXFenceTestBase;
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(device, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(device, clReleaseSemaphoreKHR);
|
|
||||||
GET_PFN(device, clEnqueueSignalSemaphoresKHR);
|
|
||||||
GET_PFN(device, clEnqueueWaitSemaphoresKHR);
|
|
||||||
|
|
||||||
test_error(!is_import_handle_available(device,
|
|
||||||
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR),
|
|
||||||
"Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between the "
|
|
||||||
"supported import types");
|
|
||||||
|
|
||||||
// Import D3D12 fence into OpenCL
|
|
||||||
const DirectXFenceWrapper fence(dx_wrapper.getDXDevice());
|
|
||||||
CLDXSemaphoreWrapper semaphore(device, context, dx_wrapper.getDXDevice());
|
|
||||||
test_error(semaphore.createSemaphoreFromFence(*fence),
|
|
||||||
"Could not create semaphore");
|
|
||||||
|
|
||||||
|
cl_int Run() override
|
||||||
|
{
|
||||||
log_info("Calling d3d12_command_queue->Wait(1)\n");
|
log_info("Calling d3d12_command_queue->Wait(1)\n");
|
||||||
cl_semaphore_payload_khr semaphore_payload = 1;
|
HRESULT hr = dx_wrapper.getDXCommandQueue()->Wait(fence_wrapper->get(),
|
||||||
HRESULT hr =
|
semaphore_payload);
|
||||||
dx_wrapper.getDXCommandQueue()->Wait(*fence, semaphore_payload);
|
|
||||||
test_error(FAILED(hr), "Failed to wait on D3D12 fence");
|
test_error(FAILED(hr), "Failed to wait on D3D12 fence");
|
||||||
|
|
||||||
log_info("Calling d3d12_command_queue->Signal(2)\n");
|
log_info("Calling d3d12_command_queue->Signal(2)\n");
|
||||||
hr = dx_wrapper.getDXCommandQueue()->Signal(*fence, semaphore_payload + 1);
|
hr = dx_wrapper.getDXCommandQueue()->Signal(fence_wrapper->get(),
|
||||||
|
semaphore_payload + 1);
|
||||||
test_error(FAILED(hr), "Failed to signal D3D12 fence");
|
test_error(FAILED(hr), "Failed to signal D3D12 fence");
|
||||||
|
|
||||||
log_info("Calling clEnqueueSignalSemaphoresKHR(1)\n");
|
log_info("Calling clEnqueueSignalSemaphoresKHR(1)\n");
|
||||||
clEventWrapper signal_event;
|
clEventWrapper signal_event;
|
||||||
errcode = clEnqueueSignalSemaphoresKHR(
|
errcode = clEnqueueSignalSemaphoresKHR(queue, 1, &semaphore,
|
||||||
queue, 1, &semaphore, &semaphore_payload, 0, nullptr, &signal_event);
|
&semaphore_payload, 0, nullptr,
|
||||||
|
&signal_event);
|
||||||
test_error(errcode, "Failed to call clEnqueueSignalSemaphoresKHR");
|
test_error(errcode, "Failed to call clEnqueueSignalSemaphoresKHR");
|
||||||
|
|
||||||
log_info("Calling clEnqueueWaitSemaphoresKHR(2)\n");
|
log_info("Calling clEnqueueWaitSemaphoresKHR(2)\n");
|
||||||
@@ -216,41 +155,52 @@ REGISTER_TEST(test_external_semaphores_cl_dx_interlock)
|
|||||||
|
|
||||||
return TEST_PASS;
|
return TEST_PASS;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Confirm that multiple waits in OpenCL followed by signals in DX12 and waits
|
// Confirm that interlocking waits between OpenCL and DX12 will complete
|
||||||
// in DX12 followed by signals in OpenCL complete successfully
|
// successfully
|
||||||
REGISTER_TEST(test_external_semaphores_multiple_wait_signal)
|
REGISTER_TEST(test_external_semaphores_cl_dx_interlock)
|
||||||
{
|
{
|
||||||
int errcode = CL_SUCCESS;
|
return MakeAndRunTest<CLDXInterlock>(device, context, queue, num_elements);
|
||||||
const DirectXWrapper dx_wrapper;
|
}
|
||||||
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore");
|
struct MultipleWaitSignal final : DXFenceTestBase
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore_dx_fence");
|
{
|
||||||
|
using DXFenceTestBase::DXFenceTestBase;
|
||||||
|
|
||||||
// Obtain pointers to semaphore's API
|
~MultipleWaitSignal() override
|
||||||
GET_PFN(device, clCreateSemaphoreWithPropertiesKHR);
|
{
|
||||||
GET_PFN(device, clReleaseSemaphoreKHR);
|
if (fence_handle_2)
|
||||||
GET_PFN(device, clEnqueueSignalSemaphoresKHR);
|
{
|
||||||
GET_PFN(device, clEnqueueWaitSemaphoresKHR);
|
CloseHandle(fence_handle_2);
|
||||||
|
fence_handle_2 = nullptr;
|
||||||
|
}
|
||||||
|
if (fence_wrapper_2)
|
||||||
|
{
|
||||||
|
delete fence_wrapper_2;
|
||||||
|
fence_wrapper_2 = nullptr;
|
||||||
|
}
|
||||||
|
if (semaphore_2)
|
||||||
|
{
|
||||||
|
clReleaseSemaphoreKHR(semaphore_2);
|
||||||
|
semaphore_2 = nullptr;
|
||||||
|
}
|
||||||
|
DXFenceTestBase::~DXFenceTestBase();
|
||||||
|
};
|
||||||
|
|
||||||
test_error(!is_import_handle_available(device,
|
int SetUp() override
|
||||||
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR),
|
{
|
||||||
"Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between the "
|
DXFenceTestBase::SetUp();
|
||||||
"supported import types");
|
fence_wrapper_2 = new DirectXFenceWrapper(dx_wrapper.getDXDevice());
|
||||||
|
semaphore_2 = createSemaphoreFromFence(fence_wrapper_2->get());
|
||||||
|
test_assert_error(!!semaphore_2, "Could not create semaphore");
|
||||||
|
|
||||||
// Import D3D12 fence into OpenCL
|
return TEST_PASS;
|
||||||
const DirectXFenceWrapper fence_1(dx_wrapper.getDXDevice());
|
}
|
||||||
CLDXSemaphoreWrapper semaphore_1(device, context, dx_wrapper.getDXDevice());
|
|
||||||
test_error(semaphore_1.createSemaphoreFromFence(*fence_1),
|
|
||||||
"Could not create semaphore");
|
|
||||||
|
|
||||||
const DirectXFenceWrapper fence_2(dx_wrapper.getDXDevice());
|
cl_int Run() override
|
||||||
CLDXSemaphoreWrapper semaphore_2(device, context, dx_wrapper.getDXDevice());
|
{
|
||||||
test_error(semaphore_2.createSemaphoreFromFence(*fence_2),
|
const cl_semaphore_khr semaphore_list[] = { semaphore, semaphore_2 };
|
||||||
"Could not create semaphore");
|
|
||||||
|
|
||||||
const cl_semaphore_khr semaphore_list[] = { *semaphore_1, *semaphore_2 };
|
|
||||||
constexpr cl_semaphore_payload_khr semaphore_payload = 1;
|
|
||||||
cl_semaphore_payload_khr semaphore_payload_list[] = {
|
cl_semaphore_payload_khr semaphore_payload_list[] = {
|
||||||
semaphore_payload, semaphore_payload + 1
|
semaphore_payload, semaphore_payload + 1
|
||||||
};
|
};
|
||||||
@@ -263,16 +213,20 @@ REGISTER_TEST(test_external_semaphores_multiple_wait_signal)
|
|||||||
test_error(errcode, "Failed to call clEnqueueWaitSemaphoresKHR");
|
test_error(errcode, "Failed to call clEnqueueWaitSemaphoresKHR");
|
||||||
|
|
||||||
log_info("Calling d3d12_command_queue->Signal()\n");
|
log_info("Calling d3d12_command_queue->Signal()\n");
|
||||||
HRESULT hr =
|
HRESULT hr = dx_wrapper.getDXCommandQueue()->Signal(
|
||||||
dx_wrapper.getDXCommandQueue()->Signal(*fence_2, semaphore_payload + 1);
|
fence_wrapper_2->get(), semaphore_payload + 1);
|
||||||
test_error(FAILED(hr), "Failed to signal D3D12 fence 2");
|
test_error(FAILED(hr), "Failed to signal D3D12 fence 2");
|
||||||
hr = dx_wrapper.getDXCommandQueue()->Signal(*fence_1, semaphore_payload);
|
hr = dx_wrapper.getDXCommandQueue()->Signal(fence_wrapper->get(),
|
||||||
|
semaphore_payload);
|
||||||
test_error(FAILED(hr), "Failed to signal D3D12 fence 1");
|
test_error(FAILED(hr), "Failed to signal D3D12 fence 1");
|
||||||
|
|
||||||
log_info("Calling d3d12_command_queue->Wait() with different payloads\n");
|
log_info(
|
||||||
hr = dx_wrapper.getDXCommandQueue()->Wait(*fence_1, semaphore_payload + 3);
|
"Calling d3d12_command_queue->Wait() with different payloads\n");
|
||||||
|
hr = dx_wrapper.getDXCommandQueue()->Wait(fence_wrapper->get(),
|
||||||
|
semaphore_payload + 3);
|
||||||
test_error(FAILED(hr), "Failed to wait on D3D12 fence 1");
|
test_error(FAILED(hr), "Failed to wait on D3D12 fence 1");
|
||||||
hr = dx_wrapper.getDXCommandQueue()->Wait(*fence_2, semaphore_payload + 2);
|
hr = dx_wrapper.getDXCommandQueue()->Wait(fence_wrapper_2->get(),
|
||||||
|
semaphore_payload + 2);
|
||||||
test_error(FAILED(hr), "Failed to wait on D3D12 fence 2");
|
test_error(FAILED(hr), "Failed to wait on D3D12 fence 2");
|
||||||
|
|
||||||
errcode = clFinish(queue);
|
errcode = clFinish(queue);
|
||||||
@@ -286,29 +240,31 @@ REGISTER_TEST(test_external_semaphores_multiple_wait_signal)
|
|||||||
log_info("Calling clEnqueueSignalSemaphoresKHR\n");
|
log_info("Calling clEnqueueSignalSemaphoresKHR\n");
|
||||||
clEventWrapper signal_event;
|
clEventWrapper signal_event;
|
||||||
errcode = clEnqueueSignalSemaphoresKHR(queue, 2, semaphore_list,
|
errcode = clEnqueueSignalSemaphoresKHR(queue, 2, semaphore_list,
|
||||||
semaphore_payload_list, 0, nullptr,
|
semaphore_payload_list, 0,
|
||||||
&signal_event);
|
nullptr, &signal_event);
|
||||||
test_error(errcode, "Could not call clEnqueueSignalSemaphoresKHR");
|
test_error(errcode, "Could not call clEnqueueSignalSemaphoresKHR");
|
||||||
|
|
||||||
// Wait until the GPU has completed commands up to this fence point.
|
// Wait until the GPU has completed commands up to this fence point.
|
||||||
log_info("Waiting for D3D12 command queue completion\n");
|
log_info("Waiting for D3D12 command queue completion\n");
|
||||||
if ((*fence_1)->GetCompletedValue() < semaphore_payload_list[0])
|
if (fence_wrapper->get()->GetCompletedValue()
|
||||||
|
< semaphore_payload_list[0])
|
||||||
{
|
{
|
||||||
const HANDLE event_handle =
|
const HANDLE event_handle =
|
||||||
CreateEventEx(nullptr, false, false, EVENT_ALL_ACCESS);
|
CreateEventEx(nullptr, nullptr, false, EVENT_ALL_ACCESS);
|
||||||
hr = (*fence_1)->SetEventOnCompletion(semaphore_payload_list[0],
|
hr = fence_wrapper->get()->SetEventOnCompletion(
|
||||||
event_handle);
|
semaphore_payload_list[0], event_handle);
|
||||||
test_error(FAILED(hr),
|
test_error(FAILED(hr),
|
||||||
"Failed to set D3D12 fence 1 event on completion");
|
"Failed to set D3D12 fence 1 event on completion");
|
||||||
WaitForSingleObject(event_handle, INFINITE);
|
WaitForSingleObject(event_handle, INFINITE);
|
||||||
CloseHandle(event_handle);
|
CloseHandle(event_handle);
|
||||||
}
|
}
|
||||||
if ((*fence_2)->GetCompletedValue() < semaphore_payload_list[1])
|
if (fence_wrapper_2->get()->GetCompletedValue()
|
||||||
|
< semaphore_payload_list[1])
|
||||||
{
|
{
|
||||||
const HANDLE event_handle =
|
const HANDLE event_handle =
|
||||||
CreateEventEx(nullptr, false, false, EVENT_ALL_ACCESS);
|
CreateEventEx(nullptr, nullptr, false, EVENT_ALL_ACCESS);
|
||||||
hr = (*fence_2)->SetEventOnCompletion(semaphore_payload_list[1],
|
hr = fence_wrapper_2->get()->SetEventOnCompletion(
|
||||||
event_handle);
|
semaphore_payload_list[1], event_handle);
|
||||||
test_error(FAILED(hr),
|
test_error(FAILED(hr),
|
||||||
"Failed to set D3D12 fence 2 event on completion");
|
"Failed to set D3D12 fence 2 event on completion");
|
||||||
WaitForSingleObject(event_handle, INFINITE);
|
WaitForSingleObject(event_handle, INFINITE);
|
||||||
@@ -322,3 +278,17 @@ REGISTER_TEST(test_external_semaphores_multiple_wait_signal)
|
|||||||
|
|
||||||
return TEST_PASS;
|
return TEST_PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
cl_semaphore_khr semaphore_2 = nullptr;
|
||||||
|
HANDLE fence_handle_2 = nullptr;
|
||||||
|
DirectXFenceWrapper *fence_wrapper_2 = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Confirm that multiple waits in OpenCL followed by signals in DX12 and waits
|
||||||
|
// in DX12 followed by signals in OpenCL complete successfully
|
||||||
|
REGISTER_TEST(test_external_semaphores_multiple_wait_signal)
|
||||||
|
{
|
||||||
|
return MakeAndRunTest<MultipleWaitSignal>(device, context, queue,
|
||||||
|
num_elements);
|
||||||
|
}
|
||||||
@@ -16,28 +16,16 @@
|
|||||||
|
|
||||||
#include "semaphore_dx_fence_base.h"
|
#include "semaphore_dx_fence_base.h"
|
||||||
|
|
||||||
// Confirm that a wait followed by a signal in DirectX 12 using an exported
|
struct ExportDXSignal final : DXFenceTestBase
|
||||||
// semaphore will complete successfully
|
|
||||||
REGISTER_TEST(test_external_semaphores_export_dx_signal)
|
|
||||||
{
|
{
|
||||||
int errcode = CL_SUCCESS;
|
using DXFenceTestBase::DXFenceTestBase;
|
||||||
const DirectXWrapper dx_wrapper;
|
|
||||||
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore");
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore_dx_fence");
|
|
||||||
|
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(device, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(device, clReleaseSemaphoreKHR);
|
|
||||||
GET_PFN(device, clEnqueueSignalSemaphoresKHR);
|
|
||||||
GET_PFN(device, clEnqueueWaitSemaphoresKHR);
|
|
||||||
GET_PFN(device, clGetSemaphoreInfoKHR);
|
|
||||||
GET_PFN(device, clGetSemaphoreHandleForTypeKHR);
|
|
||||||
|
|
||||||
|
int Run() override
|
||||||
|
{
|
||||||
size_t export_types_size = 0;
|
size_t export_types_size = 0;
|
||||||
errcode =
|
errcode =
|
||||||
clGetDeviceInfo(device, CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR, 0,
|
clGetDeviceInfo(device, CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR,
|
||||||
nullptr, &export_types_size);
|
0, nullptr, &export_types_size);
|
||||||
test_error(errcode, "Could not query export semaphore handle types");
|
test_error(errcode, "Could not query export semaphore handle types");
|
||||||
std::vector<cl_external_semaphore_handle_type_khr> export_types(
|
std::vector<cl_external_semaphore_handle_type_khr> export_types(
|
||||||
export_types_size / sizeof(cl_external_semaphore_handle_type_khr));
|
export_types_size / sizeof(cl_external_semaphore_handle_type_khr));
|
||||||
@@ -50,14 +38,16 @@ REGISTER_TEST(test_external_semaphores_export_dx_signal)
|
|||||||
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR)
|
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR)
|
||||||
== export_types.end())
|
== export_types.end())
|
||||||
{
|
{
|
||||||
log_info("Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between "
|
log_info(
|
||||||
|
"Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between "
|
||||||
"the supported export types\n");
|
"the supported export types\n");
|
||||||
return TEST_FAIL;
|
return TEST_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr cl_semaphore_properties_khr sem_props[] = {
|
constexpr cl_semaphore_properties_khr sem_props[] = {
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_KHR),
|
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_KHR),
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_BINARY_KHR),
|
static_cast<cl_semaphore_properties_khr>(
|
||||||
|
CL_SEMAPHORE_TYPE_BINARY_KHR),
|
||||||
static_cast<cl_semaphore_properties_khr>(
|
static_cast<cl_semaphore_properties_khr>(
|
||||||
CL_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR),
|
CL_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR),
|
||||||
static_cast<cl_semaphore_properties_khr>(
|
static_cast<cl_semaphore_properties_khr>(
|
||||||
@@ -66,37 +56,37 @@ REGISTER_TEST(test_external_semaphores_export_dx_signal)
|
|||||||
CL_SEMAPHORE_EXPORT_HANDLE_TYPES_LIST_END_KHR),
|
CL_SEMAPHORE_EXPORT_HANDLE_TYPES_LIST_END_KHR),
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
cl_semaphore_khr semaphore =
|
cl_semaphore_khr exportable_semaphore =
|
||||||
clCreateSemaphoreWithPropertiesKHR(context, sem_props, &errcode);
|
clCreateSemaphoreWithPropertiesKHR(context, sem_props, &errcode);
|
||||||
test_error(errcode, "Could not create semaphore");
|
test_error(errcode, "Could not create semaphore");
|
||||||
|
|
||||||
cl_bool is_exportable = CL_FALSE;
|
cl_bool is_exportable = CL_FALSE;
|
||||||
errcode =
|
errcode = clGetSemaphoreInfoKHR(
|
||||||
clGetSemaphoreInfoKHR(semaphore, CL_SEMAPHORE_EXPORTABLE_KHR,
|
exportable_semaphore, CL_SEMAPHORE_EXPORTABLE_KHR,
|
||||||
sizeof(is_exportable), &is_exportable, nullptr);
|
sizeof(is_exportable), &is_exportable, nullptr);
|
||||||
test_error(errcode, "Could not get semaphore info");
|
test_error(errcode, "Could not get semaphore info");
|
||||||
test_error(!is_exportable, "Semaphore is not exportable");
|
test_error(!is_exportable, "Semaphore is not exportable");
|
||||||
|
|
||||||
log_info("Calling clEnqueueWaitSemaphoresKHR\n");
|
log_info("Calling clEnqueueWaitSemaphoresKHR\n");
|
||||||
constexpr cl_semaphore_payload_khr semaphore_payload = 1;
|
|
||||||
clEventWrapper wait_event;
|
clEventWrapper wait_event;
|
||||||
errcode = clEnqueueWaitSemaphoresKHR(
|
errcode = clEnqueueWaitSemaphoresKHR(queue, 1, &exportable_semaphore,
|
||||||
queue, 1, &semaphore, &semaphore_payload, 0, nullptr, &wait_event);
|
&semaphore_payload, 0, nullptr,
|
||||||
|
&wait_event);
|
||||||
test_error(errcode, "Failed to wait semaphore");
|
test_error(errcode, "Failed to wait semaphore");
|
||||||
|
|
||||||
HANDLE semaphore_handle = nullptr;
|
HANDLE semaphore_handle = nullptr;
|
||||||
errcode = clGetSemaphoreHandleForTypeKHR(
|
errcode = clGetSemaphoreHandleForTypeKHR(
|
||||||
semaphore, device, CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR,
|
exportable_semaphore, device, CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR,
|
||||||
sizeof(semaphore_handle), &semaphore_handle, nullptr);
|
sizeof(semaphore_handle), &semaphore_handle, nullptr);
|
||||||
test_error(errcode, "Could not get semaphore handle");
|
test_error(errcode, "Could not get semaphore handle");
|
||||||
|
|
||||||
ID3D12Fence *fence = nullptr;
|
ID3D12Fence *exported_fence = nullptr;
|
||||||
errcode = dx_wrapper.getDXDevice()->OpenSharedHandle(semaphore_handle,
|
errcode = dx_wrapper.getDXDevice()->OpenSharedHandle(
|
||||||
IID_PPV_ARGS(&fence));
|
semaphore_handle, IID_PPV_ARGS(&exported_fence));
|
||||||
test_error(errcode, "Could not open semaphore handle");
|
test_error(errcode, "Could not open semaphore handle");
|
||||||
|
|
||||||
log_info("Calling fence->Signal()\n");
|
log_info("Calling fence->Signal()\n");
|
||||||
const HRESULT hr = fence->Signal(semaphore_payload);
|
const HRESULT hr = exported_fence->Signal(semaphore_payload);
|
||||||
test_error(FAILED(hr), "Failed to signal D3D12 fence");
|
test_error(FAILED(hr), "Failed to signal D3D12 fence");
|
||||||
|
|
||||||
errcode = clFinish(queue);
|
errcode = clFinish(queue);
|
||||||
@@ -106,34 +96,31 @@ REGISTER_TEST(test_external_semaphores_export_dx_signal)
|
|||||||
|
|
||||||
// Release resources
|
// Release resources
|
||||||
CloseHandle(semaphore_handle);
|
CloseHandle(semaphore_handle);
|
||||||
test_error(clReleaseSemaphoreKHR(semaphore), "Could not release semaphore");
|
test_error(clReleaseSemaphoreKHR(exportable_semaphore),
|
||||||
fence->Release();
|
"Could not release semaphore");
|
||||||
|
exported_fence->Release();
|
||||||
|
|
||||||
return TEST_PASS;
|
return TEST_PASS;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Confirm that a signal in OpenCL followed by a wait in DirectX 12 using an
|
// Confirm that a wait followed by a signal in DirectX 12 using an exported
|
||||||
// exported semaphore will complete successfully
|
// semaphore will complete successfully
|
||||||
REGISTER_TEST(test_external_semaphores_export_dx_wait)
|
REGISTER_TEST(test_external_semaphores_export_dx_signal)
|
||||||
{
|
{
|
||||||
int errcode = CL_SUCCESS;
|
return MakeAndRunTest<ExportDXSignal>(device, context, queue, num_elements);
|
||||||
const DirectXWrapper dx_wrapper;
|
}
|
||||||
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore");
|
struct ExportDXWait final : DXFenceTestBase
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore_dx_fence");
|
{
|
||||||
|
using DXFenceTestBase::DXFenceTestBase;
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(device, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(device, clReleaseSemaphoreKHR);
|
|
||||||
GET_PFN(device, clEnqueueSignalSemaphoresKHR);
|
|
||||||
GET_PFN(device, clEnqueueWaitSemaphoresKHR);
|
|
||||||
GET_PFN(device, clGetSemaphoreInfoKHR);
|
|
||||||
GET_PFN(device, clGetSemaphoreHandleForTypeKHR);
|
|
||||||
|
|
||||||
|
int Run() override
|
||||||
|
{
|
||||||
size_t export_types_size = 0;
|
size_t export_types_size = 0;
|
||||||
errcode =
|
errcode =
|
||||||
clGetDeviceInfo(device, CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR, 0,
|
clGetDeviceInfo(device, CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR,
|
||||||
nullptr, &export_types_size);
|
0, nullptr, &export_types_size);
|
||||||
test_error(errcode, "Could not query export semaphore handle types");
|
test_error(errcode, "Could not query export semaphore handle types");
|
||||||
std::vector<cl_external_semaphore_handle_type_khr> export_types(
|
std::vector<cl_external_semaphore_handle_type_khr> export_types(
|
||||||
export_types_size / sizeof(cl_external_semaphore_handle_type_khr));
|
export_types_size / sizeof(cl_external_semaphore_handle_type_khr));
|
||||||
@@ -146,14 +133,16 @@ REGISTER_TEST(test_external_semaphores_export_dx_wait)
|
|||||||
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR)
|
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR)
|
||||||
== export_types.end())
|
== export_types.end())
|
||||||
{
|
{
|
||||||
log_info("Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between "
|
log_info(
|
||||||
|
"Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between "
|
||||||
"the supported export types\n");
|
"the supported export types\n");
|
||||||
return TEST_FAIL;
|
return TEST_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr cl_semaphore_properties_khr sem_props[] = {
|
constexpr cl_semaphore_properties_khr sem_props[] = {
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_KHR),
|
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_KHR),
|
||||||
static_cast<cl_semaphore_properties_khr>(CL_SEMAPHORE_TYPE_BINARY_KHR),
|
static_cast<cl_semaphore_properties_khr>(
|
||||||
|
CL_SEMAPHORE_TYPE_BINARY_KHR),
|
||||||
static_cast<cl_semaphore_properties_khr>(
|
static_cast<cl_semaphore_properties_khr>(
|
||||||
CL_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR),
|
CL_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR),
|
||||||
static_cast<cl_semaphore_properties_khr>(
|
static_cast<cl_semaphore_properties_khr>(
|
||||||
@@ -162,13 +151,13 @@ REGISTER_TEST(test_external_semaphores_export_dx_wait)
|
|||||||
CL_SEMAPHORE_EXPORT_HANDLE_TYPES_LIST_END_KHR),
|
CL_SEMAPHORE_EXPORT_HANDLE_TYPES_LIST_END_KHR),
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
cl_semaphore_khr semaphore =
|
cl_semaphore_khr exportable_semaphore =
|
||||||
clCreateSemaphoreWithPropertiesKHR(context, sem_props, &errcode);
|
clCreateSemaphoreWithPropertiesKHR(context, sem_props, &errcode);
|
||||||
test_error(errcode, "Could not create semaphore");
|
test_error(errcode, "Could not create semaphore");
|
||||||
|
|
||||||
cl_bool is_exportable = CL_FALSE;
|
cl_bool is_exportable = CL_FALSE;
|
||||||
errcode =
|
errcode = clGetSemaphoreInfoKHR(
|
||||||
clGetSemaphoreInfoKHR(semaphore, CL_SEMAPHORE_EXPORTABLE_KHR,
|
exportable_semaphore, CL_SEMAPHORE_EXPORTABLE_KHR,
|
||||||
sizeof(is_exportable), &is_exportable, nullptr);
|
sizeof(is_exportable), &is_exportable, nullptr);
|
||||||
test_error(errcode, "Could not get semaphore info");
|
test_error(errcode, "Could not get semaphore info");
|
||||||
test_error(!is_exportable, "Semaphore is not exportable");
|
test_error(!is_exportable, "Semaphore is not exportable");
|
||||||
@@ -176,31 +165,33 @@ REGISTER_TEST(test_external_semaphores_export_dx_wait)
|
|||||||
log_info("Calling clEnqueueSignalSemaphoresKHR\n");
|
log_info("Calling clEnqueueSignalSemaphoresKHR\n");
|
||||||
constexpr cl_semaphore_payload_khr semaphore_payload = 1;
|
constexpr cl_semaphore_payload_khr semaphore_payload = 1;
|
||||||
clEventWrapper signal_event;
|
clEventWrapper signal_event;
|
||||||
errcode = clEnqueueSignalSemaphoresKHR(
|
errcode = clEnqueueSignalSemaphoresKHR(queue, 1, &exportable_semaphore,
|
||||||
queue, 1, &semaphore, &semaphore_payload, 0, nullptr, &signal_event);
|
&semaphore_payload, 0, nullptr,
|
||||||
|
&signal_event);
|
||||||
test_error(errcode, "Failed to signal semaphore");
|
test_error(errcode, "Failed to signal semaphore");
|
||||||
|
|
||||||
HANDLE semaphore_handle = nullptr;
|
HANDLE semaphore_handle = nullptr;
|
||||||
errcode = clGetSemaphoreHandleForTypeKHR(
|
errcode = clGetSemaphoreHandleForTypeKHR(
|
||||||
semaphore, device, CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR,
|
exportable_semaphore, device, CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR,
|
||||||
sizeof(semaphore_handle), &semaphore_handle, nullptr);
|
sizeof(semaphore_handle), &semaphore_handle, nullptr);
|
||||||
test_error(errcode, "Could not get semaphore handle");
|
test_error(errcode, "Could not get semaphore handle");
|
||||||
|
|
||||||
ID3D12Fence *fence = nullptr;
|
ID3D12Fence *exported_fence = nullptr;
|
||||||
errcode = dx_wrapper.getDXDevice()->OpenSharedHandle(semaphore_handle,
|
errcode = dx_wrapper.getDXDevice()->OpenSharedHandle(
|
||||||
IID_PPV_ARGS(&fence));
|
semaphore_handle, IID_PPV_ARGS(&exported_fence));
|
||||||
test_error(errcode, "Could not open semaphore handle");
|
test_error(errcode, "Could not open semaphore handle");
|
||||||
|
|
||||||
log_info("Calling dx_wrapper.get_d3d12_command_queue()->Wait()\n");
|
log_info("Calling dx_wrapper.get_d3d12_command_queue()->Wait()\n");
|
||||||
HRESULT hr = dx_wrapper.getDXCommandQueue()->Wait(fence, semaphore_payload);
|
HRESULT hr = dx_wrapper.getDXCommandQueue()->Wait(exported_fence,
|
||||||
|
semaphore_payload);
|
||||||
test_error(FAILED(hr), "Failed to wait on D3D12 fence");
|
test_error(FAILED(hr), "Failed to wait on D3D12 fence");
|
||||||
|
|
||||||
log_info("Calling WaitForSingleObject\n");
|
log_info("Calling WaitForSingleObject\n");
|
||||||
if (fence->GetCompletedValue() < semaphore_payload)
|
if (exported_fence->GetCompletedValue() < semaphore_payload)
|
||||||
{
|
{
|
||||||
const HANDLE event =
|
const HANDLE event =
|
||||||
CreateEventEx(nullptr, false, false, EVENT_ALL_ACCESS);
|
CreateEventEx(nullptr, nullptr, false, EVENT_ALL_ACCESS);
|
||||||
hr = fence->SetEventOnCompletion(semaphore_payload, event);
|
hr = exported_fence->SetEventOnCompletion(semaphore_payload, event);
|
||||||
test_error(FAILED(hr), "Failed to set event on completion");
|
test_error(FAILED(hr), "Failed to set event on completion");
|
||||||
WaitForSingleObject(event, INFINITE);
|
WaitForSingleObject(event, INFINITE);
|
||||||
CloseHandle(event);
|
CloseHandle(event);
|
||||||
@@ -213,8 +204,17 @@ REGISTER_TEST(test_external_semaphores_export_dx_wait)
|
|||||||
|
|
||||||
// Release resources
|
// Release resources
|
||||||
CloseHandle(semaphore_handle);
|
CloseHandle(semaphore_handle);
|
||||||
test_error(clReleaseSemaphoreKHR(semaphore), "Could not release semaphore");
|
test_error(clReleaseSemaphoreKHR(exportable_semaphore),
|
||||||
fence->Release();
|
"Could not release semaphore");
|
||||||
|
exported_fence->Release();
|
||||||
|
|
||||||
return TEST_PASS;
|
return TEST_PASS;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Confirm that a signal in OpenCL followed by a wait in DirectX 12 using an
|
||||||
|
// exported semaphore will complete successfully
|
||||||
|
REGISTER_TEST(test_external_semaphores_export_dx_wait)
|
||||||
|
{
|
||||||
|
return MakeAndRunTest<ExportDXWait>(device, context, queue, num_elements);
|
||||||
|
}
|
||||||
@@ -16,32 +16,12 @@
|
|||||||
|
|
||||||
#include "semaphore_dx_fence_base.h"
|
#include "semaphore_dx_fence_base.h"
|
||||||
|
|
||||||
// Confirm that a wait without a semaphore payload list will return
|
struct DXFenceNegativeWait final : DXFenceTestBase
|
||||||
// CL_INVALID_VALUE
|
|
||||||
REGISTER_TEST(test_external_semaphores_dx_fence_negative_wait)
|
|
||||||
{
|
{
|
||||||
int errcode = CL_SUCCESS;
|
using DXFenceTestBase::DXFenceTestBase;
|
||||||
const DirectXWrapper dx_wrapper;
|
|
||||||
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore");
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore_dx_fence");
|
|
||||||
|
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(device, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(device, clReleaseSemaphoreKHR);
|
|
||||||
GET_PFN(device, clEnqueueWaitSemaphoresKHR);
|
|
||||||
|
|
||||||
test_error(!is_import_handle_available(device,
|
|
||||||
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR),
|
|
||||||
"Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between the "
|
|
||||||
"supported import types");
|
|
||||||
|
|
||||||
// Import D3D12 fence into OpenCL
|
|
||||||
const DirectXFenceWrapper fence(dx_wrapper.getDXDevice());
|
|
||||||
CLDXSemaphoreWrapper semaphore(device, context, dx_wrapper.getDXDevice());
|
|
||||||
test_error(semaphore.createSemaphoreFromFence(*fence),
|
|
||||||
"Could not create semaphore");
|
|
||||||
|
|
||||||
|
int Run() override
|
||||||
|
{
|
||||||
log_info("Calling clEnqueueWaitSemaphoresKHR\n");
|
log_info("Calling clEnqueueWaitSemaphoresKHR\n");
|
||||||
errcode = clEnqueueWaitSemaphoresKHR(queue, 1, &semaphore, nullptr, 0,
|
errcode = clEnqueueWaitSemaphoresKHR(queue, 1, &semaphore, nullptr, 0,
|
||||||
nullptr, nullptr);
|
nullptr, nullptr);
|
||||||
@@ -51,33 +31,22 @@ REGISTER_TEST(test_external_semaphores_dx_fence_negative_wait)
|
|||||||
|
|
||||||
return TEST_PASS;
|
return TEST_PASS;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Confirm that a signal without a semaphore payload list will return
|
// Confirm that a wait without a semaphore payload list will return
|
||||||
// CL_INVALID_VALUE
|
// CL_INVALID_VALUE
|
||||||
REGISTER_TEST(test_external_semaphores_dx_fence_negative_signal)
|
REGISTER_TEST(test_external_semaphores_dx_fence_negative_wait)
|
||||||
{
|
{
|
||||||
int errcode = CL_SUCCESS;
|
return MakeAndRunTest<DXFenceNegativeWait>(device, context, queue,
|
||||||
const DirectXWrapper dx_wrapper;
|
num_elements);
|
||||||
|
}
|
||||||
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore");
|
struct DXFenceNegativeSignal final : DXFenceTestBase
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore_dx_fence");
|
{
|
||||||
|
using DXFenceTestBase::DXFenceTestBase;
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(device, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(device, clReleaseSemaphoreKHR);
|
|
||||||
GET_PFN(device, clEnqueueSignalSemaphoresKHR);
|
|
||||||
|
|
||||||
test_error(!is_import_handle_available(device,
|
|
||||||
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR),
|
|
||||||
"Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between the "
|
|
||||||
"supported import types");
|
|
||||||
|
|
||||||
// Import D3D12 fence into OpenCL
|
|
||||||
const DirectXFenceWrapper fence(dx_wrapper.getDXDevice());
|
|
||||||
CLDXSemaphoreWrapper semaphore(device, context, dx_wrapper.getDXDevice());
|
|
||||||
test_error(semaphore.createSemaphoreFromFence(*fence),
|
|
||||||
"Could not create semaphore");
|
|
||||||
|
|
||||||
|
int Run() override
|
||||||
|
{
|
||||||
log_info("Calling clEnqueueWaitSemaphoresKHR\n");
|
log_info("Calling clEnqueueWaitSemaphoresKHR\n");
|
||||||
errcode = clEnqueueSignalSemaphoresKHR(queue, 1, &semaphore, nullptr, 0,
|
errcode = clEnqueueSignalSemaphoresKHR(queue, 1, &semaphore, nullptr, 0,
|
||||||
nullptr, nullptr);
|
nullptr, nullptr);
|
||||||
@@ -87,3 +56,12 @@ REGISTER_TEST(test_external_semaphores_dx_fence_negative_signal)
|
|||||||
|
|
||||||
return TEST_PASS;
|
return TEST_PASS;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Confirm that a signal without a semaphore payload list will return
|
||||||
|
// CL_INVALID_VALUE
|
||||||
|
REGISTER_TEST(test_external_semaphores_dx_fence_negative_signal)
|
||||||
|
{
|
||||||
|
return MakeAndRunTest<DXFenceNegativeSignal>(device, context, queue,
|
||||||
|
num_elements);
|
||||||
|
}
|
||||||
@@ -16,39 +16,19 @@
|
|||||||
|
|
||||||
#include "semaphore_dx_fence_base.h"
|
#include "semaphore_dx_fence_base.h"
|
||||||
|
|
||||||
// Confirm that the CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR property is in the
|
struct DXFenceQueryProperties final : DXFenceTestBase
|
||||||
// properties returned by clGetSemaphoreInfo
|
|
||||||
REGISTER_TEST(test_external_semaphores_dx_fence_query_properties)
|
|
||||||
{
|
{
|
||||||
int errcode = CL_SUCCESS;
|
using DXFenceTestBase::DXFenceTestBase;
|
||||||
const DirectXWrapper dx_wrapper;
|
|
||||||
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore");
|
|
||||||
REQUIRE_EXTENSION("cl_khr_external_semaphore_dx_fence");
|
|
||||||
|
|
||||||
// Obtain pointers to semaphore's API
|
|
||||||
GET_PFN(device, clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_PFN(device, clReleaseSemaphoreKHR);
|
|
||||||
GET_PFN(device, clGetSemaphoreInfoKHR);
|
|
||||||
|
|
||||||
test_error(!is_import_handle_available(device,
|
|
||||||
CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR),
|
|
||||||
"Could not find CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR between the "
|
|
||||||
"supported import types");
|
|
||||||
|
|
||||||
// Import D3D12 fence into OpenCL
|
|
||||||
const DirectXFenceWrapper fence(dx_wrapper.getDXDevice());
|
|
||||||
CLDXSemaphoreWrapper semaphore(device, context, dx_wrapper.getDXDevice());
|
|
||||||
test_error(semaphore.createSemaphoreFromFence(*fence),
|
|
||||||
"Could not create semaphore");
|
|
||||||
|
|
||||||
|
int Run() override
|
||||||
|
{
|
||||||
size_t properties_size_bytes = 0;
|
size_t properties_size_bytes = 0;
|
||||||
errcode = clGetSemaphoreInfoKHR(*semaphore, CL_SEMAPHORE_PROPERTIES_KHR, 0,
|
errcode = clGetSemaphoreInfoKHR(semaphore, CL_SEMAPHORE_PROPERTIES_KHR,
|
||||||
nullptr, &properties_size_bytes);
|
0, nullptr, &properties_size_bytes);
|
||||||
test_error(errcode, "Could not get semaphore info");
|
test_error(errcode, "Could not get semaphore info");
|
||||||
std::vector<cl_semaphore_properties_khr> semaphore_properties(
|
std::vector<cl_semaphore_properties_khr> semaphore_properties(
|
||||||
properties_size_bytes / sizeof(cl_semaphore_properties_khr));
|
properties_size_bytes / sizeof(cl_semaphore_properties_khr));
|
||||||
errcode = clGetSemaphoreInfoKHR(*semaphore, CL_SEMAPHORE_PROPERTIES_KHR,
|
errcode = clGetSemaphoreInfoKHR(semaphore, CL_SEMAPHORE_PROPERTIES_KHR,
|
||||||
properties_size_bytes,
|
properties_size_bytes,
|
||||||
semaphore_properties.data(), nullptr);
|
semaphore_properties.data(), nullptr);
|
||||||
test_error(errcode, "Could not get semaphore info");
|
test_error(errcode, "Could not get semaphore info");
|
||||||
@@ -58,12 +38,21 @@ REGISTER_TEST(test_external_semaphores_dx_fence_query_properties)
|
|||||||
if (semaphore_properties[i] == CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR
|
if (semaphore_properties[i] == CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR
|
||||||
&& semaphore_properties[i + 1]
|
&& semaphore_properties[i + 1]
|
||||||
== reinterpret_cast<cl_semaphore_properties_khr>(
|
== reinterpret_cast<cl_semaphore_properties_khr>(
|
||||||
semaphore.getHandle()))
|
fence_handle))
|
||||||
{
|
{
|
||||||
return TEST_PASS;
|
return TEST_PASS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log_error(
|
log_error("Failed to find the dx fence handle type in the semaphore "
|
||||||
"Failed to find the dx fence handle type in the semaphore properties");
|
"properties");
|
||||||
return TEST_FAIL;
|
return TEST_FAIL;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Confirm that the CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR property is in the
|
||||||
|
// properties returned by clGetSemaphoreInfo
|
||||||
|
REGISTER_TEST(test_external_semaphores_dx_fence_query_properties)
|
||||||
|
{
|
||||||
|
return MakeAndRunTest<DXFenceQueryProperties>(device, context, queue,
|
||||||
|
num_elements);
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "harness/deviceInfo.h"
|
#include "harness/deviceInfo.h"
|
||||||
#include "harness/testHarness.h"
|
#include "harness/testHarness.h"
|
||||||
#include "harness/typeWrappers.h"
|
#include "harness/typeWrappers.h"
|
||||||
|
#include "harness/extensionHelpers.h"
|
||||||
|
|
||||||
struct SemaphoreBase
|
struct SemaphoreBase
|
||||||
{
|
{
|
||||||
@@ -37,27 +38,15 @@ struct SemaphoreBase
|
|||||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_PLATFORM failed");
|
test_error(error, "clGetDeviceInfo for CL_DEVICE_PLATFORM failed");
|
||||||
|
|
||||||
// If it is supported get the addresses of all the APIs here.
|
// If it is supported get the addresses of all the APIs here.
|
||||||
// clang-format off
|
GET_FUNCTION_EXTENSION_ADDRESS(device,
|
||||||
#define GET_EXTENSION_ADDRESS(FUNC) \
|
clCreateSemaphoreWithPropertiesKHR);
|
||||||
FUNC = reinterpret_cast<FUNC##_fn>( \
|
GET_FUNCTION_EXTENSION_ADDRESS(device, clEnqueueSignalSemaphoresKHR);
|
||||||
clGetExtensionFunctionAddressForPlatform(platform, #FUNC)); \
|
GET_FUNCTION_EXTENSION_ADDRESS(device, clEnqueueWaitSemaphoresKHR);
|
||||||
if (FUNC == nullptr) \
|
GET_FUNCTION_EXTENSION_ADDRESS(device, clReleaseSemaphoreKHR);
|
||||||
{ \
|
GET_FUNCTION_EXTENSION_ADDRESS(device, clGetSemaphoreInfoKHR);
|
||||||
log_error("ERROR: clGetExtensionFunctionAddressForPlatform failed" \
|
GET_FUNCTION_EXTENSION_ADDRESS(device, clRetainSemaphoreKHR);
|
||||||
" with " #FUNC "\n"); \
|
GET_FUNCTION_EXTENSION_ADDRESS(device, clGetSemaphoreHandleForTypeKHR);
|
||||||
return TEST_FAIL; \
|
|
||||||
}
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
GET_EXTENSION_ADDRESS(clCreateSemaphoreWithPropertiesKHR);
|
|
||||||
GET_EXTENSION_ADDRESS(clEnqueueSignalSemaphoresKHR);
|
|
||||||
GET_EXTENSION_ADDRESS(clEnqueueWaitSemaphoresKHR);
|
|
||||||
GET_EXTENSION_ADDRESS(clReleaseSemaphoreKHR);
|
|
||||||
GET_EXTENSION_ADDRESS(clGetSemaphoreInfoKHR);
|
|
||||||
GET_EXTENSION_ADDRESS(clRetainSemaphoreKHR);
|
|
||||||
GET_EXTENSION_ADDRESS(clGetSemaphoreHandleForTypeKHR);
|
|
||||||
|
|
||||||
#undef GET_EXTENSION_ADDRESS
|
|
||||||
return CL_SUCCESS;
|
return CL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user