feature: Native GPU fence synchronization object implementation
Related-To: NEO-10811 Signed-off-by: Krzysztof Sprzaczkowski <krzysztof.sprzaczkowski@intel.com>
This commit is contained in:
parent
fdb84aaa3d
commit
de72e91269
|
@ -927,6 +927,7 @@ include_directories(${NEO_SHARED_DIRECTORY}/kernel/definitions${BRANCH_DIR_SUFFI
|
||||||
include_directories(${NEO_SHARED_DIRECTORY}/gen_common${BRANCH_DIR_SUFFIX})
|
include_directories(${NEO_SHARED_DIRECTORY}/gen_common${BRANCH_DIR_SUFFIX})
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
include_directories(${NEO_SHARED_DIRECTORY}/gmm_helper/windows/gmm_memory${BRANCH_DIR_SUFFIX})
|
include_directories(${NEO_SHARED_DIRECTORY}/gmm_helper/windows/gmm_memory${BRANCH_DIR_SUFFIX})
|
||||||
|
include_directories(${NEO_SHARED_DIRECTORY}/os_interface/windows/wddm/definitions)
|
||||||
else()
|
else()
|
||||||
include_directories(${NEO_LINUX_KMD_HEADERS_DIR}
|
include_directories(${NEO_LINUX_KMD_HEADERS_DIR}
|
||||||
${NEO_SHARED_DIRECTORY}/gmm_helper/windows/gmm_memory
|
${NEO_SHARED_DIRECTORY}/gmm_helper/windows/gmm_memory
|
||||||
|
@ -934,6 +935,9 @@ else()
|
||||||
if("${BRANCH_TYPE}" STREQUAL "")
|
if("${BRANCH_TYPE}" STREQUAL "")
|
||||||
include_directories(${NEO_SOURCE_DIR}/third_party/uapi/prelim)
|
include_directories(${NEO_SOURCE_DIR}/third_party/uapi/prelim)
|
||||||
endif()
|
endif()
|
||||||
|
if(NOT DISABLE_WDDM_LINUX)
|
||||||
|
include_directories(${NEO_SHARED_DIRECTORY}/os_interface/linux/wddm_linux/definitions)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
include_directories(${NEO_SHARED_DIRECTORY}/helpers/definitions${BRANCH_DIR_SUFFIX})
|
include_directories(${NEO_SHARED_DIRECTORY}/helpers/definitions${BRANCH_DIR_SUFFIX})
|
||||||
include_directories(${NEO_SHARED_DIRECTORY}/memory_properties${BRANCH_DIR_SUFFIX})
|
include_directories(${NEO_SHARED_DIRECTORY}/memory_properties${BRANCH_DIR_SUFFIX})
|
||||||
|
|
|
@ -86,7 +86,7 @@ void WddmDirectSubmission<GfxFamily, Dispatcher>::ensureRingCompletion() {
|
||||||
|
|
||||||
template <typename GfxFamily, typename Dispatcher>
|
template <typename GfxFamily, typename Dispatcher>
|
||||||
bool WddmDirectSubmission<GfxFamily, Dispatcher>::allocateOsResources() {
|
bool WddmDirectSubmission<GfxFamily, Dispatcher>::allocateOsResources() {
|
||||||
bool ret = wddm->getWddmInterface()->createMonitoredFenceForDirectSubmission(ringFence, *this->osContextWin);
|
bool ret = wddm->getWddmInterface()->createFenceForDirectSubmission(ringFence, *this->osContextWin);
|
||||||
perfLogResidencyVariadicLog(wddm->getResidencyLogger(), "ULLS resource allocation finished with: %d\n", ret);
|
perfLogResidencyVariadicLog(wddm->getResidencyLogger(), "ULLS resource allocation finished with: %d\n", ret);
|
||||||
|
|
||||||
this->ringBufferEndCompletionTagData.tagAddress = this->semaphoreGpuVa + offsetof(RingSemaphoreData, tagAllocation);
|
this->ringBufferEndCompletionTagData.tagAddress = this->semaphoreGpuVa + offsetof(RingSemaphoreData, tagAllocation);
|
||||||
|
|
|
@ -116,8 +116,10 @@ if(DISABLE_WDDM_LINUX)
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
list(APPEND NEO_CORE_OS_INTERFACE_LINUX
|
list(APPEND NEO_CORE_OS_INTERFACE_LINUX
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_linux/sys_calls_win.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_linux/compatible_driver_store.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm_linux/compatible_driver_store.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm_linux/definitions/gdi_interface_logging.inl
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm_linux/sys_calls_win.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm_linux/wddm_interface_extra.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shared/source/os_interface/windows/wddm/wddm.h"
|
||||||
|
#include "shared/source/os_interface/windows/wddm/wddm_interface.h"
|
||||||
|
|
||||||
|
using namespace NEO;
|
||||||
|
|
||||||
|
bool WddmInterface32::createSyncObject(MonitoredFence &monitorFence) {
|
||||||
|
UNRECOVERABLE_IF(true);
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -45,7 +45,9 @@ set(NEO_CORE_OS_INTERFACE_WINDOWS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_create_with_fallback.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_create_with_fallback.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_dxgi.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_dxgi.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_dxgi.h
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm/adapter_factory_dxgi.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm/definitions/gdi_interface_logging.inl
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/read_preemption_regkey.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm/read_preemption_regkey.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm/wddm_interface_extra.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/windows_inc.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/windows_inc.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm/${BRANCH_DIR_SUFFIX}/perf_wddm.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm/${BRANCH_DIR_SUFFIX}/perf_wddm.cpp
|
||||||
)
|
)
|
||||||
|
@ -127,6 +129,7 @@ set(NEO_CORE_OS_INTERFACE_WDDM
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/sys_calls_wrapper.h
|
${CMAKE_CURRENT_SOURCE_DIR}/sys_calls_wrapper.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm${BRANCH_DIR_SUFFIX}/init_context_private_data.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm${BRANCH_DIR_SUFFIX}/init_context_private_data.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm${BRANCH_DIR_SUFFIX}/wddm_debug_interface.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm${BRANCH_DIR_SUFFIX}/wddm_debug_interface.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm${BRANCH_DIR_SUFFIX}/wddm_features_extra.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT WIN32 AND NOT DISABLE_WDDM_LINUX)
|
if(NOT WIN32 AND NOT DISABLE_WDDM_LINUX)
|
||||||
|
|
|
@ -59,6 +59,7 @@ bool Gdi::getAllProcAddresses() {
|
||||||
createSynchronizationObject = gdiDll->getProcAddress("D3DKMTCreateSynchronizationObject");
|
createSynchronizationObject = gdiDll->getProcAddress("D3DKMTCreateSynchronizationObject");
|
||||||
createSynchronizationObject2 = gdiDll->getProcAddress("D3DKMTCreateSynchronizationObject2");
|
createSynchronizationObject2 = gdiDll->getProcAddress("D3DKMTCreateSynchronizationObject2");
|
||||||
destroySynchronizationObject = gdiDll->getProcAddress("D3DKMTDestroySynchronizationObject");
|
destroySynchronizationObject = gdiDll->getProcAddress("D3DKMTDestroySynchronizationObject");
|
||||||
|
createNativeFence = gdiDll->getProcAddress("D3DKMTCreateNativeFence");
|
||||||
signalSynchronizationObject = gdiDll->getProcAddress("D3DKMTSignalSynchronizationObject");
|
signalSynchronizationObject = gdiDll->getProcAddress("D3DKMTSignalSynchronizationObject");
|
||||||
waitForSynchronizationObject = gdiDll->getProcAddress("D3DKMTWaitForSynchronizationObject");
|
waitForSynchronizationObject = gdiDll->getProcAddress("D3DKMTWaitForSynchronizationObject");
|
||||||
waitForSynchronizationObjectFromCpu = gdiDll->getProcAddress("D3DKMTWaitForSynchronizationObjectFromCpu");
|
waitForSynchronizationObjectFromCpu = gdiDll->getProcAddress("D3DKMTWaitForSynchronizationObjectFromCpu");
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
typedef struct _D3DKMT_CREATENATIVEFENCE D3DKMT_CREATENATIVEFENCE;
|
||||||
|
|
||||||
namespace NEO {
|
namespace NEO {
|
||||||
|
|
||||||
#define DEFINE_THK_WRAPPER(TYPE, VAR) ThkWrapper<TYPE> VAR = ThkWrapper<TYPE>(this->profiler, #TYPE, this->gdiId++);
|
#define DEFINE_THK_WRAPPER(TYPE, VAR) ThkWrapper<TYPE> VAR = ThkWrapper<TYPE>(this->profiler, #TYPE, this->gdiId++);
|
||||||
|
@ -46,6 +48,7 @@ class Gdi {
|
||||||
DEFINE_THK_WRAPPER(IN OUT D3DKMT_CREATESYNCHRONIZATIONOBJECT *, createSynchronizationObject);
|
DEFINE_THK_WRAPPER(IN OUT D3DKMT_CREATESYNCHRONIZATIONOBJECT *, createSynchronizationObject);
|
||||||
DEFINE_THK_WRAPPER(IN OUT D3DKMT_CREATESYNCHRONIZATIONOBJECT2 *, createSynchronizationObject2);
|
DEFINE_THK_WRAPPER(IN OUT D3DKMT_CREATESYNCHRONIZATIONOBJECT2 *, createSynchronizationObject2);
|
||||||
DEFINE_THK_WRAPPER(IN CONST D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *, destroySynchronizationObject);
|
DEFINE_THK_WRAPPER(IN CONST D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *, destroySynchronizationObject);
|
||||||
|
DEFINE_THK_WRAPPER(IN OUT D3DKMT_CREATENATIVEFENCE *, createNativeFence);
|
||||||
DEFINE_THK_WRAPPER(IN CONST D3DKMT_SIGNALSYNCHRONIZATIONOBJECT *, signalSynchronizationObject);
|
DEFINE_THK_WRAPPER(IN CONST D3DKMT_SIGNALSYNCHRONIZATIONOBJECT *, signalSynchronizationObject);
|
||||||
DEFINE_THK_WRAPPER(IN CONST_FROM_WDK_10_0_18328_0 D3DKMT_WAITFORSYNCHRONIZATIONOBJECT *, waitForSynchronizationObject);
|
DEFINE_THK_WRAPPER(IN CONST_FROM_WDK_10_0_18328_0 D3DKMT_WAITFORSYNCHRONIZATIONOBJECT *, waitForSynchronizationObject);
|
||||||
DEFINE_THK_WRAPPER(IN CONST D3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMCPU *, waitForSynchronizationObjectFromCpu);
|
DEFINE_THK_WRAPPER(IN CONST D3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMCPU *, waitForSynchronizationObjectFromCpu);
|
||||||
|
|
|
@ -466,6 +466,8 @@ template void logExit<CONST D3DKMT_SETALLOCATIONPRIORITY *>(NTSTATUS status, CON
|
||||||
template void logEnter<CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *>(CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *param);
|
template void logEnter<CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *>(CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *param);
|
||||||
template void logExit<CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *>(NTSTATUS status, CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *param);
|
template void logExit<CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *>(NTSTATUS status, CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *param);
|
||||||
|
|
||||||
|
#include "gdi_interface_logging.inl"
|
||||||
|
|
||||||
} // namespace GdiLogging
|
} // namespace GdiLogging
|
||||||
|
|
||||||
} // namespace NEO
|
} // namespace NEO
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void getEnterString<D3DKMT_CREATENATIVEFENCE *>(D3DKMT_CREATENATIVEFENCE *param, char *input, size_t size) {
|
||||||
|
snprintf_s(input, size, size, "D3DKMT_CREATENATIVEFENCE Info Type %u Info Flags 0x%x", param->Info.Type, param->Info.Flags.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template void logEnter<D3DKMT_CREATENATIVEFENCE *>(D3DKMT_CREATENATIVEFENCE *param);
|
||||||
|
template void logExit<D3DKMT_CREATENATIVEFENCE *>(NTSTATUS status, D3DKMT_CREATENATIVEFENCE *param);
|
|
@ -138,7 +138,10 @@ bool Wddm::init() {
|
||||||
rootDeviceEnvironment.initGmm();
|
rootDeviceEnvironment.initGmm();
|
||||||
this->rootDeviceEnvironment.getGmmClientContext()->setHandleAllocator(this->hwDeviceId->getUmKmDataTranslator()->createGmmHandleAllocator());
|
this->rootDeviceEnvironment.getGmmClientContext()->setHandleAllocator(this->hwDeviceId->getUmKmDataTranslator()->createGmmHandleAllocator());
|
||||||
|
|
||||||
if (WddmVersion::wddm23 == getWddmVersion()) {
|
auto wddmVersion = getWddmVersion();
|
||||||
|
if (WddmVersion::wddm32 == wddmVersion) {
|
||||||
|
wddmInterface = std::make_unique<WddmInterface32>(*this);
|
||||||
|
} else if (WddmVersion::wddm23 == wddmVersion) {
|
||||||
wddmInterface = std::make_unique<WddmInterface23>(*this);
|
wddmInterface = std::make_unique<WddmInterface23>(*this);
|
||||||
} else {
|
} else {
|
||||||
wddmInterface = std::make_unique<WddmInterface20>(*this);
|
wddmInterface = std::make_unique<WddmInterface20>(*this);
|
||||||
|
@ -1392,6 +1395,9 @@ void Wddm::updatePagingFenceValue(uint64_t newPagingFenceValue) {
|
||||||
|
|
||||||
WddmVersion Wddm::getWddmVersion() {
|
WddmVersion Wddm::getWddmVersion() {
|
||||||
if (featureTable->flags.ftrWddmHwQueues) {
|
if (featureTable->flags.ftrWddmHwQueues) {
|
||||||
|
if (isNativeFenceAvailable()) {
|
||||||
|
return WddmVersion::wddm32;
|
||||||
|
}
|
||||||
return WddmVersion::wddm23;
|
return WddmVersion::wddm23;
|
||||||
} else {
|
} else {
|
||||||
return WddmVersion::wddm20;
|
return WddmVersion::wddm20;
|
||||||
|
|
|
@ -106,6 +106,7 @@ class Wddm : public DriverModel {
|
||||||
|
|
||||||
MOCKABLE_VIRTUAL bool isShutdownInProgress();
|
MOCKABLE_VIRTUAL bool isShutdownInProgress();
|
||||||
MOCKABLE_VIRTUAL bool isDebugAttachAvailable();
|
MOCKABLE_VIRTUAL bool isDebugAttachAvailable();
|
||||||
|
MOCKABLE_VIRTUAL bool isNativeFenceAvailable();
|
||||||
|
|
||||||
bool isGpuHangDetected(OsContext &osContext) override;
|
bool isGpuHangDetected(OsContext &osContext) override;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2023 Intel Corporation
|
* Copyright (C) 2020-2025 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
@ -20,6 +20,7 @@ struct WddmSubmitArguments {
|
||||||
|
|
||||||
enum class WddmVersion : uint32_t {
|
enum class WddmVersion : uint32_t {
|
||||||
wddm20 = 0,
|
wddm20 = 0,
|
||||||
wddm23
|
wddm23,
|
||||||
|
wddm32
|
||||||
};
|
};
|
||||||
} // namespace NEO
|
} // namespace NEO
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shared/source/os_interface/os_interface.h"
|
||||||
|
#include "shared/source/os_interface/windows/wddm/wddm.h"
|
||||||
|
|
||||||
|
namespace NEO {
|
||||||
|
|
||||||
|
bool Wddm::isNativeFenceAvailable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace NEO
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018-2024 Intel Corporation
|
* Copyright (C) 2018-2025 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
@ -97,7 +97,7 @@ bool WddmInterface20::submit(uint64_t commandBuffer, size_t size, void *commandH
|
||||||
return STATUS_SUCCESS == status;
|
return STATUS_SUCCESS == status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NEO::WddmInterface20::createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) {
|
bool NEO::WddmInterface20::createFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) {
|
||||||
auto ret = WddmInterface::createMonitoredFence(monitorFence);
|
auto ret = WddmInterface::createMonitoredFence(monitorFence);
|
||||||
monitorFence.currentFenceValue = 1;
|
monitorFence.currentFenceValue = 1;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -177,9 +177,9 @@ bool WddmInterface23::submit(uint64_t commandBuffer, size_t size, void *commandH
|
||||||
return status == STATUS_SUCCESS;
|
return status == STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NEO::WddmInterface23::createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) {
|
bool NEO::WddmInterface23::createFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) {
|
||||||
MonitoredFence monitorFenceForResidency{};
|
MonitoredFence monitorFenceForResidency{};
|
||||||
auto ret = WddmInterface::createMonitoredFence(monitorFenceForResidency);
|
auto ret = createSyncObject(monitorFenceForResidency);
|
||||||
auto &residencyController = osContext.getResidencyController();
|
auto &residencyController = osContext.getResidencyController();
|
||||||
auto lastSubmittedFence = residencyController.getMonitoredFence().lastSubmittedFence;
|
auto lastSubmittedFence = residencyController.getMonitoredFence().lastSubmittedFence;
|
||||||
auto currentFenceValue = residencyController.getMonitoredFence().currentFenceValue;
|
auto currentFenceValue = residencyController.getMonitoredFence().currentFenceValue;
|
||||||
|
@ -198,3 +198,8 @@ bool NEO::WddmInterface23::createMonitoredFenceForDirectSubmission(MonitoredFenc
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WddmInterface23::createSyncObject(MonitoredFence &monitorFence) {
|
||||||
|
auto ret = WddmInterface::createMonitoredFence(monitorFence);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018-2024 Intel Corporation
|
* Copyright (C) 2018-2025 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
@ -31,7 +31,7 @@ class WddmInterface {
|
||||||
virtual void destroyMonitorFence(MonitoredFence &monitorFence) = 0;
|
virtual void destroyMonitorFence(MonitoredFence &monitorFence) = 0;
|
||||||
virtual bool hwQueuesSupported() = 0;
|
virtual bool hwQueuesSupported() = 0;
|
||||||
virtual bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) = 0;
|
virtual bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) = 0;
|
||||||
virtual bool createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) = 0;
|
virtual bool createFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) = 0;
|
||||||
Wddm &wddm;
|
Wddm &wddm;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ class WddmInterface20 : public WddmInterface {
|
||||||
void destroyMonitorFence(MonitoredFence &monitorFence) override;
|
void destroyMonitorFence(MonitoredFence &monitorFence) override;
|
||||||
bool hwQueuesSupported() override;
|
bool hwQueuesSupported() override;
|
||||||
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) override;
|
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) override;
|
||||||
bool createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) override;
|
bool createFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WddmInterface23 : public WddmInterface {
|
class WddmInterface23 : public WddmInterface {
|
||||||
|
@ -56,6 +56,13 @@ class WddmInterface23 : public WddmInterface {
|
||||||
void destroyMonitorFence(MonitoredFence &monitorFence) override;
|
void destroyMonitorFence(MonitoredFence &monitorFence) override;
|
||||||
bool hwQueuesSupported() override;
|
bool hwQueuesSupported() override;
|
||||||
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) override;
|
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) override;
|
||||||
bool createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) override;
|
bool createFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) override;
|
||||||
|
virtual bool createSyncObject(MonitoredFence &monitorFence);
|
||||||
|
};
|
||||||
|
|
||||||
|
class WddmInterface32 : public WddmInterface23 {
|
||||||
|
public:
|
||||||
|
using WddmInterface23::WddmInterface23;
|
||||||
|
bool createSyncObject(MonitoredFence &monitorFence) override;
|
||||||
};
|
};
|
||||||
} // namespace NEO
|
} // namespace NEO
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shared/source/os_interface/windows/gdi_interface.h"
|
||||||
|
#include "shared/source/os_interface/windows/wddm/wddm.h"
|
||||||
|
#include "shared/source/os_interface/windows/wddm/wddm_interface.h"
|
||||||
|
|
||||||
|
using namespace NEO;
|
||||||
|
|
||||||
|
bool WddmInterface32::createSyncObject(MonitoredFence &monitorFence) {
|
||||||
|
UNRECOVERABLE_IF(wddm.getGdi()->createNativeFence == nullptr);
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
D3DKMT_CREATENATIVEFENCE createNativeFenceObject = {0};
|
||||||
|
createNativeFenceObject.hDevice = wddm.getDeviceHandle();
|
||||||
|
createNativeFenceObject.Info.Type = D3DDDI_NATIVEFENCE_TYPE_DEFAULT;
|
||||||
|
createNativeFenceObject.Info.InitialFenceValue = 0;
|
||||||
|
|
||||||
|
status = wddm.getGdi()->createNativeFence(&createNativeFenceObject);
|
||||||
|
DEBUG_BREAK_IF(STATUS_SUCCESS != status);
|
||||||
|
|
||||||
|
monitorFence.fenceHandle = createNativeFenceObject.hSyncObject;
|
||||||
|
monitorFence.cpuAddress = reinterpret_cast<uint64_t *>(createNativeFenceObject.Info.NativeFenceMapping.CurrentValueCpuVa);
|
||||||
|
monitorFence.gpuAddress = createNativeFenceObject.Info.NativeFenceMapping.CurrentValueGpuVa;
|
||||||
|
|
||||||
|
return status == STATUS_SUCCESS;
|
||||||
|
}
|
|
@ -560,6 +560,10 @@ NTSTATUS __stdcall mockD3DKMTCreateSynchronizationObject2(IN OUT D3DKMT_CREATESY
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS __stdcall mockD3DKMTCreateNativeFence(IN OUT D3DKMT_CREATENATIVEFENCE *synchObject) {
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS __stdcall mockD3DKMTSetAllocationPriority(IN CONST D3DKMT_SETALLOCATIONPRIORITY *setAllocationPriority) {
|
NTSTATUS __stdcall mockD3DKMTSetAllocationPriority(IN CONST D3DKMT_SETALLOCATIONPRIORITY *setAllocationPriority) {
|
||||||
if (setAllocationPriority == nullptr || setAllocationPriority->hDevice != DEVICE_HANDLE) {
|
if (setAllocationPriority == nullptr || setAllocationPriority->hDevice != DEVICE_HANDLE) {
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
#define GPUVA (static_cast<D3DGPU_VIRTUAL_ADDRESS>(0x80123000000))
|
#define GPUVA (static_cast<D3DGPU_VIRTUAL_ADDRESS>(0x80123000000))
|
||||||
|
|
||||||
|
typedef struct _D3DKMT_CREATENATIVEFENCE D3DKMT_CREATENATIVEFENCE;
|
||||||
|
|
||||||
void mockSetAdapterInfo(const void *pGfxPlatform, const void *pGTSystemInfo, uint64_t gpuAddressSpace);
|
void mockSetAdapterInfo(const void *pGfxPlatform, const void *pGTSystemInfo, uint64_t gpuAddressSpace);
|
||||||
NTSTATUS __stdcall mockD3DKMTCreateAllocation(IN OUT D3DKMT_CREATEALLOCATION *allocation);
|
NTSTATUS __stdcall mockD3DKMTCreateAllocation(IN OUT D3DKMT_CREATEALLOCATION *allocation);
|
||||||
NTSTATUS __stdcall mockD3DKMTCreateAllocation2(IN OUT D3DKMT_CREATEALLOCATION *allocation);
|
NTSTATUS __stdcall mockD3DKMTCreateAllocation2(IN OUT D3DKMT_CREATEALLOCATION *allocation);
|
||||||
|
@ -47,6 +49,7 @@ NTSTATUS __stdcall mockD3DKMTQueryResourceInfo(IN OUT D3DKMT_QUERYRESOURCEINFO *
|
||||||
NTSTATUS __stdcall mockD3DKMTQueryResourceInfoFromNtHandle(IN OUT D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE *queryResourceInfo);
|
NTSTATUS __stdcall mockD3DKMTQueryResourceInfoFromNtHandle(IN OUT D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE *queryResourceInfo);
|
||||||
NTSTATUS __stdcall mockD3DKMTCreateSynchronizationObject2(IN OUT D3DKMT_CREATESYNCHRONIZATIONOBJECT2 *synchObject);
|
NTSTATUS __stdcall mockD3DKMTCreateSynchronizationObject2(IN OUT D3DKMT_CREATESYNCHRONIZATIONOBJECT2 *synchObject);
|
||||||
NTSTATUS __stdcall mockD3DKMTDestroySynchronizationObject(IN CONST D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *destroySynchronizationObject);
|
NTSTATUS __stdcall mockD3DKMTDestroySynchronizationObject(IN CONST D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *destroySynchronizationObject);
|
||||||
|
NTSTATUS __stdcall mockD3DKMTCreateNativeFence(IN OUT D3DKMT_CREATENATIVEFENCE *synchObject);
|
||||||
NTSTATUS __stdcall mockD3DKMTCreatePagingQueue(IN OUT D3DKMT_CREATEPAGINGQUEUE *createQueue);
|
NTSTATUS __stdcall mockD3DKMTCreatePagingQueue(IN OUT D3DKMT_CREATEPAGINGQUEUE *createQueue);
|
||||||
NTSTATUS __stdcall mockD3DKMTDestroyPagingQueue(IN OUT D3DDDI_DESTROYPAGINGQUEUE *destoryQueue);
|
NTSTATUS __stdcall mockD3DKMTDestroyPagingQueue(IN OUT D3DDDI_DESTROYPAGINGQUEUE *destoryQueue);
|
||||||
NTSTATUS __stdcall mockD3DKMTLock2(IN OUT D3DKMT_LOCK2 *lock2);
|
NTSTATUS __stdcall mockD3DKMTLock2(IN OUT D3DKMT_LOCK2 *lock2);
|
||||||
|
|
|
@ -67,6 +67,9 @@ void *MockOsLibrary::getProcAddress(const std::string &procName) {
|
||||||
if (procName == "D3DKMTCreateSynchronizationObject2") {
|
if (procName == "D3DKMTCreateSynchronizationObject2") {
|
||||||
return reinterpret_cast<void *>(mockD3DKMTCreateSynchronizationObject2);
|
return reinterpret_cast<void *>(mockD3DKMTCreateSynchronizationObject2);
|
||||||
}
|
}
|
||||||
|
if (procName == "D3DKMTCreateNativeFence") {
|
||||||
|
return reinterpret_cast<void *>(mockD3DKMTCreateNativeFence);
|
||||||
|
}
|
||||||
if (procName == "D3DKMTDestroySynchronizationObject") {
|
if (procName == "D3DKMTDestroySynchronizationObject") {
|
||||||
return reinterpret_cast<void *>(mockD3DKMTDestroySynchronizationObject);
|
return reinterpret_cast<void *>(mockD3DKMTDestroySynchronizationObject);
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,7 @@ if(WIN32 OR NOT DISABLE_WDDM_LINUX)
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface.h
|
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface20.h
|
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface20.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface23.h
|
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface23.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface32.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_residency_allocations_container.h
|
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_residency_allocations_container.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_residency_logger.h
|
${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_residency_logger.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_mock_helpers.h
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm_mock_helpers.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2024 Intel Corporation
|
* Copyright (C) 2024-2025 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
@ -20,6 +20,6 @@ class WddmMockInterface : public WddmInterface {
|
||||||
ADDMETHOD_NOBASE_VOIDRETURN(destroyMonitorFence, (MonitoredFence & monitorFence));
|
ADDMETHOD_NOBASE_VOIDRETURN(destroyMonitorFence, (MonitoredFence & monitorFence));
|
||||||
ADDMETHOD_NOBASE(hwQueuesSupported, bool, false, ());
|
ADDMETHOD_NOBASE(hwQueuesSupported, bool, false, ());
|
||||||
ADDMETHOD_NOBASE(submit, bool, true, (uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments));
|
ADDMETHOD_NOBASE(submit, bool, true, (uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments));
|
||||||
ADDMETHOD_NOBASE(createMonitoredFenceForDirectSubmission, bool, true, (MonitoredFence & monitorFence, OsContextWin &osContext));
|
ADDMETHOD_NOBASE(createFenceForDirectSubmission, bool, true, (MonitoredFence & monitorFence, OsContextWin &osContext));
|
||||||
};
|
};
|
||||||
} // namespace NEO
|
} // namespace NEO
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2024 Intel Corporation
|
* Copyright (C) 2019-2025 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
@ -33,7 +33,7 @@ class WddmMockInterface20 : public WddmInterface20 {
|
||||||
return WddmInterface::createMonitoredFence(monitorFence);
|
return WddmInterface::createMonitoredFence(monitorFence);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool createMonitoredFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) override {
|
bool createFenceForDirectSubmission(MonitoredFence &monitorFence, OsContextWin &osContext) override {
|
||||||
return createMonitoredFence(monitorFence);
|
return createMonitoredFence(monitorFence);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "shared/source/os_interface/windows/wddm/wddm_interface.h"
|
||||||
|
|
||||||
|
namespace NEO {
|
||||||
|
class WddmMockInterface32 : public WddmInterface32 {
|
||||||
|
public:
|
||||||
|
using WddmInterface32::WddmInterface32;
|
||||||
|
|
||||||
|
bool createHwQueue(OsContextWin &osContext) override {
|
||||||
|
createHwQueueCalled++;
|
||||||
|
createHwQueueResult = forceCreateHwQueueFail ? false : WddmInterface23::createHwQueue(osContext);
|
||||||
|
return createHwQueueResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyMonitorFence(MonitoredFence &monitorFence) override {
|
||||||
|
destroyMonitorFenceCalled++;
|
||||||
|
WddmInterface32::destroyMonitorFence(monitorFence);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool createSyncObject(MonitoredFence &monitorFence) override {
|
||||||
|
createSyncObjectCalled++;
|
||||||
|
WddmInterface32::createSyncObject(monitorFence);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t createHwQueueCalled = 0;
|
||||||
|
uint32_t createSyncObjectCalled = 0;
|
||||||
|
bool forceCreateHwQueueFail = false;
|
||||||
|
bool createHwQueueResult = false;
|
||||||
|
|
||||||
|
uint32_t destroyMonitorFenceCalled = 0;
|
||||||
|
};
|
||||||
|
} // namespace NEO
|
|
@ -9,5 +9,6 @@ if(UNIX AND NOT DISABLE_WDDM_LINUX)
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/configure_device_address_space_drm_or_wddm_test.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/configure_device_address_space_drm_or_wddm_test.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/ccs_mode_drm_or_wddm_test.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/ccs_mode_drm_or_wddm_test.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm32_tests_extra.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shared/test/unit_test/os_interface/windows/wddm32_tests.h"
|
||||||
|
|
||||||
|
using namespace NEO;
|
||||||
|
|
||||||
|
TEST_F(Wddm32Tests, whencreateMonitoredFenceForDirectSubmissionThenObtainHwQueueFenceAndReplaceResidencyControllerWithNewFence) {
|
||||||
|
MonitoredFence fence{};
|
||||||
|
EXPECT_THROW(wddm->getWddmInterface()->createFenceForDirectSubmission(fence, *osContext), std::exception);
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (C) 2019-2024 Intel Corporation
|
# Copyright (C) 2019-2025 Intel Corporation
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
#
|
#
|
||||||
|
@ -34,6 +34,7 @@ if(WIN32)
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_special_heap_test.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm_special_heap_test.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_memory_reservation_tests.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm_memory_reservation_tests.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_windows_tests.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm_windows_tests.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm32_tests_extra.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/${BRANCH_DIR_SUFFIX}/wddm_perf_tests.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/${BRANCH_DIR_SUFFIX}/wddm_perf_tests.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
@ -43,6 +44,7 @@ if(WIN32 OR(UNIX AND NOT DISABLE_WDDM_LINUX))
|
||||||
${IGDRCL_SRC_tests_wddm_interface}
|
${IGDRCL_SRC_tests_wddm_interface}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm20_tests.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm20_tests.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm23_tests.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm23_tests.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm32_tests.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/gdi_interface_tests.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/gdi_interface_tests.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_address_space_tests.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm_address_space_tests.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_mapper_tests.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/wddm_mapper_tests.cpp
|
||||||
|
|
|
@ -348,7 +348,7 @@ TEST_F(Wddm20WithMockGdiDllTests, GivenCpuValueDifferentThanGpuHangIndicationWhe
|
||||||
|
|
||||||
TEST_F(Wddm20WithMockGdiDllTests, whencreateMonitoredFenceForDirectSubmissionThenCreateFence) {
|
TEST_F(Wddm20WithMockGdiDllTests, whencreateMonitoredFenceForDirectSubmissionThenCreateFence) {
|
||||||
MonitoredFence fence{};
|
MonitoredFence fence{};
|
||||||
wddm->getWddmInterface()->createMonitoredFenceForDirectSubmission(fence, *osContext);
|
wddm->getWddmInterface()->createFenceForDirectSubmission(fence, *osContext);
|
||||||
EXPECT_EQ(wddmMockInterface->createMonitoredFenceCalled, 1u);
|
EXPECT_EQ(wddmMockInterface->createMonitoredFenceCalled, 1u);
|
||||||
EXPECT_NE(osContext->getHwQueue().progressFenceHandle, fence.fenceHandle);
|
EXPECT_NE(osContext->getHwQueue().progressFenceHandle, fence.fenceHandle);
|
||||||
wddm->getWddmInterface()->destroyMonitorFence(fence);
|
wddm->getWddmInterface()->destroyMonitorFence(fence);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018-2024 Intel Corporation
|
* Copyright (C) 2018-2025 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
@ -114,7 +114,7 @@ TEST_F(Wddm23Tests, whencreateMonitoredFenceForDirectSubmissionThenObtainHwQueue
|
||||||
osContext->getResidencyController().getMonitoredFence().currentFenceValue = 2u;
|
osContext->getResidencyController().getMonitoredFence().currentFenceValue = 2u;
|
||||||
osContext->getResidencyController().getMonitoredFence().lastSubmittedFence = 1u;
|
osContext->getResidencyController().getMonitoredFence().lastSubmittedFence = 1u;
|
||||||
MonitoredFence fence{};
|
MonitoredFence fence{};
|
||||||
wddm->getWddmInterface()->createMonitoredFenceForDirectSubmission(fence, *osContext);
|
wddm->getWddmInterface()->createFenceForDirectSubmission(fence, *osContext);
|
||||||
EXPECT_EQ(osContext->getHwQueue().progressFenceHandle, fence.fenceHandle);
|
EXPECT_EQ(osContext->getHwQueue().progressFenceHandle, fence.fenceHandle);
|
||||||
EXPECT_NE(osContext->getResidencyController().getMonitoredFence().fenceHandle, osContext->getHwQueue().progressFenceHandle);
|
EXPECT_NE(osContext->getResidencyController().getMonitoredFence().fenceHandle, osContext->getHwQueue().progressFenceHandle);
|
||||||
EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().currentFenceValue, 2u);
|
EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().currentFenceValue, 2u);
|
||||||
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shared/test/unit_test/os_interface/windows/wddm32_tests.h"
|
||||||
|
|
||||||
|
#include "shared/test/common/helpers/debug_manager_state_restore.h"
|
||||||
|
#include "shared/test/common/helpers/variable_backup.h"
|
||||||
|
|
||||||
|
using namespace NEO;
|
||||||
|
|
||||||
|
TEST_F(Wddm32Tests, whenGetDedicatedVideoMemoryIsCalledThenCorrectValueIsReturned) {
|
||||||
|
EXPECT_EQ(wddm->dedicatedVideoMemory, wddm->getDedicatedVideoMemory());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Wddm32Tests, whenCreateContextIsCalledThenEnableHwQueues) {
|
||||||
|
EXPECT_TRUE(wddm->wddmInterface->hwQueuesSupported());
|
||||||
|
EXPECT_EQ(1u, getCreateContextDataFcn()->Flags.HwQueueSupported);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Wddm32Tests, givenPreemptionModeWhenCreateHwQueueCalledThenSetGpuTimeoutIfEnabled) {
|
||||||
|
auto &gfxCoreHelper = this->executionEnvironment.rootDeviceEnvironments[0]->getHelper<GfxCoreHelper>();
|
||||||
|
auto defaultEngine = gfxCoreHelper.getGpgpuEngineInstances(*this->executionEnvironment.rootDeviceEnvironments[0])[0];
|
||||||
|
OsContextWin osContextWithoutPreemption(*wddm, 0, 0u,
|
||||||
|
EngineDescriptorHelper::getDefaultDescriptor(defaultEngine, PreemptionMode::Disabled));
|
||||||
|
OsContextWin osContextWithPreemption(*wddm, 0, 0, EngineDescriptorHelper::getDefaultDescriptor(defaultEngine, PreemptionMode::MidBatch));
|
||||||
|
|
||||||
|
wddm->wddmInterface->createHwQueue(osContextWithoutPreemption);
|
||||||
|
EXPECT_EQ(0u, getCreateHwQueueDataFcn()->Flags.DisableGpuTimeout);
|
||||||
|
|
||||||
|
wddm->wddmInterface->createHwQueue(osContextWithPreemption);
|
||||||
|
EXPECT_EQ(1u, getCreateHwQueueDataFcn()->Flags.DisableGpuTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Wddm32Tests, whenDestroyHwQueueCalledThenPassExistingHandle) {
|
||||||
|
D3DKMT_HANDLE hwQueue = 123;
|
||||||
|
osContext->setHwQueue({hwQueue, 0, nullptr, 0});
|
||||||
|
wddmMockInterface->destroyHwQueue(osContext->getHwQueue().handle);
|
||||||
|
EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue);
|
||||||
|
|
||||||
|
hwQueue = 0;
|
||||||
|
osContext->setHwQueue({hwQueue, 0, nullptr, 0});
|
||||||
|
wddmMockInterface->destroyHwQueue(osContext->getHwQueue().handle);
|
||||||
|
EXPECT_NE(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue); // gdi not called when 0
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Wddm32Tests, whenObjectIsDestructedThenDestroyHwQueue) {
|
||||||
|
D3DKMT_HANDLE hwQueue = 123;
|
||||||
|
osContext->setHwQueue({hwQueue, 0, nullptr, 0});
|
||||||
|
osContext.reset();
|
||||||
|
EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Wddm32Tests, givenCmdBufferWhenSubmitCalledThenSetAllRequiredFiledsAndUpdateMonitoredFence) {
|
||||||
|
uint64_t cmdBufferAddress = 123;
|
||||||
|
size_t cmdSize = 456;
|
||||||
|
auto hwQueue = osContext->getHwQueue();
|
||||||
|
COMMAND_BUFFER_HEADER cmdBufferHeader = {};
|
||||||
|
|
||||||
|
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);
|
||||||
|
EXPECT_EQ(0u, osContext->getResidencyController().getMonitoredFence().lastSubmittedFence);
|
||||||
|
|
||||||
|
WddmSubmitArguments submitArgs = {};
|
||||||
|
submitArgs.contextHandle = osContext->getWddmContextHandle();
|
||||||
|
submitArgs.hwQueueHandle = hwQueue.handle;
|
||||||
|
submitArgs.monitorFence = &osContext->getResidencyController().getMonitoredFence();
|
||||||
|
wddm->submit(cmdBufferAddress, cmdSize, &cmdBufferHeader, submitArgs);
|
||||||
|
|
||||||
|
EXPECT_EQ(cmdBufferAddress, getSubmitCommandToHwQueueDataFcn()->CommandBuffer);
|
||||||
|
EXPECT_EQ(static_cast<UINT>(cmdSize), getSubmitCommandToHwQueueDataFcn()->CommandLength);
|
||||||
|
EXPECT_EQ(hwQueue.handle, getSubmitCommandToHwQueueDataFcn()->hHwQueue);
|
||||||
|
EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().lastSubmittedFence, getSubmitCommandToHwQueueDataFcn()->HwQueueProgressFenceId);
|
||||||
|
EXPECT_EQ(&cmdBufferHeader, getSubmitCommandToHwQueueDataFcn()->pPrivateDriverData);
|
||||||
|
EXPECT_EQ(static_cast<UINT>(sizeof(COMMAND_BUFFER_HEADER)), getSubmitCommandToHwQueueDataFcn()->PrivateDriverDataSize);
|
||||||
|
|
||||||
|
EXPECT_EQ(0u, cmdBufferHeader.MonitorFenceVA);
|
||||||
|
EXPECT_EQ(0u, cmdBufferHeader.MonitorFenceValue);
|
||||||
|
EXPECT_EQ(2u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);
|
||||||
|
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().lastSubmittedFence);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Wddm32Tests, givenDebugVariableSetWhenSubmitCalledThenUseCmdBufferHeaderSizeForPrivateDriverDataSize) {
|
||||||
|
DebugManagerStateRestore restore;
|
||||||
|
debugManager.flags.UseCommandBufferHeaderSizeForWddmQueueSubmission.set(true);
|
||||||
|
|
||||||
|
COMMAND_BUFFER_HEADER cmdBufferHeader = {};
|
||||||
|
|
||||||
|
WddmSubmitArguments submitArgs = {};
|
||||||
|
submitArgs.contextHandle = osContext->getWddmContextHandle();
|
||||||
|
submitArgs.hwQueueHandle = osContext->getHwQueue().handle;
|
||||||
|
submitArgs.monitorFence = &osContext->getResidencyController().getMonitoredFence();
|
||||||
|
wddm->submit(123, 456, &cmdBufferHeader, submitArgs);
|
||||||
|
|
||||||
|
EXPECT_EQ(static_cast<UINT>(sizeof(COMMAND_BUFFER_HEADER)), getSubmitCommandToHwQueueDataFcn()->PrivateDriverDataSize);
|
||||||
|
|
||||||
|
debugManager.flags.UseCommandBufferHeaderSizeForWddmQueueSubmission.set(false);
|
||||||
|
|
||||||
|
cmdBufferHeader = {};
|
||||||
|
submitArgs = {};
|
||||||
|
submitArgs.contextHandle = osContext->getWddmContextHandle();
|
||||||
|
submitArgs.hwQueueHandle = osContext->getHwQueue().handle;
|
||||||
|
submitArgs.monitorFence = &osContext->getResidencyController().getMonitoredFence();
|
||||||
|
wddm->submit(123, 456, &cmdBufferHeader, submitArgs);
|
||||||
|
|
||||||
|
EXPECT_EQ(static_cast<UINT>(MemoryConstants::pageSize), getSubmitCommandToHwQueueDataFcn()->PrivateDriverDataSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Wddm32Tests, whenMonitoredFenceIsCreatedThenSetupAllRequiredFields) {
|
||||||
|
wddm->wddmInterface->createMonitoredFence(*osContext);
|
||||||
|
auto hwQueue = osContext->getHwQueue();
|
||||||
|
|
||||||
|
EXPECT_EQ(hwQueue.progressFenceCpuVA, osContext->getResidencyController().getMonitoredFence().cpuAddress);
|
||||||
|
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);
|
||||||
|
EXPECT_EQ(hwQueue.progressFenceHandle, osContext->getResidencyController().getMonitoredFence().fenceHandle);
|
||||||
|
EXPECT_EQ(hwQueue.progressFenceGpuVA, osContext->getResidencyController().getMonitoredFence().gpuAddress);
|
||||||
|
EXPECT_EQ(0u, osContext->getResidencyController().getMonitoredFence().lastSubmittedFence);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Wddm32Tests, givenCurrentPendingFenceValueGreaterThanPendingFenceValueWhenSubmitCalledThenCallWaitOnGpu) {
|
||||||
|
uint64_t cmdBufferAddress = 123;
|
||||||
|
size_t cmdSize = 456;
|
||||||
|
COMMAND_BUFFER_HEADER cmdBufferHeader = {};
|
||||||
|
|
||||||
|
WddmSubmitArguments submitArgs = {};
|
||||||
|
submitArgs.contextHandle = osContext->getWddmContextHandle();
|
||||||
|
submitArgs.hwQueueHandle = osContext->getHwQueue().handle;
|
||||||
|
submitArgs.monitorFence = &osContext->getResidencyController().getMonitoredFence();
|
||||||
|
|
||||||
|
VariableBackup<volatile uint64_t> pagingFenceBackup(wddm->pagingFenceAddress);
|
||||||
|
*wddm->pagingFenceAddress = 1;
|
||||||
|
wddm->currentPagingFenceValue = 1;
|
||||||
|
|
||||||
|
wddm->submit(cmdBufferAddress, cmdSize, &cmdBufferHeader, submitArgs);
|
||||||
|
EXPECT_EQ(0u, wddm->waitOnGPUResult.called);
|
||||||
|
|
||||||
|
wddm->currentPagingFenceValue = 2;
|
||||||
|
wddm->submit(cmdBufferAddress, cmdSize, &cmdBufferHeader, submitArgs);
|
||||||
|
EXPECT_EQ(1u, wddm->waitOnGPUResult.called);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Wddm32Tests, givenDestructionOsContextWinWhenCallingDestroyMonitorFenceThenDoNotCallDestroy) {
|
||||||
|
osContext.reset(nullptr);
|
||||||
|
EXPECT_EQ(0u, wddmMockInterface->destroyMonitorFenceCalled);
|
||||||
|
EXPECT_EQ(0u, getDestroySynchronizationObjectDataFcn()->hSyncObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Wddm32TestsWithoutWddmInit, whenInitCalledThenInitializeNewGdiDDIsAndCallToCreateHwQueue) {
|
||||||
|
EXPECT_EQ(nullptr, wddm->getGdi()->createHwQueue.mFunc);
|
||||||
|
EXPECT_EQ(nullptr, wddm->getGdi()->destroyHwQueue.mFunc);
|
||||||
|
EXPECT_EQ(nullptr, wddm->getGdi()->submitCommandToHwQueue.mFunc);
|
||||||
|
|
||||||
|
init();
|
||||||
|
EXPECT_EQ(1u, wddmMockInterface->createHwQueueCalled);
|
||||||
|
|
||||||
|
EXPECT_NE(nullptr, wddm->getGdi()->createHwQueue.mFunc);
|
||||||
|
EXPECT_NE(nullptr, wddm->getGdi()->destroyHwQueue.mFunc);
|
||||||
|
EXPECT_NE(nullptr, wddm->getGdi()->submitCommandToHwQueue.mFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Wddm32TestsWithoutWddmInit, whenCreateHwQueueFailedThenReturnFalseFromInit) {
|
||||||
|
wddmMockInterface->forceCreateHwQueueFail = true;
|
||||||
|
EXPECT_ANY_THROW(init());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Wddm32TestsWithoutWddmInit, givenFailureOnGdiInitializationWhenCreatingHwQueueThenReturnFailure) {
|
||||||
|
struct MyMockGdi : public Gdi {
|
||||||
|
bool setupHwQueueProcAddresses() override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto myMockGdi = new MyMockGdi();
|
||||||
|
wddm->resetGdi(myMockGdi);
|
||||||
|
EXPECT_ANY_THROW(init());
|
||||||
|
EXPECT_EQ(1u, wddmMockInterface->createHwQueueCalled);
|
||||||
|
EXPECT_FALSE(wddmMockInterface->createHwQueueResult);
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "shared/source/command_stream/preemption.h"
|
||||||
|
#include "shared/source/helpers/gfx_core_helper.h"
|
||||||
|
#include "shared/source/os_interface/windows/gdi_interface.h"
|
||||||
|
#include "shared/source/os_interface/windows/os_context_win.h"
|
||||||
|
#include "shared/test/common/helpers/engine_descriptor_helper.h"
|
||||||
|
#include "shared/test/common/mocks/mock_execution_environment.h"
|
||||||
|
#include "shared/test/common/mocks/mock_wddm.h"
|
||||||
|
#include "shared/test/common/mocks/mock_wddm_interface32.h"
|
||||||
|
#include "shared/test/common/os_interface/windows/gdi_dll_fixture.h"
|
||||||
|
#include "shared/test/common/test_macros/hw_test.h"
|
||||||
|
|
||||||
|
using namespace NEO;
|
||||||
|
|
||||||
|
struct Wddm32TestsWithoutWddmInit : public ::testing::Test, GdiDllFixture {
|
||||||
|
void SetUp() override {
|
||||||
|
GdiDllFixture::setUp();
|
||||||
|
|
||||||
|
wddm = static_cast<WddmMock *>(Wddm::createWddm(nullptr, *executionEnvironment.rootDeviceEnvironments[0].get()));
|
||||||
|
auto &osInterface = executionEnvironment.rootDeviceEnvironments[0]->osInterface;
|
||||||
|
osInterface = std::make_unique<OSInterface>();
|
||||||
|
osInterface->setDriverModel(std::unique_ptr<DriverModel>(wddm));
|
||||||
|
|
||||||
|
wddm->featureTable->flags.ftrWddmHwQueues = true;
|
||||||
|
wddmMockInterface = new WddmMockInterface32(*wddm);
|
||||||
|
wddm->wddmInterface.reset(wddmMockInterface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
auto preemptionMode = PreemptionHelper::getDefaultPreemptionMode(*defaultHwInfo);
|
||||||
|
wddmMockInterface = static_cast<WddmMockInterface32 *>(wddm->wddmInterface.release());
|
||||||
|
wddm->init();
|
||||||
|
wddm->wddmInterface.reset(wddmMockInterface);
|
||||||
|
auto &gfxCoreHelper = this->executionEnvironment.rootDeviceEnvironments[0]->getHelper<GfxCoreHelper>();
|
||||||
|
osContext = std::make_unique<OsContextWin>(*wddm, 0, 0u,
|
||||||
|
EngineDescriptorHelper::getDefaultDescriptor(gfxCoreHelper.getGpgpuEngineInstances(*this->executionEnvironment.rootDeviceEnvironments[0])[0], preemptionMode));
|
||||||
|
osContext->ensureContextInitialized(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown() override {
|
||||||
|
GdiDllFixture::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
MockExecutionEnvironment executionEnvironment;
|
||||||
|
std::unique_ptr<OsContextWin> osContext;
|
||||||
|
WddmMock *wddm = nullptr;
|
||||||
|
WddmMockInterface32 *wddmMockInterface = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Wddm32Tests : public Wddm32TestsWithoutWddmInit {
|
||||||
|
using Wddm32TestsWithoutWddmInit::TearDown;
|
||||||
|
void SetUp() override {
|
||||||
|
Wddm32TestsWithoutWddmInit::SetUp();
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shared/test/unit_test/os_interface/windows/wddm32_tests.h"
|
||||||
|
|
||||||
|
using namespace NEO;
|
||||||
|
|
||||||
|
TEST_F(Wddm32Tests, whencreateMonitoredFenceForDirectSubmissionThenObtainHwQueueFenceAndReplaceResidencyControllerWithNewFence) {
|
||||||
|
MonitoredFence fence{};
|
||||||
|
wddm->getWddmInterface()->createFenceForDirectSubmission(fence, *osContext);
|
||||||
|
EXPECT_EQ(wddmMockInterface->createSyncObjectCalled, 1u);
|
||||||
|
}
|
Loading…
Reference in New Issue