1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-19 05:52:11 +01:00

[d3d11] Move frame latency handling into D3D11SwapChain

This commit is contained in:
Philip Rebohle 2019-11-25 17:45:28 +01:00
parent a0651392c4
commit 69bad7bf8c
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 38 additions and 33 deletions

View File

@ -2474,10 +2474,8 @@ namespace dxvk {
m_d3d11Device (this, FeatureLevel, FeatureFlags), m_d3d11Device (this, FeatureLevel, FeatureFlags),
m_d3d11DeviceExt(this, &m_d3d11Device), m_d3d11DeviceExt(this, &m_d3d11Device),
m_d3d11Interop (this, &m_d3d11Device), m_d3d11Interop (this, &m_d3d11Device),
m_wineFactory (this, &m_d3d11Device), m_wineFactory (this, &m_d3d11Device) {
m_frameLatencyCap(m_d3d11Device.GetOptions()->maxFrameLatency) {
for (uint32_t i = 0; i < m_frameEvents.size(); i++)
m_frameEvents[i] = new sync::Signal(true);
} }
@ -2712,7 +2710,7 @@ namespace dxvk {
if (MaxLatency == 0) if (MaxLatency == 0)
MaxLatency = DefaultFrameLatency; MaxLatency = DefaultFrameLatency;
if (MaxLatency > m_frameEvents.size()) if (MaxLatency > DXGI_MAX_SWAP_CHAIN_BUFFERS)
return DXGI_ERROR_INVALID_CALL; return DXGI_ERROR_INVALID_CALL;
m_frameLatency = MaxLatency; m_frameLatency = MaxLatency;
@ -2790,22 +2788,6 @@ namespace dxvk {
} }
Rc<sync::Signal> STDMETHODCALLTYPE D3D11DXGIDevice::GetFrameSyncEvent(UINT BufferCount) {
uint32_t frameLatency = m_frameLatency;
if (BufferCount != 0
&& BufferCount <= frameLatency)
frameLatency = BufferCount;
if (m_frameLatencyCap != 0
&& m_frameLatencyCap <= frameLatency)
frameLatency = m_frameLatencyCap;
uint32_t frameId = m_frameId++ % frameLatency;
return m_frameEvents[frameId];
}
Rc<DxvkDevice> STDMETHODCALLTYPE D3D11DXGIDevice::GetDXVKDevice() { Rc<DxvkDevice> STDMETHODCALLTYPE D3D11DXGIDevice::GetDXVKDevice() {
return m_dxvkDevice; return m_dxvkDevice;
} }

View File

@ -634,9 +634,6 @@ namespace dxvk {
void STDMETHODCALLTYPE Trim() final; void STDMETHODCALLTYPE Trim() final;
Rc<sync::Signal> STDMETHODCALLTYPE GetFrameSyncEvent(
UINT BufferCount);
Rc<DxvkDevice> STDMETHODCALLTYPE GetDXVKDevice(); Rc<DxvkDevice> STDMETHODCALLTYPE GetDXVKDevice();
private: private:
@ -653,11 +650,7 @@ namespace dxvk {
WineDXGISwapChainFactory m_wineFactory; WineDXGISwapChainFactory m_wineFactory;
uint32_t m_frameLatencyCap = 0; uint32_t m_frameLatency = DefaultFrameLatency;
uint32_t m_frameLatency = DefaultFrameLatency;
uint32_t m_frameId = 0;
std::array<Rc<sync::Signal>, 16> m_frameEvents;
Rc<DxvkDevice> CreateDevice(D3D_FEATURE_LEVEL FeatureLevel); Rc<DxvkDevice> CreateDevice(D3D_FEATURE_LEVEL FeatureLevel);

View File

@ -24,7 +24,10 @@ namespace dxvk {
m_window (hWnd), m_window (hWnd),
m_desc (*pDesc), m_desc (*pDesc),
m_device (pDevice->GetDXVKDevice()), m_device (pDevice->GetDXVKDevice()),
m_context (m_device->createContext()) { m_context (m_device->createContext()),
m_frameLatencyCap(pDevice->GetOptions()->maxFrameLatency) {
CreateFrameLatencySignals();
if (!pDevice->GetOptions()->deferSurfaceCreation) if (!pDevice->GetOptions()->deferSurfaceCreation)
CreatePresenter(); CreatePresenter();
@ -206,7 +209,8 @@ namespace dxvk {
immediateContext->Flush(); immediateContext->Flush();
// Wait for the sync event so that we respect the maximum frame latency // Wait for the sync event so that we respect the maximum frame latency
auto syncEvent = m_dxgiDevice->GetFrameSyncEvent(m_desc.BufferCount); uint32_t frameId = m_frameId++ % GetActualFrameLatency();
auto syncEvent = m_frameLatencySignals[frameId];
syncEvent->wait(); syncEvent->wait();
if (m_hud != nullptr) if (m_hud != nullptr)
@ -366,6 +370,12 @@ namespace dxvk {
} }
void D3D11SwapChain::CreateFrameLatencySignals() {
for (uint32_t i = 0; i < m_frameLatencySignals.size(); i++)
m_frameLatencySignals[i] = new sync::Signal(true);
}
void D3D11SwapChain::CreatePresenter() { void D3D11SwapChain::CreatePresenter() {
DxvkDeviceQueue graphicsQueue = m_device->queues().graphics; DxvkDeviceQueue graphicsQueue = m_device->queues().graphics;
@ -709,6 +719,18 @@ namespace dxvk {
} }
uint32_t D3D11SwapChain::GetActualFrameLatency() {
uint32_t maxFrameLatency = DefaultFrameLatency;
m_dxgiDevice->GetMaximumFrameLatency(&maxFrameLatency);
if (m_frameLatencyCap)
maxFrameLatency = std::min(maxFrameLatency, m_frameLatencyCap);
maxFrameLatency = std::min(maxFrameLatency, m_desc.BufferCount + 1);
return maxFrameLatency;
}
uint32_t D3D11SwapChain::PickFormats( uint32_t D3D11SwapChain::PickFormats(
DXGI_FORMAT Format, DXGI_FORMAT Format,
VkSurfaceFormatKHR* pDstFormats) { VkSurfaceFormatKHR* pDstFormats) {

View File

@ -21,7 +21,7 @@ namespace dxvk {
}; };
class D3D11SwapChain : public ComObject<IDXGIVkSwapChain> { class D3D11SwapChain : public ComObject<IDXGIVkSwapChain> {
constexpr static uint32_t DefaultFrameLatency = 1;
public: public:
D3D11SwapChain( D3D11SwapChain(
@ -68,7 +68,7 @@ namespace dxvk {
UINT SyncInterval, UINT SyncInterval,
UINT PresentFlags, UINT PresentFlags,
const DXGI_PRESENT_PARAMETERS* pPresentParameters); const DXGI_PRESENT_PARAMETERS* pPresentParameters);
private: private:
enum BindingIds : uint32_t { enum BindingIds : uint32_t {
@ -117,6 +117,10 @@ namespace dxvk {
std::vector<Rc<DxvkImageView>> m_imageViews; std::vector<Rc<DxvkImageView>> m_imageViews;
uint32_t m_frameId = 0;
std::array<Rc<sync::Signal>, DXGI_MAX_SWAP_CHAIN_BUFFERS> m_frameLatencySignals;
uint32_t m_frameLatencyCap = 0;
bool m_dirty = true; bool m_dirty = true;
bool m_vsync = true; bool m_vsync = true;
@ -131,6 +135,8 @@ namespace dxvk {
void RecreateSwapChain( void RecreateSwapChain(
BOOL Vsync); BOOL Vsync);
void CreateFrameLatencySignals();
void CreatePresenter(); void CreatePresenter();
void CreateRenderTargetViews(); void CreateRenderTargetViews();
@ -150,6 +156,8 @@ namespace dxvk {
void InitSamplers(); void InitSamplers();
void InitShaders(); void InitShaders();
uint32_t GetActualFrameLatency();
uint32_t PickFormats( uint32_t PickFormats(
DXGI_FORMAT Format, DXGI_FORMAT Format,