diff --git a/src/d3d/nvapi_d3d_instance.cpp b/src/d3d/nvapi_d3d_instance.cpp index 6cdf2609..44441719 100644 --- a/src/d3d/nvapi_d3d_instance.cpp +++ b/src/d3d/nvapi_d3d_instance.cpp @@ -1,4 +1,5 @@ #include "../util/util_log.h" +#include "nvapi_d3d_low_latency_device.h" #include "nvapi_d3d_instance.h" namespace dxvk { @@ -13,25 +14,35 @@ namespace dxvk { log::write("LatencyFleX loaded and initialized successfully"); } - bool NvapiD3dInstance::IsReflexAvailable() { - return m_lfx->IsAvailable(); + bool NvapiD3dInstance::IsReflexAvailable(IUnknown* device) { + return NvapiD3dLowLatencyDevice::SupportsLowLatency(device) || m_lfx->IsAvailable(); } - bool NvapiD3dInstance::IsReflexEnabled() const { - return m_isLfxEnabled; + bool NvapiD3dInstance::IsLowLatencyEnabled() const { + return m_isLowLatencyEnabled; } - void NvapiD3dInstance::SetReflexEnabled(bool value) { - m_isLfxEnabled = value; + bool NvapiD3dInstance::IsUsingLfx() const { + return m_lfx->IsAvailable(); } - void NvapiD3dInstance::Sleep() { - if (m_isLfxEnabled) - m_lfx->WaitAndBeginFrame(); + void NvapiD3dInstance::SetReflexMode(IUnknown* device, bool enable, bool boost, uint64_t frameTimeUs) { + if (IsReflexAvailable(device)) { + m_isLowLatencyEnabled = enable; + } + + if (m_lfx->IsAvailable() && enable) { + constexpr uint64_t kNanoInMicro = 1000; + m_lfx->SetTargetFrameTime(frameTimeUs * kNanoInMicro); + } else if (NvapiD3dLowLatencyDevice::SupportsLowLatency(device)) { + NvapiD3dLowLatencyDevice::SetLatencySleepMode(device, enable, boost, frameTimeUs); + } } - void NvapiD3dInstance::SetTargetFrameTime(uint64_t frameTimeUs) { - constexpr uint64_t kNanoInMicro = 1000; - m_lfx->SetTargetFrameTime(frameTimeUs * kNanoInMicro); + void NvapiD3dInstance::Sleep(IUnknown* device) { + if (m_lfx->IsAvailable() && m_isLowLatencyEnabled) + m_lfx->WaitAndBeginFrame(); + else if (NvapiD3dLowLatencyDevice::SupportsLowLatency(device)) + NvapiD3dLowLatencyDevice::LatencySleep(device); } } \ No newline at end of file diff --git a/src/d3d/nvapi_d3d_instance.h b/src/d3d/nvapi_d3d_instance.h index 5a223714..9f46652d 100644 --- a/src/d3d/nvapi_d3d_instance.h +++ b/src/d3d/nvapi_d3d_instance.h @@ -10,15 +10,15 @@ namespace dxvk { ~NvapiD3dInstance(); void Initialize(); - [[nodiscard]] bool IsReflexAvailable(); - [[nodiscard]] bool IsReflexEnabled() const; - void SetReflexEnabled(bool value); - void Sleep(); - void SetTargetFrameTime(uint64_t frameTimeUs); + [[nodiscard]] bool IsReflexAvailable(IUnknown* device); + [[nodiscard]] bool IsLowLatencyEnabled() const; + [[nodiscard]] bool IsUsingLfx() const; + void SetReflexMode(IUnknown* device, bool enable, bool boost, uint64_t frameTimeUs); + void Sleep(IUnknown* device); private: ResourceFactory& m_resourceFactory; std::unique_ptr m_lfx; - bool m_isLfxEnabled = false; + bool m_isLowLatencyEnabled = false; }; } \ No newline at end of file diff --git a/src/d3d/nvapi_d3d_low_latency_device.cpp b/src/d3d/nvapi_d3d_low_latency_device.cpp new file mode 100644 index 00000000..f9e7089e --- /dev/null +++ b/src/d3d/nvapi_d3d_low_latency_device.cpp @@ -0,0 +1,58 @@ +#include "nvapi_d3d_low_latency_device.h" + +namespace dxvk { + bool NvapiD3dLowLatencyDevice::SupportsLowLatency(IUnknown* pDevice) { + auto d3dLowLatencyDevice = GetLowLatencyDevice(pDevice); + if (d3dLowLatencyDevice == nullptr) + return false; + + return d3dLowLatencyDevice->SupportsLowLatency(); + } + + bool NvapiD3dLowLatencyDevice::LatencySleep(IUnknown* pDevice) { + auto d3dLowLatencyDevice = GetLowLatencyDevice(pDevice); + if (d3dLowLatencyDevice == nullptr) + return false; + + return d3dLowLatencyDevice->LatencySleep(); + } + + bool NvapiD3dLowLatencyDevice::SetLatencySleepMode(IUnknown* pDevice, bool lowLatencyMode, bool lowLatencyBoost, uint32_t minimumIntervalUs) { + auto d3dLowLatencyDevice = GetLowLatencyDevice(pDevice); + if (d3dLowLatencyDevice == nullptr) + return false; + + return d3dLowLatencyDevice->SetLatencySleepMode(lowLatencyMode, lowLatencyBoost, minimumIntervalUs); + } + + bool NvapiD3dLowLatencyDevice::GetLatencyInfo(IUnknown* pDevice, D3D_LATENCY_RESULTS* latency_results) { + auto d3dLowLatencyDevice = GetLowLatencyDevice(pDevice); + if (d3dLowLatencyDevice == nullptr) + return false; + + return d3dLowLatencyDevice->GetLatencyInfo(latency_results); + } + + bool NvapiD3dLowLatencyDevice::SetLatencyMarker(IUnknown* pDevice, uint64_t frameID, uint32_t markerType) { + auto d3dLowLatencyDevice = GetLowLatencyDevice(pDevice); + if (d3dLowLatencyDevice == nullptr) + return false; + + return d3dLowLatencyDevice->SetLatencyMarker(frameID, markerType); + } + + Com NvapiD3dLowLatencyDevice::GetLowLatencyDevice(IUnknown* device) { + std::scoped_lock lock(m_LowLatencyDeviceMutex); + auto it = m_lowLatencyDeviceMap.find(device); + if (it != m_lowLatencyDeviceMap.end()) + return it->second; + + Com d3dLowLatencyDevice; + if (FAILED(device->QueryInterface(IID_PPV_ARGS(&d3dLowLatencyDevice)))) + return nullptr; + + m_lowLatencyDeviceMap.emplace(device, d3dLowLatencyDevice.ptr()); + + return d3dLowLatencyDevice; + } +} diff --git a/src/d3d/nvapi_d3d_low_latency_device.h b/src/d3d/nvapi_d3d_low_latency_device.h new file mode 100644 index 00000000..650332f2 --- /dev/null +++ b/src/d3d/nvapi_d3d_low_latency_device.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../nvapi_private.h" +#include "../shared/shared_interfaces.h" +#include "../util/com_pointer.h" + +namespace dxvk { + class NvapiD3dLowLatencyDevice { + public: + static bool SupportsLowLatency(IUnknown* pDevice); + static bool LatencySleep(IUnknown* pDevice); + static bool SetLatencySleepMode(IUnknown* pDevice, bool lowLatencyMode, bool lowLatencyBoost, uint32_t minimumIntervalUs); + static bool GetLatencyInfo(IUnknown* pDevice, D3D_LATENCY_RESULTS* latency_results); + static bool SetLatencyMarker(IUnknown* pDevice, uint64_t frameID, uint32_t markerType); + + private: + inline static std::unordered_map m_lowLatencyDeviceMap; + + inline static std::mutex m_LowLatencyDeviceMutex; + + [[nodiscard]] static Com GetLowLatencyDevice(IUnknown* device); + }; +} \ No newline at end of file diff --git a/src/d3d12/nvapi_d3d12_device.cpp b/src/d3d12/nvapi_d3d12_device.cpp index 0d30d347..b69fa982 100644 --- a/src/d3d12/nvapi_d3d12_device.cpp +++ b/src/d3d12/nvapi_d3d12_device.cpp @@ -81,6 +81,14 @@ namespace dxvk { return SUCCEEDED(cubinDevice->GetCudaSurfaceObject(uavHandle, reinterpret_cast(cudaSurfaceHandle))); } + bool NvapiD3d12Device::NotifyOutOfBandCommandQueue(ID3D12CommandQueue* commandQueue, D3D12_OUT_OF_BAND_CQ_TYPE type) { + auto commandQueueExt = GetCommandQueueExt(commandQueue); + if (commandQueueExt == nullptr) + return false; + + return SUCCEEDED(commandQueueExt->NotifyOutOfBandCommandQueue(type)); + } + bool NvapiD3d12Device::LaunchCubinShader(ID3D12GraphicsCommandList* commandList, NVDX_ObjectHandle pShader, NvU32 blockX, NvU32 blockY, NvU32 blockZ, const void* params, NvU32 paramSize) { auto commandListExt = GetCommandListExt(commandList); if (!commandListExt.has_value()) @@ -146,6 +154,22 @@ namespace dxvk { return deviceExt; } + Com NvapiD3d12Device::GetCommandQueueExt(ID3D12CommandQueue* commandQueue) { + std::scoped_lock lock(m_commandQueueMutex); + auto it = m_commandQueueMap.find(commandQueue); + if (it != m_commandQueueMap.end()) + return it->second; + + Com commandQueueExt; + if (FAILED(commandQueue->QueryInterface(IID_PPV_ARGS(&commandQueueExt)))) + return nullptr; + + if (commandQueueExt != nullptr) + m_commandQueueMap.emplace(commandQueue, commandQueueExt.ptr()); + + return commandQueueExt; + } + std::optional NvapiD3d12Device::GetCommandListExt(ID3D12GraphicsCommandList* commandList) { std::scoped_lock lock(m_commandListMutex); auto it = m_commandListMap.find(commandList); @@ -169,11 +193,13 @@ namespace dxvk { } void NvapiD3d12Device::ClearCacheMaps() { + std::scoped_lock commandQueueLock(m_commandQueueMutex); std::scoped_lock commandListLock(m_commandListMutex); std::scoped_lock cubinDeviceLock(m_cubinDeviceMutex); std::scoped_lock cubinSmemLock(m_cubinSmemMutex); m_cubinDeviceMap.clear(); + m_commandQueueMap.clear(); m_commandListMap.clear(); m_cubinSmemMap.clear(); } diff --git a/src/d3d12/nvapi_d3d12_device.h b/src/d3d12/nvapi_d3d12_device.h index ef419d34..386de906 100644 --- a/src/d3d12/nvapi_d3d12_device.h +++ b/src/d3d12/nvapi_d3d12_device.h @@ -24,6 +24,7 @@ namespace dxvk { static bool DestroyCubinComputeShader(ID3D12Device* device, NVDX_ObjectHandle shader); static bool GetCudaTextureObject(ID3D12Device* device, D3D12_CPU_DESCRIPTOR_HANDLE srvHandle, D3D12_CPU_DESCRIPTOR_HANDLE samplerHandle, NvU32* cudaTextureHandle); static bool GetCudaSurfaceObject(ID3D12Device* device, D3D12_CPU_DESCRIPTOR_HANDLE uavHandle, NvU32* cudaSurfaceHandle); + static bool NotifyOutOfBandCommandQueue(ID3D12CommandQueue* commandQueue, D3D12_OUT_OF_BAND_CQ_TYPE type); static bool LaunchCubinShader(ID3D12GraphicsCommandList* commandList, NVDX_ObjectHandle shader, NvU32 blockX, NvU32 blockY, NvU32 blockZ, const void* params, NvU32 paramSize); static bool CaptureUAVInfo(ID3D12Device* device, NVAPI_UAV_INFO* uavInfo); static bool IsFatbinPTXSupported(ID3D12Device* device); @@ -32,15 +33,18 @@ namespace dxvk { private: inline static std::unordered_map m_cubinDeviceMap; + inline static std::unordered_map m_commandQueueMap; inline static std::unordered_map m_commandListMap; inline static std::unordered_map m_cubinSmemMap; inline static std::mutex m_commandListMutex; + inline static std::mutex m_commandQueueMutex; inline static std::mutex m_cubinDeviceMutex; inline static std::mutex m_cubinSmemMutex; [[nodiscard]] static Com GetCubinDevice(ID3D12Device* device); [[nodiscard]] static Com GetDeviceExt(ID3D12Device* device, D3D12_VK_EXTENSION extension); + [[nodiscard]] static Com GetCommandQueueExt(ID3D12CommandQueue* commandQueue); [[nodiscard]] static std::optional GetCommandListExt(ID3D12GraphicsCommandList* commandList); }; } diff --git a/src/meson.build b/src/meson.build index 98410c0f..daabb3f8 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,6 +1,7 @@ nvapi_src = files([ 'dxvk/dxvk_interfaces.cpp', 'vkd3d-proton/vkd3d-proton_interfaces.cpp', + 'shared/shared_interfaces.cpp', 'util/util_string.cpp', 'util/util_env.cpp', 'util/util_log.cpp', @@ -12,6 +13,7 @@ nvapi_src = files([ 'resource_factory.cpp', 'd3d/lfx.cpp', 'd3d/nvapi_d3d_instance.cpp', + 'd3d/nvapi_d3d_low_latency_device.cpp', 'd3d11/nvapi_d3d11_device.cpp', 'd3d12/nvapi_d3d12_device.cpp', 'nvapi_globals.cpp', diff --git a/src/nvapi_d3d.cpp b/src/nvapi_d3d.cpp index 7f1168bf..64628001 100644 --- a/src/nvapi_d3d.cpp +++ b/src/nvapi_d3d.cpp @@ -1,3 +1,5 @@ +#include "dxvk/dxvk_interfaces.h" +#include "d3d/nvapi_d3d_low_latency_device.h" #include "nvapi_private.h" #include "nvapi_globals.h" #include "util/util_statuscode.h" @@ -112,10 +114,10 @@ extern "C" { if (nvapiAdapterRegistry == nullptr) return ApiNotInitialized(n); - if (!nvapiD3dInstance->IsReflexAvailable()) + if (!nvapiD3dInstance->IsReflexAvailable(pDevice)) return NoImplementation(n, alreadyLoggedNoLfx); - nvapiD3dInstance->Sleep(); + nvapiD3dInstance->Sleep(pDevice); return Ok(n, alreadyLoggedOk); } @@ -130,12 +132,13 @@ extern "C" { if (pSetSleepModeParams->version != NV_SET_SLEEP_MODE_PARAMS_VER1) return IncompatibleStructVersion(n); - if (!nvapiD3dInstance->IsReflexAvailable()) + if (!nvapiD3dInstance->IsReflexAvailable(pDevice)) return NoImplementation(n, alreadyLoggedNoLfx); - nvapiD3dInstance->SetReflexEnabled(pSetSleepModeParams->bLowLatencyMode); - if (pSetSleepModeParams->bLowLatencyMode) - nvapiD3dInstance->SetTargetFrameTime(pSetSleepModeParams->minimumIntervalUs); + bool lowLatencyMode = pSetSleepModeParams->bLowLatencyMode; + bool lowLatencyBoost = pSetSleepModeParams->bLowLatencyBoost; + uint64_t minimumIntervalUs = pSetSleepModeParams->minimumIntervalUs; + nvapiD3dInstance->SetReflexMode(pDevice, lowLatencyMode, lowLatencyBoost, minimumIntervalUs); return Ok(str::format(n, " (", pSetSleepModeParams->bLowLatencyMode ? (str::format("Enabled/", pSetSleepModeParams->minimumIntervalUs, "us")) : "Disabled", ")")); } @@ -150,20 +153,47 @@ extern "C" { if (pGetSleepStatusParams->version != NV_GET_SLEEP_STATUS_PARAMS_VER1) return IncompatibleStructVersion(n); - if (!nvapiD3dInstance->IsReflexAvailable()) + if (!nvapiD3dInstance->IsReflexAvailable(pDevice)) return NoImplementation(n, alreadyLoggedNoLfx); - pGetSleepStatusParams->bLowLatencyMode = nvapiD3dInstance->IsReflexEnabled(); + pGetSleepStatusParams->bLowLatencyMode = nvapiD3dInstance->IsLowLatencyEnabled(); + return Ok(n); } NvAPI_Status __cdecl NvAPI_D3D_GetLatency(IUnknown* pDev, NV_LATENCY_RESULT_PARAMS* pGetLatencyParams) { + constexpr auto n = __func__; static bool alreadyLogged = false; - return NoImplementation(__func__, alreadyLogged); + + if (nvapiAdapterRegistry == nullptr) + return ApiNotInitialized(n); + + if (pGetLatencyParams->version != NV_LATENCY_RESULT_PARAMS_VER1) + return IncompatibleStructVersion(n); + + if (nvapiD3dInstance->IsUsingLfx() || !NvapiD3dLowLatencyDevice::SupportsLowLatency(pDev)) + return NoImplementation(n, alreadyLogged); + + NvapiD3dLowLatencyDevice::GetLatencyInfo(pDev, reinterpret_cast(pGetLatencyParams)); + + return Ok(n); } NvAPI_Status __cdecl NvAPI_D3D_SetLatencyMarker(IUnknown* pDev, NV_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams) { + constexpr auto n = __func__; static bool alreadyLogged = false; - return NoImplementation(__func__, alreadyLogged); + + if (nvapiAdapterRegistry == nullptr) + return ApiNotInitialized(n); + + if (pSetLatencyMarkerParams->version != NV_LATENCY_MARKER_PARAMS_VER1) + return IncompatibleStructVersion(n); + + if (nvapiD3dInstance->IsUsingLfx() || !NvapiD3dLowLatencyDevice::SupportsLowLatency(pDev)) + return NoImplementation(n, alreadyLogged); + + NvapiD3dLowLatencyDevice::SetLatencyMarker(pDev, pSetLatencyMarkerParams->frameID, pSetLatencyMarkerParams->markerType); + + return Ok(n); } } diff --git a/src/nvapi_d3d12.cpp b/src/nvapi_d3d12.cpp index aadd7f22..922b19a0 100644 --- a/src/nvapi_d3d12.cpp +++ b/src/nvapi_d3d12.cpp @@ -1,5 +1,6 @@ #include "nvapi_private.h" #include "nvapi_globals.h" +#include "d3d/nvapi_d3d_low_latency_device.h" #include "d3d12/nvapi_d3d12_device.h" #include "util/util_statuscode.h" #include "util/util_op_code.h" @@ -397,4 +398,51 @@ extern "C" { return Ok(n, alreadyLoggedOk); } + + NvAPI_Status __cdecl NvAPI_D3D12_NotifyOutOfBandCommandQueue(ID3D12CommandQueue* pCommandQueue, NV_OUT_OF_BAND_CQ_TYPE cqType) { + constexpr auto n = __func__; + static bool alreadyLogged = false; + + if (nvapiAdapterRegistry == nullptr) + return ApiNotInitialized(n); + + if (pCommandQueue == nullptr) + return InvalidArgument(n); + + ID3D12Device* pDevice; + if (FAILED(pCommandQueue->GetDevice(IID_PPV_ARGS(&pDevice)))) + return InvalidArgument(n); + + if (nvapiD3dInstance->IsUsingLfx() || !NvapiD3dLowLatencyDevice::SupportsLowLatency(pDevice)) + return NoImplementation(n, alreadyLogged); + + NvapiD3d12Device::NotifyOutOfBandCommandQueue(pCommandQueue, static_cast(cqType)); + + return Ok(n); + } + + NvAPI_Status __cdecl NvAPI_D3D12_SetAsyncFrameMarker(ID3D12CommandQueue* pCommandQueue, NV_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams) { + constexpr auto n = __func__; + static bool alreadyLogged = false; + + if (nvapiAdapterRegistry == nullptr) + return ApiNotInitialized(n); + + if (pSetLatencyMarkerParams->version != NV_LATENCY_MARKER_PARAMS_VER1) + return IncompatibleStructVersion(n); + + if (pCommandQueue == nullptr) + return InvalidArgument(n); + + ID3D12Device* pDevice; + if (FAILED(pCommandQueue->GetDevice(IID_PPV_ARGS(&pDevice)))) + return InvalidArgument(n); + + if (nvapiD3dInstance->IsUsingLfx() || !NvapiD3dLowLatencyDevice::SupportsLowLatency(pDevice)) + return NoImplementation(n, alreadyLogged); + + NvapiD3dLowLatencyDevice::SetLatencyMarker(pDevice, pSetLatencyMarkerParams->frameID, pSetLatencyMarkerParams->markerType); + + return Ok(n); + } } diff --git a/src/nvapi_interface.cpp b/src/nvapi_interface.cpp index b461166e..4b6f24b3 100644 --- a/src/nvapi_interface.cpp +++ b/src/nvapi_interface.cpp @@ -69,6 +69,8 @@ extern "C" { INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingCaps) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx) + INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_NotifyOutOfBandCommandQueue) + INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_SetAsyncFrameMarker) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_GetObjectHandleForResource) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_SetResourceHint) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_GetCurrentSLIState) diff --git a/src/shared/shared_interfaces.cpp b/src/shared/shared_interfaces.cpp new file mode 100644 index 00000000..2d675ebc --- /dev/null +++ b/src/shared/shared_interfaces.cpp @@ -0,0 +1,3 @@ +#include "shared_interfaces.h" + +const GUID ID3DLowLatencyDevice::guid = {0xf3112584, 0x41f9, 0x348d, {0xa5, 0x9b, 0x00, 0xb7, 0xe1, 0xd2, 0x85, 0xd6}}; diff --git a/src/shared/shared_interfaces.h b/src/shared/shared_interfaces.h new file mode 100644 index 00000000..3baebb9a --- /dev/null +++ b/src/shared/shared_interfaces.h @@ -0,0 +1,61 @@ +#pragma once + +#include "../nvapi_private.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#endif // __GNUC__ + +#define SHARED_DEFINE_GUID(iface) \ + template <> \ + inline GUID const& __mingw_uuidof() { return iface::guid; } + +/** + * \brief Frame Report Info + */ +typedef struct D3D_LATENCY_RESULTS { + UINT32 version; + struct D3D_FRAME_REPORT { + UINT64 frameID; + UINT64 inputSampleTime; + UINT64 simStartTime; + UINT64 simEndTime; + UINT64 renderSubmitStartTime; + UINT64 renderSubmitEndTime; + UINT64 presentStartTime; + UINT64 presentEndTime; + UINT64 driverStartTime; + UINT64 driverEndTime; + UINT64 osRenderQueueStartTime; + UINT64 osRenderQueueEndTime; + UINT64 gpuRenderStartTime; + UINT64 gpuRenderEndTime; + UINT32 gpuActiveRenderTimeUs; + UINT32 gpuFrameTimeUs; + UINT8 rsvd[120]; + } frame_reports[64]; + UINT8 rsvd[32]; +} D3D_LATENCY_RESULTS; + +MIDL_INTERFACE("f3112584-41f9-348d-a59b-00b7e1d285d6") +ID3DLowLatencyDevice : public IUnknown { + static const GUID guid; + + virtual BOOL STDMETHODCALLTYPE SupportsLowLatency() = 0; + + virtual HRESULT STDMETHODCALLTYPE LatencySleep() = 0; + + virtual HRESULT STDMETHODCALLTYPE SetLatencySleepMode( + BOOL lowLatencyMode, + BOOL lowLatencyBoost, + uint32_t minimumIntervalUs) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetLatencyMarker( + uint64_t frameID, + uint32_t markerType) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetLatencyInfo( + D3D_LATENCY_RESULTS * latency_results) = 0; +}; + +SHARED_DEFINE_GUID(ID3DLowLatencyDevice) diff --git a/src/vkd3d-proton/vkd3d-proton_interfaces.cpp b/src/vkd3d-proton/vkd3d-proton_interfaces.cpp index 03a4acd1..7b41fb7d 100644 --- a/src/vkd3d-proton/vkd3d-proton_interfaces.cpp +++ b/src/vkd3d-proton/vkd3d-proton_interfaces.cpp @@ -20,3 +20,4 @@ const GUID ID3D12DeviceExt::guid = {0x11ea7a1a, 0x0f6a, 0x49bf, {0xb6, 0x12, 0x3e, 0x30, 0xf8, 0xe2, 0x01, 0xdd}}; const GUID ID3D12GraphicsCommandListExt::guid = {0x77a86b09, 0x2bea, 0x4801, {0xb8, 0x9a, 0x37, 0x64, 0x8e, 0x10, 0x4a, 0xf1}}; const GUID ID3D12GraphicsCommandListExt1::guid = {0xd53b0028, 0xafb4, 0x4b65, {0xa4, 0xf1, 0x7b, 0x0d, 0xaa, 0xa6, 0x5b, 0x4f}}; +const GUID ID3D12CommandQueueExt::guid = {0x40ed3f96, 0xe773, 0xe9bc, {0xfc, 0x0c, 0xe9, 0x55, 0x60, 0xc9, 0x9a, 0xd6}}; diff --git a/src/vkd3d-proton/vkd3d-proton_interfaces.h b/src/vkd3d-proton/vkd3d-proton_interfaces.h index 8f388ac6..b16f38d7 100644 --- a/src/vkd3d-proton/vkd3d-proton_interfaces.h +++ b/src/vkd3d-proton/vkd3d-proton_interfaces.h @@ -29,7 +29,13 @@ enum D3D12_VK_EXTENSION : uint32_t { D3D12_VK_NVX_BINARY_IMPORT = 0x1, - D3D12_VK_NVX_IMAGE_VIEW_HANDLE = 0x2 + D3D12_VK_NVX_IMAGE_VIEW_HANDLE = 0x2, + D3D12_VK_NV_LOW_LATENCY_2 = 0x3 +}; + +enum D3D12_OUT_OF_BAND_CQ_TYPE : uint32_t { + D3D_OUT_OF_BAND_RENDER = 0x0, + D3D_OUT_OF_BAND_PRESENT = 0x1 }; struct D3D12_CUBIN_DATA_HANDLE { @@ -114,6 +120,15 @@ ID3D12GraphicsCommandListExt1 : public ID3D12GraphicsCommandListExt { UINT32 raw_params_count) = 0; }; +MIDL_INTERFACE("40ed3f96-e773-e9bc-fc0c-e95560c99ad6") +ID3D12CommandQueueExt : public IUnknown { + static const GUID guid; + + virtual HRESULT STDMETHODCALLTYPE NotifyOutOfBandCommandQueue( + D3D12_OUT_OF_BAND_CQ_TYPE type) = 0; +}; + VKD3D_PROTON_GUID(ID3D12DeviceExt) VKD3D_PROTON_GUID(ID3D12GraphicsCommandListExt) VKD3D_PROTON_GUID(ID3D12GraphicsCommandListExt1) +VKD3D_PROTON_GUID(ID3D12CommandQueueExt)