1
0
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:
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_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;
}

View File

@ -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);

View File

@ -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) {

View File

@ -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,