|
15 | 15 | #include "d3d11_device.h"
|
16 | 16 | #include "d3d11_fence.h"
|
17 | 17 | #include "d3d11_input_layout.h"
|
| 18 | +#include "d3d11_interfaces.h" |
18 | 19 | #include "d3d11_interop.h"
|
19 | 20 | #include "d3d11_query.h"
|
20 | 21 | #include "d3d11_resource.h"
|
@@ -2469,12 +2470,14 @@ namespace dxvk {
|
2469 | 2470 | return deviceFeatures.nvxBinaryImport
|
2470 | 2471 | && deviceFeatures.vk12.bufferDeviceAddress;
|
2471 | 2472 |
|
| 2473 | + case D3D11_VK_NV_LOW_LATENCY_2: |
| 2474 | + return deviceFeatures.nvLowLatency2; |
| 2475 | + |
2472 | 2476 | default:
|
2473 | 2477 | return false;
|
2474 | 2478 | }
|
2475 | 2479 | }
|
2476 |
| - |
2477 |
| - |
| 2480 | + |
2478 | 2481 | bool STDMETHODCALLTYPE D3D11DeviceExt::GetCudaTextureObjectNVX(uint32_t srvDriverHandle, uint32_t samplerDriverHandle, uint32_t* pCudaTextureHandle) {
|
2479 | 2482 | ID3D11ShaderResourceView* srv = HandleToSrvNVX(srvDriverHandle);
|
2480 | 2483 |
|
@@ -2783,8 +2786,133 @@ namespace dxvk {
|
2783 | 2786 |
|
2784 | 2787 |
|
2785 | 2788 |
|
| 2789 | + |
| 2790 | + D3D11LowLatencyDevice::D3D11LowLatencyDevice( |
| 2791 | + D3D11DXGIDevice* pContainer, |
| 2792 | + D3D11Device* pDevice) |
| 2793 | + : m_container(pContainer), m_device(pDevice) { |
| 2794 | + |
| 2795 | + } |
2786 | 2796 |
|
2787 | 2797 |
|
| 2798 | + ULONG STDMETHODCALLTYPE D3D11LowLatencyDevice::AddRef() { |
| 2799 | + return m_container->AddRef(); |
| 2800 | + } |
| 2801 | + |
| 2802 | + |
| 2803 | + ULONG STDMETHODCALLTYPE D3D11LowLatencyDevice::Release() { |
| 2804 | + return m_container->Release(); |
| 2805 | + } |
| 2806 | + |
| 2807 | + |
| 2808 | + HRESULT STDMETHODCALLTYPE D3D11LowLatencyDevice::QueryInterface( |
| 2809 | + REFIID riid, |
| 2810 | + void** ppvObject) { |
| 2811 | + return m_container->QueryInterface(riid, ppvObject); |
| 2812 | + } |
| 2813 | + |
| 2814 | + BOOL STDMETHODCALLTYPE D3D11LowLatencyDevice::SupportsLowLatency() { |
| 2815 | + return m_device->GetDXVKDevice()->features().nvLowLatency2; |
| 2816 | + } |
| 2817 | + |
| 2818 | + HRESULT STDMETHODCALLTYPE D3D11LowLatencyDevice::LatencySleep() { |
| 2819 | + if (!m_device->GetDXVKDevice()->features().nvLowLatency2) { |
| 2820 | + return E_NOINTERFACE; |
| 2821 | + } |
| 2822 | + |
| 2823 | + D3D11SwapChain* pSwapChain = m_device->GetLowLatencySwapChain(); |
| 2824 | + if (pSwapChain && pSwapChain->LowLatencyEnabled()) { |
| 2825 | + VkResult res = pSwapChain->LatencySleep(); |
| 2826 | + if (res != VK_SUCCESS) { |
| 2827 | + return S_FALSE; |
| 2828 | + } |
| 2829 | + } |
| 2830 | + |
| 2831 | + return S_OK; |
| 2832 | + } |
| 2833 | + |
| 2834 | + HRESULT STDMETHODCALLTYPE D3D11LowLatencyDevice::SetLatencySleepMode(BOOL lowLatencyMode, BOOL lowLatencyBoost, uint32_t minimumIntervalUs) { |
| 2835 | + if (!m_device->GetDXVKDevice()->features().nvLowLatency2) { |
| 2836 | + return E_NOINTERFACE; |
| 2837 | + } |
| 2838 | + |
| 2839 | + D3D11SwapChain* pSwapChain = m_device->GetLowLatencySwapChain(); |
| 2840 | + if (pSwapChain) { |
| 2841 | + VkResult res = pSwapChain->SetLatencySleepMode(lowLatencyMode, lowLatencyBoost, minimumIntervalUs); |
| 2842 | + if (res != VK_SUCCESS) { |
| 2843 | + return S_FALSE; |
| 2844 | + } |
| 2845 | + } |
| 2846 | + |
| 2847 | + return S_OK; |
| 2848 | + } |
| 2849 | + |
| 2850 | + HRESULT STDMETHODCALLTYPE D3D11LowLatencyDevice::SetLatencyMarker(uint64_t frameID, uint32_t markerType) { |
| 2851 | + if (!m_device->GetDXVKDevice()->features().nvLowLatency2) { |
| 2852 | + return E_NOINTERFACE; |
| 2853 | + } |
| 2854 | + |
| 2855 | + D3D11SwapChain* pSwapChain = m_device->GetLowLatencySwapChain(); |
| 2856 | + VkLatencyMarkerNV marker = static_cast<VkLatencyMarkerNV>(markerType); |
| 2857 | + uint64_t internalFrameId = frameID + DXGI_MAX_SWAP_CHAIN_BUFFERS; |
| 2858 | + |
| 2859 | + m_device->GetDXVKDevice()->setLatencyMarker(marker, internalFrameId); |
| 2860 | + |
| 2861 | + if (pSwapChain && pSwapChain->LowLatencyEnabled()) { |
| 2862 | + pSwapChain->SetLatencyMarker(marker, internalFrameId); |
| 2863 | + } |
| 2864 | + |
| 2865 | + return S_OK; |
| 2866 | + } |
| 2867 | + |
| 2868 | + HRESULT STDMETHODCALLTYPE D3D11LowLatencyDevice::GetLatencyInfo(D3D11_LATENCY_RESULTS* latencyResults) |
| 2869 | + { |
| 2870 | + if (!m_device->GetDXVKDevice()->features().nvLowLatency2) { |
| 2871 | + return E_NOINTERFACE; |
| 2872 | + } |
| 2873 | + |
| 2874 | + constexpr uint32_t frameReportSize = 64; |
| 2875 | + D3D11SwapChain* pSwapChain = m_device->GetLowLatencySwapChain(); |
| 2876 | + |
| 2877 | + if (pSwapChain && pSwapChain->LowLatencyEnabled()) { |
| 2878 | + std::vector<VkLatencyTimingsFrameReportNV> frameReports; |
| 2879 | + pSwapChain->GetLatencyTimings(frameReports); |
| 2880 | + |
| 2881 | + if (frameReports.size() >= frameReportSize) { |
| 2882 | + for (uint32_t i = 0; i < frameReportSize; i++) { |
| 2883 | + VkLatencyTimingsFrameReportNV& frameReport = frameReports[i]; |
| 2884 | + latencyResults->frame_reports[i].frameID = frameReport.presentID - DXGI_MAX_SWAP_CHAIN_BUFFERS; |
| 2885 | + latencyResults->frame_reports[i].inputSampleTime = frameReport.inputSampleTimeUs; |
| 2886 | + latencyResults->frame_reports[i].simStartTime = frameReport.simStartTimeUs; |
| 2887 | + latencyResults->frame_reports[i].simEndTime = frameReport.simEndTimeUs; |
| 2888 | + latencyResults->frame_reports[i].renderSubmitStartTime = frameReport.renderSubmitStartTimeUs; |
| 2889 | + latencyResults->frame_reports[i].renderSubmitEndTime = frameReport.renderSubmitEndTimeUs; |
| 2890 | + latencyResults->frame_reports[i].presentStartTime = frameReport.presentStartTimeUs; |
| 2891 | + latencyResults->frame_reports[i].presentEndTime = frameReport.presentEndTimeUs; |
| 2892 | + latencyResults->frame_reports[i].driverStartTime = frameReport.driverStartTimeUs; |
| 2893 | + latencyResults->frame_reports[i].driverEndTime = frameReport.driverEndTimeUs; |
| 2894 | + latencyResults->frame_reports[i].osRenderQueueStartTime = frameReport.osRenderQueueStartTimeUs; |
| 2895 | + latencyResults->frame_reports[i].osRenderQueueEndTime = frameReport.osRenderQueueEndTimeUs; |
| 2896 | + latencyResults->frame_reports[i].gpuRenderStartTime = frameReport.gpuRenderStartTimeUs; |
| 2897 | + latencyResults->frame_reports[i].gpuRenderEndTime = frameReport.gpuRenderEndTimeUs; |
| 2898 | + latencyResults->frame_reports[i].gpuActiveRenderTimeUs = |
| 2899 | + frameReport.gpuRenderEndTimeUs - frameReport.gpuRenderStartTimeUs; |
| 2900 | + latencyResults->frame_reports[i].gpuFrameTimeUs = 0; |
| 2901 | + |
| 2902 | + if (i) { |
| 2903 | + latencyResults->frame_reports[i].gpuFrameTimeUs = |
| 2904 | + frameReports[i].gpuRenderEndTimeUs - frameReports[i - 1].gpuRenderEndTimeUs; |
| 2905 | + } |
| 2906 | + } |
| 2907 | + } |
| 2908 | + } |
| 2909 | + |
| 2910 | + return S_OK; |
| 2911 | + } |
| 2912 | + |
| 2913 | + |
| 2914 | + |
| 2915 | + |
2788 | 2916 | D3D11VideoDevice::D3D11VideoDevice(
|
2789 | 2917 | D3D11DXGIDevice* pContainer,
|
2790 | 2918 | D3D11Device* pDevice)
|
@@ -3021,7 +3149,11 @@ namespace dxvk {
|
3021 | 3149 |
|
3022 | 3150 | Com<D3D11SwapChain> presenter = new D3D11SwapChain(
|
3023 | 3151 | m_container, m_device, pSurfaceFactory, pDesc);
|
3024 |
| - |
| 3152 | + |
| 3153 | + if (m_device->GetDXVKDevice()->features().nvLowLatency2) { |
| 3154 | + m_device->AddSwapchain(presenter.ref()); |
| 3155 | + } |
| 3156 | + |
3025 | 3157 | *ppSwapChain = presenter.ref();
|
3026 | 3158 | return S_OK;
|
3027 | 3159 | } catch (const DxvkError& e) {
|
@@ -3078,17 +3210,18 @@ namespace dxvk {
|
3078 | 3210 | Rc<DxvkDevice> pDxvkDevice,
|
3079 | 3211 | D3D_FEATURE_LEVEL FeatureLevel,
|
3080 | 3212 | UINT FeatureFlags)
|
3081 |
| - : m_dxgiAdapter (pAdapter), |
3082 |
| - m_dxvkInstance (pDxvkInstance), |
3083 |
| - m_dxvkAdapter (pDxvkAdapter), |
3084 |
| - m_dxvkDevice (pDxvkDevice), |
3085 |
| - m_d3d11Device (this, FeatureLevel, FeatureFlags), |
3086 |
| - m_d3d11DeviceExt(this, &m_d3d11Device), |
3087 |
| - m_d3d11Interop (this, &m_d3d11Device), |
3088 |
| - m_d3d11Video (this, &m_d3d11Device), |
3089 |
| - m_d3d11on12 (this, &m_d3d11Device, pD3D12Device, pD3D12Queue), |
3090 |
| - m_metaDevice (this), |
3091 |
| - m_dxvkFactory (this, &m_d3d11Device) { |
| 3213 | + : m_dxgiAdapter (pAdapter), |
| 3214 | + m_dxvkInstance (pDxvkInstance), |
| 3215 | + m_dxvkAdapter (pDxvkAdapter), |
| 3216 | + m_dxvkDevice (pDxvkDevice), |
| 3217 | + m_d3d11Device (this, FeatureLevel, FeatureFlags), |
| 3218 | + m_d3d11DeviceExt (this, &m_d3d11Device), |
| 3219 | + m_d3d11Interop (this, &m_d3d11Device), |
| 3220 | + m_d3dLowLatencyDevice (this, &m_d3d11Device), |
| 3221 | + m_d3d11Video (this, &m_d3d11Device), |
| 3222 | + m_d3d11on12 (this, &m_d3d11Device, pD3D12Device, pD3D12Queue), |
| 3223 | + m_metaDevice (this), |
| 3224 | + m_dxvkFactory (this, &m_d3d11Device) { |
3092 | 3225 |
|
3093 | 3226 | }
|
3094 | 3227 |
|
@@ -3142,7 +3275,12 @@ namespace dxvk {
|
3142 | 3275 | *ppvObject = ref(&m_d3d11DeviceExt);
|
3143 | 3276 | return S_OK;
|
3144 | 3277 | }
|
3145 |
| - |
| 3278 | + |
| 3279 | + if (riid == __uuidof(ID3DLowLatencyDevice)) { |
| 3280 | + *ppvObject = ref(&m_d3dLowLatencyDevice); |
| 3281 | + return S_OK; |
| 3282 | + } |
| 3283 | + |
3146 | 3284 | if (riid == __uuidof(IDXGIDXVKDevice)) {
|
3147 | 3285 | *ppvObject = ref(&m_metaDevice);
|
3148 | 3286 | return S_OK;
|
|
0 commit comments