1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-07 16:54:14 +01:00

[dxgi] Support SyncInterval values > 1

Required for Eve Online and the Unity Blacksmith demo.
This commit is contained in:
Philip Rebohle 2018-05-28 21:06:35 +02:00
parent f68bf1a187
commit e615fc19a9
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 81 additions and 67 deletions

View File

@ -143,7 +143,7 @@ namespace dxvk {
} }
void DxgiVkPresenter::PresentImage() { void DxgiVkPresenter::PresentImage(UINT SyncInterval) {
if (m_hud != nullptr) { if (m_hud != nullptr) {
m_hud->render({ m_hud->render({
m_options.preferredBufferSize.width, m_options.preferredBufferSize.width,
@ -151,77 +151,84 @@ namespace dxvk {
}); });
} }
// Check whether the back buffer size is the same
// as the window size, in which case we should use
// VK_FILTER_NEAREST to avoid blurry output
const bool fitSize = const bool fitSize =
m_backBuffer->info().extent.width == m_options.preferredBufferSize.width m_backBuffer->info().extent.width == m_options.preferredBufferSize.width
&& m_backBuffer->info().extent.height == m_options.preferredBufferSize.height; && m_backBuffer->info().extent.height == m_options.preferredBufferSize.height;
m_context->beginRecording( for (uint32_t i = 0; i < SyncInterval || i < 1; i++) {
m_device->createCommandList()); m_context->beginRecording(
m_device->createCommandList());
VkImageSubresourceLayers resolveSubresources; // Resolve back buffer if it is multisampled. We
resolveSubresources.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; // only have to do it only for the first frame.
resolveSubresources.mipLevel = 0; if (m_backBufferResolve != nullptr && i == 0) {
resolveSubresources.baseArrayLayer = 0; VkImageSubresourceLayers resolveSubresources;
resolveSubresources.layerCount = 1; resolveSubresources.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
resolveSubresources.mipLevel = 0;
resolveSubresources.baseArrayLayer = 0;
resolveSubresources.layerCount = 1;
if (m_backBufferResolve != nullptr) { m_context->resolveImage(
m_context->resolveImage( m_backBufferResolve, resolveSubresources,
m_backBufferResolve, resolveSubresources, m_backBuffer, resolveSubresources,
m_backBuffer, resolveSubresources, VK_FORMAT_UNDEFINED);
VK_FORMAT_UNDEFINED); }
}
auto swapSemas = m_swapchain->getSemaphorePair(); auto swapSemas = m_swapchain->getSemaphorePair();
auto swapImage = m_swapchain->getImageView(swapSemas.acquireSync); auto swapImage = m_swapchain->getImageView(swapSemas.acquireSync);
DxvkRenderTargets renderTargets; DxvkRenderTargets renderTargets;
renderTargets.color[0].view = swapImage; renderTargets.color[0].view = swapImage;
renderTargets.color[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; renderTargets.color[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
m_context->bindRenderTargets(renderTargets); m_context->bindRenderTargets(renderTargets);
VkViewport viewport; VkViewport viewport;
viewport.x = 0.0f; viewport.x = 0.0f;
viewport.y = 0.0f; viewport.y = 0.0f;
viewport.width = float(swapImage->imageInfo().extent.width); viewport.width = float(swapImage->imageInfo().extent.width);
viewport.height = float(swapImage->imageInfo().extent.height); viewport.height = float(swapImage->imageInfo().extent.height);
viewport.minDepth = 0.0f; viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f; viewport.maxDepth = 1.0f;
VkRect2D scissor; VkRect2D scissor;
scissor.offset.x = 0; scissor.offset.x = 0;
scissor.offset.y = 0; scissor.offset.y = 0;
scissor.extent.width = swapImage->imageInfo().extent.width; scissor.extent.width = swapImage->imageInfo().extent.width;
scissor.extent.height = swapImage->imageInfo().extent.height; scissor.extent.height = swapImage->imageInfo().extent.height;
m_context->setViewports(1, &viewport, &scissor); m_context->setViewports(1, &viewport, &scissor);
m_context->bindResourceSampler(BindingIds::Sampler, m_context->bindResourceSampler(BindingIds::Sampler,
fitSize ? m_samplerFitting : m_samplerScaling); fitSize ? m_samplerFitting : m_samplerScaling);
m_blendMode.enableBlending = VK_FALSE; m_blendMode.enableBlending = VK_FALSE;
m_context->setBlendMode(0, m_blendMode);
m_context->bindResourceView(BindingIds::Texture, m_backBufferView, nullptr);
m_context->draw(4, 1, 0, 0);
m_context->bindResourceSampler(BindingIds::GammaSmp, m_gammaSampler);
m_context->bindResourceView (BindingIds::GammaTex, m_gammaTextureView, nullptr);
if (m_hud != nullptr) {
m_blendMode.enableBlending = VK_TRUE;
m_context->setBlendMode(0, m_blendMode); m_context->setBlendMode(0, m_blendMode);
m_context->bindResourceView(BindingIds::Texture, m_hud->texture(), nullptr); m_context->bindResourceView(BindingIds::Texture, m_backBufferView, nullptr);
m_context->draw(4, 1, 0, 0); m_context->draw(4, 1, 0, 0);
m_context->bindResourceSampler(BindingIds::GammaSmp, m_gammaSampler);
m_context->bindResourceView (BindingIds::GammaTex, m_gammaTextureView, nullptr);
if (m_hud != nullptr) {
m_blendMode.enableBlending = VK_TRUE;
m_context->setBlendMode(0, m_blendMode);
m_context->bindResourceView(BindingIds::Texture, m_hud->texture(), nullptr);
m_context->draw(4, 1, 0, 0);
}
m_device->submitCommandList(
m_context->endRecording(),
swapSemas.acquireSync,
swapSemas.presentSync);
m_swapchain->present(
swapSemas.presentSync);
} }
m_device->submitCommandList(
m_context->endRecording(),
swapSemas.acquireSync,
swapSemas.presentSync);
m_swapchain->present(
swapSemas.presentSync);
} }

View File

@ -82,8 +82,9 @@ namespace dxvk {
/** /**
* \brief Renders back buffer to the screen * \brief Renders back buffer to the screen
* \param [in] SyncInterval Vsync interval
*/ */
void PresentImage(); void PresentImage(UINT SyncInterval);
/** /**
* \brief Sets new back buffer * \brief Sets new back buffer

View File

@ -286,6 +286,12 @@ namespace dxvk {
if (Flags & DXGI_PRESENT_TEST) if (Flags & DXGI_PRESENT_TEST)
return S_OK; return S_OK;
// 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);
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.
@ -311,7 +317,7 @@ namespace dxvk {
: VK_PRESENT_MODE_FIFO_KHR; : VK_PRESENT_MODE_FIFO_KHR;
m_presenter->RecreateSwapchain(m_desc.Format, presentMode, GetWindowSize()); m_presenter->RecreateSwapchain(m_desc.Format, presentMode, GetWindowSize());
m_presenter->PresentImage(); m_presenter->PresentImage(SyncInterval);
return S_OK; return S_OK;
} catch (const DxvkError& err) { } catch (const DxvkError& err) {
Logger::err(err.message()); Logger::err(err.message());