Lock d3d sharing before accessing device context
Related-To: NEO-5987 With this change D3D device context will not be accessed from parallel threads. Signed-off-by: Maciej Plewka <maciej.plewka@intel.com>
This commit is contained in:
parent
7aebfc3293
commit
a7de1fb3c2
|
@ -43,6 +43,7 @@ D3DSharing<D3D>::~D3DSharing() {
|
|||
|
||||
template <typename D3D>
|
||||
void D3DSharing<D3D>::synchronizeObject(UpdateData &updateData) {
|
||||
std::unique_lock<std::mutex> lock(this->mtx);
|
||||
sharingFunctions->getDeviceContext(d3dQuery);
|
||||
if (!sharedResource) {
|
||||
sharingFunctions->copySubresourceRegion(resourceStaging, 0, resource, subresource);
|
||||
|
@ -58,6 +59,7 @@ void D3DSharing<D3D>::synchronizeObject(UpdateData &updateData) {
|
|||
template <typename D3D>
|
||||
void D3DSharing<D3D>::releaseResource(MemObj *memObject, uint32_t rootDeviceIndex) {
|
||||
if (!sharedResource) {
|
||||
std::unique_lock<std::mutex> lock(this->mtx);
|
||||
sharingFunctions->getDeviceContext(d3dQuery);
|
||||
sharingFunctions->copySubresourceRegion(resource, subresource, resourceStaging, 0);
|
||||
if (!context->getInteropUserSyncEnabled()) {
|
||||
|
|
|
@ -47,5 +47,6 @@ class D3DSharing : public SharingHandler {
|
|||
D3DQuery *d3dQuery = nullptr;
|
||||
bool sharedResource = false;
|
||||
unsigned int subresource = 0;
|
||||
std::mutex mtx;
|
||||
};
|
||||
} // namespace NEO
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#
|
||||
# Copyright (C) 2021 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
set(IGDRCL_SRCS_mt_tests_sharing
|
||||
# local files
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/d3d_sharing_mt_tests.cpp
|
||||
)
|
||||
if(WIN32)
|
||||
target_sources(igdrcl_mt_tests PRIVATE ${IGDRCL_SRCS_mt_tests_sharing})
|
||||
endif()
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/test/common/test_macros/test.h"
|
||||
|
||||
#include "opencl/source/os_interface/windows/d3d_sharing_functions.h"
|
||||
#include "opencl/source/sharings/d3d/d3d_sharing.h"
|
||||
#include "opencl/test/unit_test/mocks/mock_context.h"
|
||||
|
||||
using namespace NEO;
|
||||
|
||||
template <typename D3D>
|
||||
class MockD3DSharingFunctions : public D3DSharingFunctions<D3D> {
|
||||
public:
|
||||
typedef typename D3D::D3DDevice D3DDevice;
|
||||
typedef typename D3D::D3DQuery D3DQuery;
|
||||
typedef typename D3D::D3DResource D3DResource;
|
||||
MockD3DSharingFunctions() : D3DSharingFunctions<D3D>((D3DDevice *)1) {
|
||||
}
|
||||
void getDeviceContext(D3DQuery *query) override {
|
||||
signalDeviceContextCalled = true;
|
||||
while (!signalLockChecked)
|
||||
;
|
||||
}
|
||||
void copySubresourceRegion(D3DResource *dst, cl_uint dstSubresource,
|
||||
D3DResource *src, cl_uint srcSubresource) override {
|
||||
}
|
||||
void flushAndWait(D3DQuery *query) override {
|
||||
}
|
||||
void releaseDeviceContext(D3DQuery *query) override {
|
||||
}
|
||||
void addRef(D3DResource *resource) override {
|
||||
}
|
||||
void createQuery(D3DQuery **query) override {
|
||||
}
|
||||
void release(IUnknown *resource) override {
|
||||
}
|
||||
|
||||
std::atomic_bool signalDeviceContextCalled = false;
|
||||
std::atomic_bool signalLockChecked = false;
|
||||
};
|
||||
|
||||
template <typename D3D>
|
||||
class MockD3DSharingBase : public D3DSharing<D3D> {
|
||||
public:
|
||||
using D3DSharing<D3D>::sharingFunctions;
|
||||
MockD3DSharingBase(Context *ctx) : D3DSharing<D3D>(ctx, nullptr, nullptr, 0, false) {
|
||||
}
|
||||
void checkIfMutexWasLocked() {
|
||||
isLocked = !this->mtx.try_lock();
|
||||
reinterpret_cast<MockD3DSharingFunctions<D3D> *>(this->sharingFunctions)->signalLockChecked = true;
|
||||
}
|
||||
bool isLocked = false;
|
||||
};
|
||||
|
||||
TEST(SharingD3DMT, givenD3DSharingWhenSynchroniceObjectIsCalledThenMtxIsLockedBeforeAccessingDevice) {
|
||||
auto mockCtx = std::make_unique<MockContext>();
|
||||
mockCtx->sharingFunctions[MockD3DSharingFunctions<D3DTypesHelper::D3D11>::sharingId] = std::make_unique<MockD3DSharingFunctions<D3DTypesHelper::D3D11>>();
|
||||
auto mockD3DSharing = std::make_unique<MockD3DSharingBase<D3DTypesHelper::D3D11>>(mockCtx.get());
|
||||
UpdateData updateData(0);
|
||||
std::thread t1(&MockD3DSharingBase<D3DTypesHelper::D3D11>::synchronizeObject, mockD3DSharing.get(), updateData);
|
||||
while (!reinterpret_cast<MockD3DSharingFunctions<D3DTypesHelper::D3D11> *>(mockD3DSharing->sharingFunctions)->signalDeviceContextCalled)
|
||||
;
|
||||
std::thread t2(&MockD3DSharingBase<D3DTypesHelper::D3D11>::checkIfMutexWasLocked, mockD3DSharing.get());
|
||||
t1.join();
|
||||
t2.join();
|
||||
EXPECT_TRUE(mockD3DSharing->isLocked);
|
||||
}
|
||||
|
||||
TEST(SharingD3DMT, givenD3DSharingWhenReleaseResourceIsCalledThenMtxIsLockedBeforeAccessingDevice) {
|
||||
auto mockCtx = std::make_unique<MockContext>();
|
||||
mockCtx->sharingFunctions[MockD3DSharingFunctions<D3DTypesHelper::D3D11>::sharingId] = std::make_unique<MockD3DSharingFunctions<D3DTypesHelper::D3D11>>();
|
||||
auto mockD3DSharing = std::make_unique<MockD3DSharingBase<D3DTypesHelper::D3D11>>(mockCtx.get());
|
||||
UpdateData updateData(0);
|
||||
std::thread t1(&MockD3DSharingBase<D3DTypesHelper::D3D11>::releaseResource, mockD3DSharing.get(), nullptr, 0);
|
||||
while (!reinterpret_cast<MockD3DSharingFunctions<D3DTypesHelper::D3D11> *>(mockD3DSharing->sharingFunctions)->signalDeviceContextCalled)
|
||||
;
|
||||
std::thread t2(&MockD3DSharingBase<D3DTypesHelper::D3D11>::checkIfMutexWasLocked, mockD3DSharing.get());
|
||||
t1.join();
|
||||
t2.join();
|
||||
EXPECT_TRUE(mockD3DSharing->isLocked);
|
||||
}
|
Loading…
Reference in New Issue