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:
parent
f68bf1a187
commit
e615fc19a9
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user