Verify HDC handle when returning devices for GL sharing

Resolves: NEO-4952
Change-Id: I298bb26aacd2cc5ad7206f7fff2b2235098fb8bf
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski
2020-08-07 08:03:07 +02:00
committed by sys_ocldev
parent c2a4835943
commit 418db08517
11 changed files with 194 additions and 13 deletions

View File

@ -6,6 +6,7 @@
*/
#include "shared/source/helpers/get_info.h"
#include "shared/source/os_interface/windows/os_interface.h"
#include "shared/source/utilities/api_intercept.h"
#include "opencl/source/api/api.h"
@ -350,11 +351,23 @@ cl_int CL_API_CALL clGetGLContextInfoKHR(const cl_context_properties *properties
}
if (paramName == CL_DEVICES_FOR_GL_CONTEXT_KHR || paramName == CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR) {
if (platform) {
info.set<cl_device_id>(platform->getClDevice(0));
} else {
info.set<cl_device_id>(platformsImpl[0]->getClDevice(0));
if (!platform) {
platform = platformsImpl[0].get();
}
ClDevice *deviceToReturn = nullptr;
for (auto i = 0u; i < platform->getNumDevices(); i++) {
auto device = platform->getClDevice(i);
if (device->getRootDeviceEnvironment().osInterface->get()->getWddm()->verifyHdcHandle(GLHDCHandle)) {
deviceToReturn = device;
break;
}
}
if (!deviceToReturn) {
retVal = CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR;
return retVal;
}
info.set<cl_device_id>(deviceToReturn);
return retVal;
}

View File

@ -15,7 +15,6 @@ if(WIN32)
${CMAKE_CURRENT_SOURCE_DIR}/cl_enqueue_acquire_gl_objects_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_enqueue_release_gl_objects_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_get_gl_device_info_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_get_gl_context_info_khr_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_get_gl_object_info_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_get_gl_texture_info_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_gl_intel_tracing_tests.cpp

View File

@ -46,6 +46,7 @@ class WddmMock : public Wddm {
using Wddm::temporaryResources;
using Wddm::wddmInterface;
WddmMock(std::unique_ptr<HwDeviceId> hwDeviceId, RootDeviceEnvironment &rootDeviceEnvironment) : Wddm(std::move(hwDeviceId), rootDeviceEnvironment) {}
WddmMock(RootDeviceEnvironment &rootDeviceEnvironment);
~WddmMock();
@ -108,6 +109,9 @@ class WddmMock : public Wddm {
++counterVerifySharedHandle;
return Wddm::verifySharedHandle(osHandle);
}
bool verifyHdcHandle(size_t hdcHandle) const override {
return verifyHdcReturnValue;
}
void resetGdi(Gdi *gdi);
@ -147,6 +151,7 @@ class WddmMock : public Wddm {
bool makeResidentStatus = true;
bool callBaseMakeResident = true;
bool callBaseCreatePagingLogger = true;
bool verifyHdcReturnValue = true;
};
struct GmockWddm : WddmMock {

View File

@ -0,0 +1,13 @@
#
# Copyright (C) 2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(IGDRCL_SRCS_tests_os_interface_windows_gl
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/cl_get_gl_context_info_khr_tests.cpp
)
if(WIN32)
target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_os_interface_windows_gl})
endif()

View File

@ -7,20 +7,28 @@
#include "shared/source/helpers/hw_info.h"
#include "shared/source/os_interface/device_factory.h"
#include "shared/source/os_interface/windows/os_interface.h"
#include "shared/test/unit_test/mocks/mock_device.h"
#include "opencl/source/cl_device/cl_device.h"
#include "opencl/test/unit_test/api/cl_api_tests.h"
#include "opencl/test/unit_test/mocks/mock_platform.h"
#include "opencl/test/unit_test/mocks/mock_wddm.h"
#include "opencl/test/unit_test/sharings/gl/gl_dll_helper.h"
using namespace NEO;
typedef api_tests clGetGLContextInfoKHR_;
using clGetGLContextInfoKhrTest = api_tests;
namespace ULT {
TEST_F(clGetGLContextInfoKHR_, successWithDefaultPlatform) {
TEST_F(clGetGLContextInfoKhrTest, successWithDefaultPlatform) {
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
auto defaultPlatform = std::make_unique<MockPlatform>();
defaultPlatform->initializeWithNewDevices();
platformsImpl[0] = std::move(defaultPlatform);
auto expectedDevice = ::platform()->getClDevice(0);
cl_device_id retDevice = 0;
size_t retSize = 0;
@ -44,6 +52,9 @@ using clGetGLContextInfoKHRNonDefaultPlatform = ::testing::Test;
TEST_F(clGetGLContextInfoKHRNonDefaultPlatform, successWithNonDefaultPlatform) {
platformsImpl.clear();
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
cl_int retVal = CL_SUCCESS;
auto nonDefaultPlatform = std::make_unique<MockPlatform>();
@ -68,7 +79,7 @@ TEST_F(clGetGLContextInfoKHRNonDefaultPlatform, successWithNonDefaultPlatform) {
EXPECT_EQ(sizeof(cl_device_id), retSize);
}
TEST_F(clGetGLContextInfoKHR_, invalidParam) {
TEST_F(clGetGLContextInfoKhrTest, invalidParam) {
cl_device_id retDevice = 0;
size_t retSize = 0;
const cl_context_properties properties[] = {CL_GL_CONTEXT_KHR, 1, CL_WGL_HDC_KHR, 2, 0};
@ -79,7 +90,7 @@ TEST_F(clGetGLContextInfoKHR_, invalidParam) {
EXPECT_EQ(0u, retSize);
}
TEST_F(clGetGLContextInfoKHR_, givenContextFromNoIntelOpenGlDriverWhenCallClGetGLContextInfoKHRThenReturnClInvalidContext) {
TEST_F(clGetGLContextInfoKhrTest, givenContextFromNoIntelOpenGlDriverWhenCallClGetGLContextInfoKHRThenReturnClInvalidContext) {
cl_device_id retDevice = 0;
size_t retSize = 0;
const cl_context_properties properties[] = {CL_GL_CONTEXT_KHR, 1, CL_WGL_HDC_KHR, 2, 0};
@ -92,7 +103,7 @@ TEST_F(clGetGLContextInfoKHR_, givenContextFromNoIntelOpenGlDriverWhenCallClGetG
EXPECT_EQ(0u, retSize);
}
TEST_F(clGetGLContextInfoKHR_, givenNullVersionFromIntelOpenGlDriverWhenCallClGetGLContextInfoKHRThenReturnClInvalidContext) {
TEST_F(clGetGLContextInfoKhrTest, givenNullVersionFromIntelOpenGlDriverWhenCallClGetGLContextInfoKHRThenReturnClInvalidContext) {
cl_device_id retDevice = 0;
size_t retSize = 0;
const cl_context_properties properties[] = {CL_GL_CONTEXT_KHR, 1, CL_WGL_HDC_KHR, 2, 0};
@ -105,7 +116,7 @@ TEST_F(clGetGLContextInfoKHR_, givenNullVersionFromIntelOpenGlDriverWhenCallClGe
EXPECT_EQ(0u, retSize);
}
TEST_F(clGetGLContextInfoKHR_, GivenIncorrectPropertiesWhenCallclGetGLContextInfoKHRThenReturnClInvalidGlShareGroupRererencKhr) {
TEST_F(clGetGLContextInfoKhrTest, GivenIncorrectPropertiesWhenCallclGetGLContextInfoKHRThenReturnClInvalidGlShareGroupRererencKhr) {
cl_device_id retDevice = 0;
size_t retSize = 0;
retVal = clGetGLContextInfoKHR(nullptr, 0, sizeof(cl_device_id), &retDevice, &retSize);
@ -120,4 +131,58 @@ TEST_F(clGetGLContextInfoKHR_, GivenIncorrectPropertiesWhenCallclGetGLContextInf
EXPECT_EQ(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR, retVal);
}
TEST_F(clGetGLContextInfoKHRNonDefaultPlatform, whenVerificationOfHdcHandleFailsThenInvalidGlReferenceErrorIsReturned) {
platformsImpl.clear();
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
cl_int retVal = CL_SUCCESS;
auto nonDefaultPlatform = std::make_unique<MockPlatform>();
nonDefaultPlatform->initializeWithNewDevices();
cl_platform_id nonDefaultPlatformCl = nonDefaultPlatform.get();
auto device = nonDefaultPlatform->getClDevice(0);
static_cast<WddmMock *>(device->getRootDeviceEnvironment().osInterface->get()->getWddm())->verifyHdcReturnValue = false;
size_t retSize = 0;
cl_device_id retDevice = 0;
const cl_context_properties properties[] = {CL_GL_CONTEXT_KHR, 1, CL_WGL_HDC_KHR, 2, CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(nonDefaultPlatformCl), 0};
retVal = clGetGLContextInfoKHR(properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_device_id), &retDevice, &retSize);
EXPECT_EQ(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR, retVal);
}
TEST_F(clGetGLContextInfoKHRNonDefaultPlatform, whenVerificationOfHdcHandleFailsForFirstDeviceButSucceedsForSecondOneThenReturnTheSecondDevice) {
platformsImpl.clear();
DebugManagerStateRestore restorer;
DebugManager.flags.CreateMultipleRootDevices.set(2);
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
cl_int retVal = CL_SUCCESS;
auto nonDefaultPlatform = std::make_unique<MockPlatform>();
nonDefaultPlatform->initializeWithNewDevices();
cl_platform_id nonDefaultPlatformCl = nonDefaultPlatform.get();
auto device0 = nonDefaultPlatform->getClDevice(0);
auto device1 = nonDefaultPlatform->getClDevice(0);
cl_device_id expectedDevice = device1;
static_cast<WddmMock *>(device0->getRootDeviceEnvironment().osInterface->get()->getWddm())->verifyHdcReturnValue = false;
static_cast<WddmMock *>(device1->getRootDeviceEnvironment().osInterface->get()->getWddm())->verifyHdcReturnValue = true;
size_t retSize = 0;
cl_device_id retDevice = 0;
const cl_context_properties properties[] = {CL_GL_CONTEXT_KHR, 1, CL_WGL_HDC_KHR, 2, CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(nonDefaultPlatformCl), 0};
retVal = clGetGLContextInfoKHR(properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_device_id), &retDevice, &retSize);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(expectedDevice, retDevice);
EXPECT_EQ(sizeof(cl_device_id), retSize);
}
} // namespace ULT

View File

@ -1449,3 +1449,63 @@ TEST(DiscoverDevices, whenDriverInfoHasIncompatibleDriverStoreThenHwDeviceIdIsNo
auto hwDeviceIds = OSInterface::discoverDevices(executionEnvironment);
EXPECT_TRUE(hwDeviceIds.empty());
}
TEST(VerifyHdcTest, givenHdcHandleFromCorrectAdapterLuidWhenVerifyHdcHandleIsCalledThenSuccessIsReturned) {
auto gdi = std::make_unique<MockGdi>();
auto osEnv = std::make_unique<OsEnvironmentWin>();
osEnv->gdi = std::move(gdi);
LUID adapterLuid = {0x1234, 0x5678};
VariableBackup<LUID> luidBackup(&MockGdi::adapterLuidToReturn, adapterLuid);
auto hwDeviceId = std::make_unique<HwDeviceId>(ADAPTER_HANDLE, adapterLuid, osEnv.get());
MockExecutionEnvironment executionEnvironment;
executionEnvironment.osEnvironment = std::move(osEnv);
RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment);
WddmMock wddm(std::move(hwDeviceId), rootDeviceEnvironment);
size_t hdcHandle = 0x1;
auto status = wddm.Wddm::verifyHdcHandle(hdcHandle);
EXPECT_TRUE(status);
status = wddm.Wddm::verifyHdcHandle(0u);
EXPECT_FALSE(status);
}
TEST(VerifyHdcTest, givenHdcHandleFromInvalidAdapterLuidWhenVerifyHdcHandleIsCalledThenFailureIsReturned) {
auto gdi = std::make_unique<MockGdi>();
auto osEnv = std::make_unique<OsEnvironmentWin>();
osEnv->gdi = std::move(gdi);
LUID adapterLuid = {0x1234, 0x5678};
VariableBackup<LUID> luidBackup(&MockGdi::adapterLuidToReturn);
auto hwDeviceId = std::make_unique<HwDeviceId>(ADAPTER_HANDLE, adapterLuid, osEnv.get());
MockExecutionEnvironment executionEnvironment;
executionEnvironment.osEnvironment = std::move(osEnv);
RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment);
WddmMock wddm(std::move(hwDeviceId), rootDeviceEnvironment);
size_t hdcHandle = 0x1;
MockGdi::adapterLuidToReturn = {0x1233, 0x5678};
auto status = wddm.Wddm::verifyHdcHandle(hdcHandle);
EXPECT_FALSE(status);
MockGdi::adapterLuidToReturn = {0x1234, 0x5679};
status = wddm.Wddm::verifyHdcHandle(hdcHandle);
EXPECT_FALSE(status);
}

View File

@ -22,7 +22,7 @@ inline const std::string getGdiName() {
Gdi::Gdi() : gdiDll(getGdiName()),
initialized(false) {
if (gdiDll.isLoaded()) {
initialized = getAllProcAddresses();
initialized = Gdi::getAllProcAddresses();
}
}

View File

@ -1059,4 +1059,15 @@ void Wddm::createPagingFenceLogger() {
}
}
bool Wddm::verifyHdcHandle(size_t hdcHandle) const {
D3DKMT_OPENADAPTERFROMHDC openAdapterFromHdcStruct{};
openAdapterFromHdcStruct.hDc = reinterpret_cast<HDC>(hdcHandle);
auto status = getGdi()->openAdapterFromHdc(&openAdapterFromHdcStruct);
if (STATUS_SUCCESS != status) {
DEBUG_BREAK_IF(true);
return false;
}
return openAdapterFromHdcStruct.AdapterLuid.HighPart == hwDeviceId->getAdapterLuid().HighPart && openAdapterFromHdcStruct.AdapterLuid.LowPart == hwDeviceId->getAdapterLuid().LowPart;
}
} // namespace NEO

View File

@ -92,6 +92,8 @@ class Wddm {
bool configureDeviceAddressSpace();
MOCKABLE_VIRTUAL bool verifyHdcHandle(size_t hdcHandle) const;
GT_SYSTEM_INFO *getGtSysInfo() const {
DEBUG_BREAK_IF(!gtSystemInfo);
return gtSystemInfo.get();

View File

@ -9,4 +9,5 @@
namespace NEO {
UINT64 MockGdi::pagingFenceReturnValue = 0x3ull;
LUID MockGdi::adapterLuidToReturn{};
} // namespace NEO

View File

@ -15,12 +15,13 @@ namespace NEO {
class MockGdi : public Gdi {
public:
MockGdi() {
initialized = getAllProcAddresses();
initialized = MockGdi::getAllProcAddresses();
}
~MockGdi(){};
static UINT64 pagingFenceReturnValue;
bool nonZeroNumBytesToTrim = false;
static LUID adapterLuidToReturn;
void setNonZeroNumBytesToTrimInEvict() {
nonZeroNumBytesToTrim = true;
@ -106,6 +107,7 @@ class MockGdi : public Gdi {
waitForSynchronizationObjectFromCpu = reinterpret_cast<PFND3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMCPU>(waitFromCpuMock);
queryResourceInfo = reinterpret_cast<PFND3DKMT_QUERYRESOURCEINFO>(queryResourceInfoMock);
openResource = reinterpret_cast<PFND3DKMT_OPENRESOURCE>(openResourceMock);
openAdapterFromHdc = reinterpret_cast<PFND3DKMT_OPENADAPTERFROMHDC>(MockGdi::openAdapterFromHdcMock);
return true;
}
@ -163,6 +165,16 @@ class MockGdi : public Gdi {
static D3DKMT_OPENRESOURCE openResource;
return openResource;
}
static NTSTATUS __stdcall openAdapterFromHdcMock(D3DKMT_OPENADAPTERFROMHDC *openAdapterFromHdcStruct) {
if (!openAdapterFromHdcStruct) {
return STATUS_INVALID_PARAMETER;
}
if (openAdapterFromHdcStruct->hDc == 0) {
return STATUS_INVALID_PARAMETER;
}
openAdapterFromHdcStruct->AdapterLuid = MockGdi::adapterLuidToReturn;
return STATUS_SUCCESS;
}
};
} // namespace NEO