1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-29 19:24:10 +01:00

[dxgi] Use new presenter for D3D11

This commit is contained in:
Philip Rebohle 2018-10-22 22:44:04 +02:00
parent 967b276acb
commit b53f6661f8
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 17 additions and 134 deletions

View File

@ -35,18 +35,6 @@ namespace dxvk {
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
*

View File

@ -54,11 +54,8 @@ namespace dxvk {
if (!m_descFs.Windowed && FAILED(EnterFullscreenMode(nullptr)))
throw DxvkError("DXGI: DxgiSwapChain: Failed to set initial fullscreen state");
if (FAILED(CreatePresenter()) || FAILED(CreateBackBuffer()))
throw DxvkError("DXGI: DxgiSwapChain: Failed to create presenter or back buffer");
if (FAILED(SetDefaultGammaControl()))
throw DxvkError("DXGI: DxgiSwapChain: Failed to set up gamma ramp");
if (FAILED(m_presentDevice->CreateSwapChainForHwnd(m_window, &m_desc, &m_presenter)))
throw DxvkError("DXGI: DxgiSwapChain: Failed to create presenter");
}
@ -99,18 +96,7 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE DxgiSwapChain::GetBuffer(UINT Buffer, REFIID riid, void** ppSurface) {
InitReturnPtr(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);
return m_presenter->GetImage(Buffer, riid, ppSurface);
}
@ -263,34 +249,29 @@ namespace dxvk {
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))
return DXGI_ERROR_INVALID_CALL;
if (Flags & DXGI_PRESENT_TEST)
if (PresentFlags & DXGI_PRESENT_TEST)
return S_OK;
std::lock_guard<std::mutex> lockWin(m_lockWindow);
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:
//
// "1 through 4 - Synchronize presentation after the nth vertical blank."
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb174576(v=vs.85).aspx
SyncInterval = std::min<UINT>(SyncInterval, 4);
if (options->syncInterval >= 0)
SyncInterval = options->syncInterval;
try {
// If in fullscreen mode, apply any updated gamma curve
// if it has been changed since the last present call.
@ -303,17 +284,7 @@ namespace dxvk {
m_adapter->SetOutputData(m_monitor, &outputData);
}
// Submit pending rendering commands
// 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;
return m_presenter->Present(SyncInterval, PresentFlags, nullptr);
} catch (const DxvkError& err) {
Logger::err(err.message());
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(
UINT BufferCount,
UINT Width,
@ -353,7 +313,7 @@ namespace dxvk {
if (NewFormat != DXGI_FORMAT_UNKNOWN)
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) {
DXGI_VK_GAMMA_CURVE curve;
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;
return m_presenter->SetGammaControl(DXGI_VK_GAMMA_CP_COUNT, pGammaControl->GammaCurve);
}
HRESULT DxgiSwapChain::SetDefaultGammaControl() {
DXGI_VK_GAMMA_CURVE curve;
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;
}
return m_presenter->SetGammaControl(0, nullptr);
}

View File

@ -145,15 +145,11 @@ namespace dxvk {
DXGI_SWAP_CHAIN_FULLSCREEN_DESC m_descFs;
DXGI_FRAME_STATISTICS m_stats;
Rc<DxgiVkPresenter> m_presenter;
Com<IDXGIVkBackBuffer> m_backBuffer;
Com<IDXGIVkSwapChain> m_presenter;
HMONITOR m_monitor;
WindowState m_windowState;
HRESULT CreatePresenter();
HRESULT CreateBackBuffer();
VkExtent2D GetWindowSize() const;
HRESULT EnterFullscreenMode(