mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 20:52:10 +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_d3d11DeviceExt(this, &m_d3d11Device),
|
||||
m_d3d11Interop (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);
|
||||
m_wineFactory (this, &m_d3d11Device) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -2712,7 +2710,7 @@ namespace dxvk {
|
||||
if (MaxLatency == 0)
|
||||
MaxLatency = DefaultFrameLatency;
|
||||
|
||||
if (MaxLatency > m_frameEvents.size())
|
||||
if (MaxLatency > DXGI_MAX_SWAP_CHAIN_BUFFERS)
|
||||
return DXGI_ERROR_INVALID_CALL;
|
||||
|
||||
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() {
|
||||
return m_dxvkDevice;
|
||||
}
|
||||
|
@ -634,9 +634,6 @@ namespace dxvk {
|
||||
|
||||
void STDMETHODCALLTYPE Trim() final;
|
||||
|
||||
Rc<sync::Signal> STDMETHODCALLTYPE GetFrameSyncEvent(
|
||||
UINT BufferCount);
|
||||
|
||||
Rc<DxvkDevice> STDMETHODCALLTYPE GetDXVKDevice();
|
||||
|
||||
private:
|
||||
@ -653,11 +650,7 @@ namespace dxvk {
|
||||
|
||||
WineDXGISwapChainFactory m_wineFactory;
|
||||
|
||||
uint32_t m_frameLatencyCap = 0;
|
||||
uint32_t m_frameLatency = DefaultFrameLatency;
|
||||
uint32_t m_frameId = 0;
|
||||
|
||||
std::array<Rc<sync::Signal>, 16> m_frameEvents;
|
||||
uint32_t m_frameLatency = DefaultFrameLatency;
|
||||
|
||||
Rc<DxvkDevice> CreateDevice(D3D_FEATURE_LEVEL FeatureLevel);
|
||||
|
||||
|
@ -24,7 +24,10 @@ namespace dxvk {
|
||||
m_window (hWnd),
|
||||
m_desc (*pDesc),
|
||||
m_device (pDevice->GetDXVKDevice()),
|
||||
m_context (m_device->createContext()) {
|
||||
m_context (m_device->createContext()),
|
||||
m_frameLatencyCap(pDevice->GetOptions()->maxFrameLatency) {
|
||||
CreateFrameLatencySignals();
|
||||
|
||||
if (!pDevice->GetOptions()->deferSurfaceCreation)
|
||||
CreatePresenter();
|
||||
|
||||
@ -206,7 +209,8 @@ namespace dxvk {
|
||||
immediateContext->Flush();
|
||||
|
||||
// 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();
|
||||
|
||||
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() {
|
||||
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(
|
||||
DXGI_FORMAT Format,
|
||||
VkSurfaceFormatKHR* pDstFormats) {
|
||||
|
@ -21,7 +21,7 @@ namespace dxvk {
|
||||
};
|
||||
|
||||
class D3D11SwapChain : public ComObject<IDXGIVkSwapChain> {
|
||||
|
||||
constexpr static uint32_t DefaultFrameLatency = 1;
|
||||
public:
|
||||
|
||||
D3D11SwapChain(
|
||||
@ -68,7 +68,7 @@ namespace dxvk {
|
||||
UINT SyncInterval,
|
||||
UINT PresentFlags,
|
||||
const DXGI_PRESENT_PARAMETERS* pPresentParameters);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
enum BindingIds : uint32_t {
|
||||
@ -117,6 +117,10 @@ namespace dxvk {
|
||||
|
||||
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_vsync = true;
|
||||
|
||||
@ -131,6 +135,8 @@ namespace dxvk {
|
||||
void RecreateSwapChain(
|
||||
BOOL Vsync);
|
||||
|
||||
void CreateFrameLatencySignals();
|
||||
|
||||
void CreatePresenter();
|
||||
|
||||
void CreateRenderTargetViews();
|
||||
@ -150,6 +156,8 @@ namespace dxvk {
|
||||
void InitSamplers();
|
||||
|
||||
void InitShaders();
|
||||
|
||||
uint32_t GetActualFrameLatency();
|
||||
|
||||
uint32_t PickFormats(
|
||||
DXGI_FORMAT Format,
|
||||
|
Loading…
x
Reference in New Issue
Block a user