Renderer: Expose present mode and allow to query/set it
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderer.hpp>
|
||||
#include <Nazara/Renderer/CommandPool.hpp>
|
||||
#include <Nazara/Renderer/WindowSwapchain.hpp>
|
||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
@@ -54,6 +53,23 @@ namespace Nz
|
||||
else
|
||||
depthFormat = PixelFormat::Undefined;
|
||||
|
||||
m_supportedPresentModes = m_context->GetSupportedPresentModes();
|
||||
|
||||
#ifdef NAZARA_PLATFORM_WEB
|
||||
m_presentMode = PresentMode::Immediate; //< default present mode
|
||||
#else
|
||||
m_presentMode = PresentMode::VerticalSync; //< default present mode
|
||||
#endif
|
||||
|
||||
for (PresentMode presentMode : parameters.presentMode)
|
||||
{
|
||||
if (m_supportedPresentModes & presentMode)
|
||||
{
|
||||
SetPresentMode(presentMode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<RenderPass::Attachment> attachments;
|
||||
std::vector<RenderPass::SubpassDescription> subpassDescriptions;
|
||||
std::vector<RenderPass::SubpassDependency> subpassDependencies;
|
||||
@@ -78,7 +94,7 @@ namespace Nz
|
||||
|
||||
std::shared_ptr<CommandPool> OpenGLSwapchain::CreateCommandPool(QueueType /*queueType*/)
|
||||
{
|
||||
return std::make_unique<OpenGLCommandPool>();
|
||||
return std::make_shared<OpenGLCommandPool>();
|
||||
}
|
||||
|
||||
const OpenGLFramebuffer& OpenGLSwapchain::GetFramebuffer(std::size_t i) const
|
||||
@@ -98,11 +114,21 @@ namespace Nz
|
||||
return *m_renderPass;
|
||||
}
|
||||
|
||||
PresentMode OpenGLSwapchain::GetPresentMode() const
|
||||
{
|
||||
return m_presentMode;
|
||||
}
|
||||
|
||||
const Vector2ui& OpenGLSwapchain::GetSize() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
PresentModeFlags OpenGLSwapchain::GetSupportedPresentModes() const
|
||||
{
|
||||
return m_supportedPresentModes;
|
||||
}
|
||||
|
||||
void OpenGLSwapchain::NotifyResize(const Vector2ui& newSize)
|
||||
{
|
||||
OnRenderTargetSizeChange(this, newSize);
|
||||
@@ -117,6 +143,17 @@ namespace Nz
|
||||
m_currentFrame = (m_currentFrame + 1) % m_renderImage.size();
|
||||
}
|
||||
|
||||
void OpenGLSwapchain::SetPresentMode(PresentMode presentMode)
|
||||
{
|
||||
NazaraAssert(m_supportedPresentModes & presentMode, "unsupported present mode");
|
||||
|
||||
if (m_presentMode != presentMode)
|
||||
{
|
||||
m_context->SetPresentMode(presentMode);
|
||||
m_presentMode = presentMode;
|
||||
}
|
||||
}
|
||||
|
||||
TransientResources& OpenGLSwapchain::Transient()
|
||||
{
|
||||
return *m_renderImage[m_currentFrame];
|
||||
|
||||
@@ -670,8 +670,6 @@ namespace Nz::GL
|
||||
m_state.renderStates.scissorTest = false;
|
||||
m_state.renderStates.stencilTest = false;
|
||||
|
||||
EnableVerticalSync(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,9 +87,33 @@ namespace Nz::GL
|
||||
}
|
||||
}
|
||||
|
||||
void EGLContextBase::EnableVerticalSync(bool enabled)
|
||||
PresentModeFlags EGLContextBase::GetSupportedPresentModes() const
|
||||
{
|
||||
// TODO
|
||||
PresentModeFlags supportedModes;
|
||||
if (m_maxSwapInterval >= 1)
|
||||
supportedModes |= PresentMode::VerticalSync;
|
||||
|
||||
if (m_minSwapInterval <= 0)
|
||||
supportedModes |= PresentMode::Immediate;
|
||||
|
||||
if (m_minSwapInterval <= -1)
|
||||
supportedModes |= PresentMode::RelaxedVerticalSync;
|
||||
|
||||
return supportedModes;
|
||||
}
|
||||
|
||||
void EGLContextBase::SetPresentMode(PresentMode presentMode)
|
||||
{
|
||||
int interval = 0;
|
||||
switch (presentMode)
|
||||
{
|
||||
case PresentMode::Immediate: interval = 0; break;
|
||||
case PresentMode::RelaxedVerticalSync: interval = -1; break;
|
||||
case PresentMode::VerticalSync: interval = 1; break;
|
||||
default: return; // TODO: Unreachable
|
||||
}
|
||||
|
||||
m_loader.eglSwapInterval(m_display, interval);
|
||||
}
|
||||
|
||||
void EGLContextBase::SwapBuffers()
|
||||
@@ -247,6 +271,9 @@ namespace Nz::GL
|
||||
return false;
|
||||
}
|
||||
|
||||
m_loader.eglGetConfigAttrib(m_display, config, EGL_MAX_SWAP_INTERVAL, &m_maxSwapInterval);
|
||||
m_loader.eglGetConfigAttrib(m_display, config, EGL_MIN_SWAP_INTERVAL, &m_minSwapInterval);
|
||||
|
||||
LoadEGLExt();
|
||||
|
||||
return true;
|
||||
|
||||
@@ -73,15 +73,34 @@ namespace Nz::GL
|
||||
}
|
||||
}
|
||||
|
||||
void WGLContext::EnableVerticalSync(bool enabled)
|
||||
PresentModeFlags WGLContext::GetSupportedPresentModes() const
|
||||
{
|
||||
PresentModeFlags supportedModes = PresentMode::Immediate;
|
||||
if (wglSwapIntervalEXT)
|
||||
{
|
||||
if (!SetCurrentContext(this))
|
||||
return;
|
||||
|
||||
wglSwapIntervalEXT(enabled);
|
||||
supportedModes |= PresentMode::VerticalSync;
|
||||
if (HasPlatformExtension("WGL_EXT_swap_control_tear"))
|
||||
supportedModes |= PresentMode::RelaxedVerticalSync;
|
||||
}
|
||||
|
||||
return supportedModes;
|
||||
}
|
||||
|
||||
void WGLContext::SetPresentMode(PresentMode presentMode)
|
||||
{
|
||||
if (!SetCurrentContext(this))
|
||||
return;
|
||||
|
||||
int interval = 0;
|
||||
switch (presentMode)
|
||||
{
|
||||
case PresentMode::Immediate: interval = 0; break;
|
||||
case PresentMode::RelaxedVerticalSync: interval = -1; break; //< WGL_EXT_swap_control_tear
|
||||
case PresentMode::VerticalSync: interval = 1; break;
|
||||
default: return; // TODO: Unreachable
|
||||
}
|
||||
|
||||
wglSwapIntervalEXT(interval);
|
||||
}
|
||||
|
||||
void WGLContext::SwapBuffers()
|
||||
|
||||
@@ -64,9 +64,15 @@ namespace Nz::GL
|
||||
}
|
||||
}
|
||||
|
||||
void WebContext::EnableVerticalSync(bool /*enabled*/)
|
||||
PresentModeFlags WebContext::GetSupportedPresentModes() const
|
||||
{
|
||||
// TODO
|
||||
// WebGL does not support disabling V-Sync
|
||||
return PresentMode::VerticalSync;
|
||||
}
|
||||
|
||||
void WebContext::SetPresentMode(PresentMode /*presentMode*/)
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
void WebContext::SwapBuffers()
|
||||
|
||||
@@ -151,6 +151,27 @@ namespace Nz
|
||||
throw std::runtime_error("failed to find a support depth-stencil format");
|
||||
}
|
||||
|
||||
std::vector<VkPresentModeKHR> presentModes;
|
||||
if (!m_surface.GetPresentModes(physDeviceInfo.physDevice, &presentModes))
|
||||
throw std::runtime_error("failed to query supported present modes");
|
||||
|
||||
m_supportedPresentModes.Clear();
|
||||
for (VkPresentModeKHR vkPresentMode : presentModes)
|
||||
{
|
||||
if (auto presentModeOpt = FromVulkan(vkPresentMode))
|
||||
m_supportedPresentModes |= *presentModeOpt;
|
||||
}
|
||||
|
||||
m_presentMode = PresentMode::VerticalSync; //< guaranteed to be supported
|
||||
for (PresentMode presentMode : parameters.presentMode)
|
||||
{
|
||||
if (m_supportedPresentModes & presentMode)
|
||||
{
|
||||
m_presentMode = presentMode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetupRenderPass())
|
||||
throw std::runtime_error("failed to create renderpass");
|
||||
|
||||
@@ -292,6 +313,16 @@ namespace Nz
|
||||
return m_swapchainSize;
|
||||
}
|
||||
|
||||
PresentMode VulkanSwapchain::GetPresentMode() const
|
||||
{
|
||||
return m_presentMode;
|
||||
}
|
||||
|
||||
PresentModeFlags VulkanSwapchain::GetSupportedPresentModes() const
|
||||
{
|
||||
return m_supportedPresentModes;
|
||||
}
|
||||
|
||||
void VulkanSwapchain::NotifyResize(const Vector2ui& newSize)
|
||||
{
|
||||
OnRenderTargetSizeChange(this, newSize);
|
||||
@@ -332,6 +363,17 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanSwapchain::SetPresentMode(PresentMode presentMode)
|
||||
{
|
||||
NazaraAssert(m_supportedPresentModes & presentMode, "unsupported present mode");
|
||||
|
||||
if (m_presentMode != presentMode)
|
||||
{
|
||||
m_presentMode = presentMode;
|
||||
m_shouldRecreateSwapchain = true;
|
||||
}
|
||||
}
|
||||
|
||||
TransientResources& VulkanSwapchain::Transient()
|
||||
{
|
||||
return *m_concurrentImageData[m_currentFrame];
|
||||
@@ -566,26 +608,6 @@ namespace Nz
|
||||
else
|
||||
extent = surfaceCapabilities.currentExtent;
|
||||
|
||||
std::vector<VkPresentModeKHR> presentModes;
|
||||
if (!m_surface.GetPresentModes(deviceInfo.physDevice, &presentModes))
|
||||
{
|
||||
NazaraError("Failed to query supported present modes");
|
||||
return false;
|
||||
}
|
||||
|
||||
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
for (VkPresentModeKHR presentMode : presentModes)
|
||||
{
|
||||
if (presentMode == VK_PRESENT_MODE_MAILBOX_KHR)
|
||||
{
|
||||
swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (presentMode == VK_PRESENT_MODE_IMMEDIATE_KHR)
|
||||
swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||
}
|
||||
|
||||
VkCompositeAlphaFlagBitsKHR compositeAlpha;
|
||||
if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
|
||||
compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
@@ -610,7 +632,7 @@ namespace Nz
|
||||
0, nullptr,
|
||||
surfaceCapabilities.currentTransform,
|
||||
compositeAlpha,
|
||||
swapchainPresentMode,
|
||||
ToVulkan(m_presentMode),
|
||||
VK_TRUE,
|
||||
m_swapchain
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user