mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 01:24:11 +01:00
[dxgi] Use new presenter for D3D11
This commit is contained in:
parent
967b276acb
commit
b53f6661f8
@ -35,18 +35,6 @@ namespace dxvk {
|
|||||||
DXGI_VK_GAMMA_CP ControlPoints[DXGI_VK_GAMMA_CP_COUNT];
|
DXGI_VK_GAMMA_CP ControlPoints[DXGI_VK_GAMMA_CP_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Maps color value to normalized integer
|
|
||||||
*
|
|
||||||
* \param [in] x Input value, as floating point
|
|
||||||
* \returns Corresponding normalized integer
|
|
||||||
*/
|
|
||||||
inline uint16_t MapGammaControlPoint(float x) {
|
|
||||||
if (x < 0.0f) x = 0.0f;
|
|
||||||
if (x > 1.0f) x = 1.0f;
|
|
||||||
return uint16_t(65535.0f * x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Computes gamma control point location
|
* \brief Computes gamma control point location
|
||||||
*
|
*
|
||||||
|
@ -54,11 +54,8 @@ namespace dxvk {
|
|||||||
if (!m_descFs.Windowed && FAILED(EnterFullscreenMode(nullptr)))
|
if (!m_descFs.Windowed && FAILED(EnterFullscreenMode(nullptr)))
|
||||||
throw DxvkError("DXGI: DxgiSwapChain: Failed to set initial fullscreen state");
|
throw DxvkError("DXGI: DxgiSwapChain: Failed to set initial fullscreen state");
|
||||||
|
|
||||||
if (FAILED(CreatePresenter()) || FAILED(CreateBackBuffer()))
|
if (FAILED(m_presentDevice->CreateSwapChainForHwnd(m_window, &m_desc, &m_presenter)))
|
||||||
throw DxvkError("DXGI: DxgiSwapChain: Failed to create presenter or back buffer");
|
throw DxvkError("DXGI: DxgiSwapChain: Failed to create presenter");
|
||||||
|
|
||||||
if (FAILED(SetDefaultGammaControl()))
|
|
||||||
throw DxvkError("DXGI: DxgiSwapChain: Failed to set up gamma ramp");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -99,18 +96,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DxgiSwapChain::GetBuffer(UINT Buffer, REFIID riid, void** ppSurface) {
|
HRESULT STDMETHODCALLTYPE DxgiSwapChain::GetBuffer(UINT Buffer, REFIID riid, void** ppSurface) {
|
||||||
InitReturnPtr(ppSurface);
|
return m_presenter->GetImage(Buffer, riid, ppSurface);
|
||||||
|
|
||||||
if (!IsWindow(m_window))
|
|
||||||
return DXGI_ERROR_INVALID_CALL;
|
|
||||||
|
|
||||||
if (Buffer > 0) {
|
|
||||||
Logger::err("DxgiSwapChain::GetBuffer: Buffer > 0 not supported");
|
|
||||||
return DXGI_ERROR_INVALID_CALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(m_lockBuffer);
|
|
||||||
return m_backBuffer->QueryInterface(riid, ppSurface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -263,34 +249,29 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DxgiSwapChain::Present(UINT SyncInterval, UINT Flags) {
|
HRESULT STDMETHODCALLTYPE DxgiSwapChain::Present(UINT SyncInterval, UINT Flags) {
|
||||||
|
return Present1(SyncInterval, Flags, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE DxgiSwapChain::Present1(
|
||||||
|
UINT SyncInterval,
|
||||||
|
UINT PresentFlags,
|
||||||
|
const DXGI_PRESENT_PARAMETERS* pPresentParameters) {
|
||||||
if (!IsWindow(m_window))
|
if (!IsWindow(m_window))
|
||||||
return DXGI_ERROR_INVALID_CALL;
|
return DXGI_ERROR_INVALID_CALL;
|
||||||
|
|
||||||
if (Flags & DXGI_PRESENT_TEST)
|
if (PresentFlags & DXGI_PRESENT_TEST)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lockWin(m_lockWindow);
|
std::lock_guard<std::mutex> lockWin(m_lockWindow);
|
||||||
std::lock_guard<std::mutex> lockBuf(m_lockBuffer);
|
std::lock_guard<std::mutex> lockBuf(m_lockBuffer);
|
||||||
|
|
||||||
// We'll apply certainl user options to the presenter
|
|
||||||
const DxgiOptions* options = m_factory->GetOptions();
|
|
||||||
|
|
||||||
// Retrieve the number of back buffers. If this option
|
|
||||||
// was defined by the user, it overrides app settings.
|
|
||||||
uint32_t bufferCount = m_desc.BufferCount;
|
|
||||||
|
|
||||||
if (options->numBackBuffers > 0)
|
|
||||||
bufferCount = options->numBackBuffers;
|
|
||||||
|
|
||||||
// Higher values are not allowed according to the Microsoft documentation:
|
// Higher values are not allowed according to the Microsoft documentation:
|
||||||
//
|
//
|
||||||
// "1 through 4 - Synchronize presentation after the nth vertical blank."
|
// "1 through 4 - Synchronize presentation after the nth vertical blank."
|
||||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb174576(v=vs.85).aspx
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb174576(v=vs.85).aspx
|
||||||
SyncInterval = std::min<UINT>(SyncInterval, 4);
|
SyncInterval = std::min<UINT>(SyncInterval, 4);
|
||||||
|
|
||||||
if (options->syncInterval >= 0)
|
|
||||||
SyncInterval = options->syncInterval;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// If in fullscreen mode, apply any updated gamma curve
|
// If in fullscreen mode, apply any updated gamma curve
|
||||||
// if it has been changed since the last present call.
|
// if it has been changed since the last present call.
|
||||||
@ -303,17 +284,7 @@ namespace dxvk {
|
|||||||
m_adapter->SetOutputData(m_monitor, &outputData);
|
m_adapter->SetOutputData(m_monitor, &outputData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Submit pending rendering commands
|
return m_presenter->Present(SyncInterval, PresentFlags, nullptr);
|
||||||
// before recording the present code.
|
|
||||||
m_presentDevice->FlushRenderingCommands();
|
|
||||||
|
|
||||||
// Update swap chain properties. This will not only set
|
|
||||||
// up vertical synchronization properly, but also apply
|
|
||||||
// changes that were made to the window size even if the
|
|
||||||
// Vulkan swap chain itself remains valid.
|
|
||||||
m_presenter->RecreateSwapchain(m_desc.Format, SyncInterval != 0, GetWindowSize(), bufferCount);
|
|
||||||
m_presenter->PresentImage(SyncInterval, m_device->GetFrameSyncEvent());
|
|
||||||
return S_OK;
|
|
||||||
} catch (const DxvkError& err) {
|
} catch (const DxvkError& err) {
|
||||||
Logger::err(err.message());
|
Logger::err(err.message());
|
||||||
return DXGI_ERROR_DRIVER_INTERNAL_ERROR;
|
return DXGI_ERROR_DRIVER_INTERNAL_ERROR;
|
||||||
@ -321,17 +292,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DxgiSwapChain::Present1(
|
|
||||||
UINT SyncInterval,
|
|
||||||
UINT PresentFlags,
|
|
||||||
const DXGI_PRESENT_PARAMETERS* pPresentParameters) {
|
|
||||||
if (pPresentParameters != nullptr)
|
|
||||||
Logger::warn("DXGI: Present parameters not supported");
|
|
||||||
|
|
||||||
return Present(SyncInterval, PresentFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DxgiSwapChain::ResizeBuffers(
|
HRESULT STDMETHODCALLTYPE DxgiSwapChain::ResizeBuffers(
|
||||||
UINT BufferCount,
|
UINT BufferCount,
|
||||||
UINT Width,
|
UINT Width,
|
||||||
@ -353,7 +313,7 @@ namespace dxvk {
|
|||||||
if (NewFormat != DXGI_FORMAT_UNKNOWN)
|
if (NewFormat != DXGI_FORMAT_UNKNOWN)
|
||||||
m_desc.Format = NewFormat;
|
m_desc.Format = NewFormat;
|
||||||
|
|
||||||
return CreateBackBuffer();
|
return m_presenter->ChangeProperties(&m_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -442,73 +402,12 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
HRESULT DxgiSwapChain::SetGammaControl(const DXGI_GAMMA_CONTROL* pGammaControl) {
|
HRESULT DxgiSwapChain::SetGammaControl(const DXGI_GAMMA_CONTROL* pGammaControl) {
|
||||||
DXGI_VK_GAMMA_CURVE curve;
|
return m_presenter->SetGammaControl(DXGI_VK_GAMMA_CP_COUNT, pGammaControl->GammaCurve);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < DXGI_VK_GAMMA_CP_COUNT; i++) {
|
|
||||||
const DXGI_RGB cp = pGammaControl->GammaCurve[i];
|
|
||||||
curve.ControlPoints[i].R = MapGammaControlPoint(cp.Red);
|
|
||||||
curve.ControlPoints[i].G = MapGammaControlPoint(cp.Green);
|
|
||||||
curve.ControlPoints[i].B = MapGammaControlPoint(cp.Blue);
|
|
||||||
curve.ControlPoints[i].A = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_presenter->SetGammaControl(&curve);
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT DxgiSwapChain::SetDefaultGammaControl() {
|
HRESULT DxgiSwapChain::SetDefaultGammaControl() {
|
||||||
DXGI_VK_GAMMA_CURVE curve;
|
return m_presenter->SetGammaControl(0, nullptr);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < DXGI_VK_GAMMA_CP_COUNT; i++) {
|
|
||||||
const uint16_t value = MapGammaControlPoint(
|
|
||||||
float(i) / float(DXGI_VK_GAMMA_CP_COUNT - 1));
|
|
||||||
curve.ControlPoints[i] = { value, value, value, 0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
m_presenter->SetGammaControl(&curve);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT DxgiSwapChain::CreatePresenter() {
|
|
||||||
try {
|
|
||||||
m_presenter = new DxgiVkPresenter(
|
|
||||||
m_factory->GetOptions(),
|
|
||||||
m_device->GetDXVKDevice(),
|
|
||||||
m_window);
|
|
||||||
return S_OK;
|
|
||||||
} catch (const DxvkError& e) {
|
|
||||||
Logger::err(e.message());
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT DxgiSwapChain::CreateBackBuffer() {
|
|
||||||
// Figure out sample count based on swap chain description
|
|
||||||
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
|
|
||||||
if (FAILED(GetSampleCount(m_desc.SampleDesc.Count, &sampleCount))) {
|
|
||||||
Logger::err("DXGI: CreateBackBuffer: Invalid sample count");
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy previous back buffer before creating a new one
|
|
||||||
m_backBuffer = nullptr;
|
|
||||||
|
|
||||||
if (FAILED(m_presentDevice->CreateSwapChainBackBuffer(&m_desc, &m_backBuffer))) {
|
|
||||||
Logger::err("DXGI: CreateBackBuffer: Failed to create back buffer");
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
m_presenter->UpdateBackBuffer(m_backBuffer->GetDXVKImage());
|
|
||||||
return S_OK;
|
|
||||||
} catch (const DxvkError& e) {
|
|
||||||
Logger::err(e.message());
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,15 +145,11 @@ namespace dxvk {
|
|||||||
DXGI_SWAP_CHAIN_FULLSCREEN_DESC m_descFs;
|
DXGI_SWAP_CHAIN_FULLSCREEN_DESC m_descFs;
|
||||||
DXGI_FRAME_STATISTICS m_stats;
|
DXGI_FRAME_STATISTICS m_stats;
|
||||||
|
|
||||||
Rc<DxgiVkPresenter> m_presenter;
|
Com<IDXGIVkSwapChain> m_presenter;
|
||||||
Com<IDXGIVkBackBuffer> m_backBuffer;
|
|
||||||
|
|
||||||
HMONITOR m_monitor;
|
HMONITOR m_monitor;
|
||||||
WindowState m_windowState;
|
WindowState m_windowState;
|
||||||
|
|
||||||
HRESULT CreatePresenter();
|
|
||||||
HRESULT CreateBackBuffer();
|
|
||||||
|
|
||||||
VkExtent2D GetWindowSize() const;
|
VkExtent2D GetWindowSize() const;
|
||||||
|
|
||||||
HRESULT EnterFullscreenMode(
|
HRESULT EnterFullscreenMode(
|
||||||
|
Loading…
Reference in New Issue
Block a user