mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-15 13:01:45 +08:00
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:

committed by
Compute-Runtime-Automation

parent
7aebfc3293
commit
a7de1fb3c2
@ -43,6 +43,7 @@ D3DSharing<D3D>::~D3DSharing() {
|
|||||||
|
|
||||||
template <typename D3D>
|
template <typename D3D>
|
||||||
void D3DSharing<D3D>::synchronizeObject(UpdateData &updateData) {
|
void D3DSharing<D3D>::synchronizeObject(UpdateData &updateData) {
|
||||||
|
std::unique_lock<std::mutex> lock(this->mtx);
|
||||||
sharingFunctions->getDeviceContext(d3dQuery);
|
sharingFunctions->getDeviceContext(d3dQuery);
|
||||||
if (!sharedResource) {
|
if (!sharedResource) {
|
||||||
sharingFunctions->copySubresourceRegion(resourceStaging, 0, resource, subresource);
|
sharingFunctions->copySubresourceRegion(resourceStaging, 0, resource, subresource);
|
||||||
@ -58,6 +59,7 @@ void D3DSharing<D3D>::synchronizeObject(UpdateData &updateData) {
|
|||||||
template <typename D3D>
|
template <typename D3D>
|
||||||
void D3DSharing<D3D>::releaseResource(MemObj *memObject, uint32_t rootDeviceIndex) {
|
void D3DSharing<D3D>::releaseResource(MemObj *memObject, uint32_t rootDeviceIndex) {
|
||||||
if (!sharedResource) {
|
if (!sharedResource) {
|
||||||
|
std::unique_lock<std::mutex> lock(this->mtx);
|
||||||
sharingFunctions->getDeviceContext(d3dQuery);
|
sharingFunctions->getDeviceContext(d3dQuery);
|
||||||
sharingFunctions->copySubresourceRegion(resource, subresource, resourceStaging, 0);
|
sharingFunctions->copySubresourceRegion(resource, subresource, resourceStaging, 0);
|
||||||
if (!context->getInteropUserSyncEnabled()) {
|
if (!context->getInteropUserSyncEnabled()) {
|
||||||
|
@ -47,5 +47,6 @@ class D3DSharing : public SharingHandler {
|
|||||||
D3DQuery *d3dQuery = nullptr;
|
D3DQuery *d3dQuery = nullptr;
|
||||||
bool sharedResource = false;
|
bool sharedResource = false;
|
||||||
unsigned int subresource = 0;
|
unsigned int subresource = 0;
|
||||||
|
std::mutex mtx;
|
||||||
};
|
};
|
||||||
} // namespace NEO
|
} // namespace NEO
|
||||||
|
15
opencl/test/unit_test/mt_tests/sharing/CMakeLists.txt
Normal file
15
opencl/test/unit_test/mt_tests/sharing/CMakeLists.txt
Normal file
@ -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);
|
||||||
|
}
|
Reference in New Issue
Block a user