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:
parent
a0651392c4
commit
69bad7bf8c
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user