2019-12-16 03:28:01 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "d3d9_device_child.h"
|
|
|
|
#include "d3d9_device.h"
|
|
|
|
#include "d3d9_format.h"
|
|
|
|
|
|
|
|
#include "../dxvk/hud/dxvk_hud.h"
|
|
|
|
|
2021-02-27 15:00:39 +01:00
|
|
|
#include "../dxvk/dxvk_swapchain_blitter.h"
|
|
|
|
|
2019-12-16 03:28:01 +00:00
|
|
|
#include "../util/sync/sync_signal.h"
|
|
|
|
|
2022-08-14 17:36:58 +00:00
|
|
|
#include "../wsi/wsi_window.h"
|
|
|
|
#include "../wsi/wsi_monitor.h"
|
|
|
|
|
2019-12-16 03:28:01 +00:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
class D3D9Surface;
|
2023-05-15 17:45:14 +00:00
|
|
|
class D3D9SwapChainEx;
|
|
|
|
|
|
|
|
class D3D9VkExtSwapchain final : public ID3D9VkExtSwapchain {
|
|
|
|
public:
|
|
|
|
D3D9VkExtSwapchain(D3D9SwapChainEx *pSwapChain);
|
|
|
|
|
|
|
|
ULONG STDMETHODCALLTYPE AddRef();
|
|
|
|
|
|
|
|
ULONG STDMETHODCALLTYPE Release();
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE QueryInterface(
|
|
|
|
REFIID riid,
|
|
|
|
void** ppvObject);
|
|
|
|
|
|
|
|
BOOL STDMETHODCALLTYPE CheckColorSpaceSupport(
|
|
|
|
VkColorSpaceKHR ColorSpace);
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE SetColorSpace(
|
|
|
|
VkColorSpaceKHR ColorSpace);
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE SetHDRMetaData(
|
|
|
|
const VkHdrMetadataEXT *pHDRMetadata);
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE GetCurrentOutputDesc(
|
|
|
|
D3D9VkExtOutputMetadata *pOutputDesc);
|
|
|
|
|
|
|
|
void STDMETHODCALLTYPE UnlockAdditionalFormats();
|
|
|
|
|
|
|
|
private:
|
|
|
|
D3D9SwapChainEx *m_swapchain;
|
|
|
|
};
|
2019-12-16 03:28:01 +00:00
|
|
|
|
|
|
|
using D3D9SwapChainExBase = D3D9DeviceChild<IDirect3DSwapChain9Ex>;
|
|
|
|
class D3D9SwapChainEx final : public D3D9SwapChainExBase {
|
|
|
|
static constexpr uint32_t NumControlPoints = 256;
|
2023-05-15 17:45:14 +00:00
|
|
|
|
|
|
|
friend class D3D9VkExtSwapchain;
|
2019-12-16 03:28:01 +00:00
|
|
|
public:
|
|
|
|
|
|
|
|
D3D9SwapChainEx(
|
|
|
|
D3D9DeviceEx* pDevice,
|
|
|
|
D3DPRESENT_PARAMETERS* pPresentParams,
|
|
|
|
const D3DDISPLAYMODEEX* pFullscreenDisplayMode);
|
|
|
|
|
|
|
|
~D3D9SwapChainEx();
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE Present(
|
|
|
|
const RECT* pSourceRect,
|
|
|
|
const RECT* pDestRect,
|
|
|
|
HWND hDestWindowOverride,
|
|
|
|
const RGNDATA* pDirtyRegion,
|
|
|
|
DWORD dwFlags);
|
|
|
|
|
2023-04-13 04:20:01 +02:00
|
|
|
#ifdef _WIN32
|
2023-05-03 19:32:32 +02:00
|
|
|
HRESULT PresentImageGDI(HWND Window);
|
2023-04-13 04:20:01 +02:00
|
|
|
#endif
|
|
|
|
|
2019-12-16 03:28:01 +00:00
|
|
|
HRESULT STDMETHODCALLTYPE GetFrontBufferData(IDirect3DSurface9* pDestSurface);
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE GetBackBuffer(
|
|
|
|
UINT iBackBuffer,
|
|
|
|
D3DBACKBUFFER_TYPE Type,
|
|
|
|
IDirect3DSurface9** ppBackBuffer);
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE GetRasterStatus(D3DRASTER_STATUS* pRasterStatus);
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE GetDisplayMode(D3DDISPLAYMODE* pMode);
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE GetPresentParameters(D3DPRESENT_PARAMETERS* pPresentationParameters);
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE GetLastPresentCount(UINT* pLastPresentCount);
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE GetPresentStats(D3DPRESENTSTATS* pPresentationStatistics);
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE GetDisplayModeEx(D3DDISPLAYMODEEX* pMode, D3DDISPLAYROTATION* pRotation);
|
|
|
|
|
2021-07-24 23:47:17 +02:00
|
|
|
HRESULT Reset(
|
2019-12-16 03:28:01 +00:00
|
|
|
D3DPRESENT_PARAMETERS* pPresentParams,
|
|
|
|
D3DDISPLAYMODEEX* pFullscreenDisplayMode);
|
|
|
|
|
|
|
|
HRESULT WaitForVBlank();
|
|
|
|
|
|
|
|
void SetGammaRamp(
|
|
|
|
DWORD Flags,
|
|
|
|
const D3DGAMMARAMP* pRamp);
|
|
|
|
|
|
|
|
void GetGammaRamp(D3DGAMMARAMP* pRamp);
|
|
|
|
|
|
|
|
void Invalidate(HWND hWindow);
|
|
|
|
|
|
|
|
HRESULT SetDialogBoxMode(bool bEnableDialogs);
|
|
|
|
|
|
|
|
D3D9Surface* GetBackBuffer(UINT iBackBuffer);
|
|
|
|
|
2020-02-28 01:43:07 +00:00
|
|
|
const D3DPRESENT_PARAMETERS* GetPresentParams() const { return &m_presentParams; }
|
|
|
|
|
2021-06-01 17:07:10 +01:00
|
|
|
void SyncFrameLatency();
|
|
|
|
|
2023-05-15 17:45:14 +00:00
|
|
|
bool HasFormatsUnlocked() const { return m_unlockAdditionalFormats; }
|
|
|
|
|
2023-06-10 01:18:05 +02:00
|
|
|
void DestroyBackBuffers();
|
|
|
|
|
2019-12-16 03:28:01 +00:00
|
|
|
private:
|
|
|
|
|
|
|
|
enum BindingIds : uint32_t {
|
|
|
|
Image = 0,
|
|
|
|
Gamma = 1,
|
|
|
|
};
|
|
|
|
|
2021-02-27 15:00:39 +01:00
|
|
|
D3DPRESENT_PARAMETERS m_presentParams;
|
|
|
|
D3DGAMMARAMP m_ramp;
|
2019-12-16 03:28:01 +00:00
|
|
|
|
2021-02-27 15:00:39 +01:00
|
|
|
Rc<DxvkDevice> m_device;
|
|
|
|
Rc<DxvkContext> m_context;
|
|
|
|
Rc<DxvkSwapchainBlitter> m_blitter;
|
2019-12-16 03:28:01 +00:00
|
|
|
|
2023-05-29 13:18:13 +02:00
|
|
|
Rc<Presenter> m_presenter;
|
2019-12-16 03:28:01 +00:00
|
|
|
|
2021-02-27 15:00:39 +01:00
|
|
|
Rc<hud::Hud> m_hud;
|
2019-12-16 03:28:01 +00:00
|
|
|
|
2020-04-26 12:58:19 +01:00
|
|
|
std::vector<Com<D3D9Surface, false>> m_backBuffers;
|
2019-12-16 03:28:01 +00:00
|
|
|
|
2021-02-27 15:00:39 +01:00
|
|
|
RECT m_srcRect;
|
|
|
|
RECT m_dstRect;
|
2023-05-03 19:32:32 +02:00
|
|
|
VkExtent2D m_swapchainExtent = { 0u, 0u };
|
2023-04-13 04:20:01 +02:00
|
|
|
bool m_partialCopy = false;
|
2019-12-16 03:28:01 +00:00
|
|
|
|
2021-02-27 15:00:39 +01:00
|
|
|
DxvkSubmitStatus m_presentStatus;
|
2019-12-16 03:28:01 +00:00
|
|
|
|
|
|
|
std::vector<Rc<DxvkImageView>> m_imageViews;
|
|
|
|
|
|
|
|
|
2021-02-27 15:00:39 +01:00
|
|
|
uint64_t m_frameId = D3D9DeviceEx::MaxFrameLatency;
|
|
|
|
uint32_t m_frameLatencyCap = 0;
|
|
|
|
Rc<sync::Fence> m_frameLatencySignal;
|
2019-12-16 03:28:01 +00:00
|
|
|
|
2021-02-27 15:00:39 +01:00
|
|
|
bool m_dirty = true;
|
2023-05-29 14:51:40 +02:00
|
|
|
bool m_dialog = false;
|
2021-02-27 15:00:39 +01:00
|
|
|
bool m_lastDialog = false;
|
2019-12-16 03:28:01 +00:00
|
|
|
|
2021-02-27 15:00:39 +01:00
|
|
|
HWND m_window = nullptr;
|
|
|
|
HMONITOR m_monitor = nullptr;
|
2019-12-16 03:28:01 +00:00
|
|
|
|
2022-08-14 17:36:58 +00:00
|
|
|
wsi::DxvkWindowState m_windowState;
|
2019-12-16 03:28:01 +00:00
|
|
|
|
2021-06-09 08:05:55 +02:00
|
|
|
double m_displayRefreshRate = 0.0;
|
|
|
|
|
2023-05-07 13:28:42 +02:00
|
|
|
bool m_warnedAboutGDIFallback = false;
|
2023-04-13 04:20:01 +02:00
|
|
|
|
2023-05-15 17:45:14 +00:00
|
|
|
VkColorSpaceKHR m_colorspace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
|
|
|
|
|
|
|
std::optional<VkHdrMetadataEXT> m_hdrMetadata;
|
|
|
|
bool m_dirtyHdrMetadata = true;
|
|
|
|
bool m_unlockAdditionalFormats = false;
|
|
|
|
|
|
|
|
D3D9VkExtSwapchain m_swapchainExt;
|
|
|
|
|
2019-12-16 03:28:01 +00:00
|
|
|
void PresentImage(UINT PresentInterval);
|
|
|
|
|
2023-06-15 17:24:44 +02:00
|
|
|
void SubmitPresent(const PresenterSync& Sync, uint32_t Repeat);
|
2019-12-16 03:28:01 +00:00
|
|
|
|
|
|
|
void SynchronizePresent();
|
|
|
|
|
2023-05-29 14:51:40 +02:00
|
|
|
void RecreateSwapChain();
|
2019-12-16 03:28:01 +00:00
|
|
|
|
|
|
|
void CreatePresenter();
|
|
|
|
|
2022-10-28 15:52:43 +02:00
|
|
|
VkResult CreateSurface(VkSurfaceKHR* pSurface);
|
|
|
|
|
2019-12-16 03:28:01 +00:00
|
|
|
void CreateRenderTargetViews();
|
|
|
|
|
2023-05-03 12:34:37 +01:00
|
|
|
HRESULT CreateBackBuffers(
|
2020-01-15 01:03:02 +01:00
|
|
|
uint32_t NumBackBuffers);
|
2019-12-16 03:28:01 +00:00
|
|
|
|
2021-02-27 15:00:39 +01:00
|
|
|
void CreateBlitter();
|
2019-12-16 03:28:01 +00:00
|
|
|
|
|
|
|
void CreateHud();
|
|
|
|
|
|
|
|
void InitRamp();
|
|
|
|
|
|
|
|
uint32_t GetActualFrameLatency();
|
|
|
|
|
|
|
|
uint32_t PickFormats(
|
|
|
|
D3D9Format Format,
|
|
|
|
VkSurfaceFormatKHR* pDstFormats);
|
|
|
|
|
|
|
|
uint32_t PickImageCount(
|
|
|
|
UINT Preferred);
|
|
|
|
|
|
|
|
void NormalizePresentParameters(D3DPRESENT_PARAMETERS* pPresentParams);
|
|
|
|
|
2021-06-09 08:05:55 +02:00
|
|
|
void NotifyDisplayRefreshRate(
|
|
|
|
double RefreshRate);
|
|
|
|
|
2019-12-16 03:28:01 +00:00
|
|
|
HRESULT EnterFullscreenMode(
|
|
|
|
D3DPRESENT_PARAMETERS* pPresentParams,
|
|
|
|
const D3DDISPLAYMODEEX* pFullscreenDisplayMode);
|
|
|
|
|
|
|
|
HRESULT LeaveFullscreenMode();
|
|
|
|
|
|
|
|
HRESULT ChangeDisplayMode(
|
|
|
|
D3DPRESENT_PARAMETERS* pPresentParams,
|
|
|
|
const D3DDISPLAYMODEEX* pFullscreenDisplayMode);
|
|
|
|
|
|
|
|
HRESULT RestoreDisplayMode(HMONITOR hMonitor);
|
|
|
|
|
|
|
|
bool UpdatePresentRegion(const RECT* pSourceRect, const RECT* pDestRect);
|
|
|
|
|
|
|
|
VkExtent2D GetPresentExtent();
|
|
|
|
|
|
|
|
VkFullScreenExclusiveEXT PickFullscreenMode();
|
|
|
|
|
2020-01-28 13:15:02 +01:00
|
|
|
std::string GetApiName();
|
|
|
|
|
2023-05-03 19:32:32 +02:00
|
|
|
const Com<D3D9Surface, false>& GetFrontBuffer() const {
|
|
|
|
return m_backBuffers.back();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HasFrontBuffer() const {
|
|
|
|
if (m_presentParams.SwapEffect == D3DSWAPEFFECT_COPY)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (m_presentParams.SwapEffect == D3DSWAPEFFECT_COPY_VSYNC)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Tests show that SWAPEEFFECT_DISCARD + 1 backbuffer in windowed mode behaves identically to SWAPEFFECT_COPY
|
|
|
|
// For SWAPEFFECT_COPY we don't swap buffers but do another blit to the front buffer instead.
|
|
|
|
if (m_presentParams.SwapEffect == D3DSWAPEFFECT_DISCARD && m_presentParams.BackBufferCount == 1 && m_presentParams.Windowed)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2019-12-16 03:28:01 +00:00
|
|
|
};
|
|
|
|
|
2023-05-03 19:32:32 +02:00
|
|
|
}
|