Add Vsync configuration support to the RHI. (#1)

This commit is contained in:
Darío 2024-10-30 05:32:30 -03:00 committed by GitHub
parent ca9009b88d
commit 7d04ed057c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 40 additions and 5 deletions

View file

@ -1265,7 +1265,8 @@ namespace RT64 {
while (WaitForSingleObjectEx(waitableObject, 0, FALSE));
}
HRESULT res = d3d->Present(1, 0);
UINT syncInterval = vsyncEnabled ? 1 : 0;
HRESULT res = d3d->Present(syncInterval, 0);
return SUCCEEDED(res);
}
@ -1299,6 +1300,14 @@ namespace RT64 {
return (d3d == nullptr) || (windowWidth != width) || (windowHeight != height);
}
void D3D12SwapChain::setVsyncEnabled(bool vsyncEnabled) {
this->vsyncEnabled = vsyncEnabled;
}
bool D3D12SwapChain::isVsyncEnabled() const {
return vsyncEnabled;
}
uint32_t D3D12SwapChain::getWidth() const {
return width;
}

View file

@ -103,12 +103,15 @@ namespace RT64 {
uint32_t width = 0;
uint32_t height = 0;
uint32_t refreshRate = 0;
bool vsyncEnabled = true;
D3D12SwapChain(D3D12CommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format);
~D3D12SwapChain() override;
bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override;
bool resize() override;
bool needsResize() const override;
void setVsyncEnabled(bool vsyncEnabled) override;
bool isVsyncEnabled() const override;
uint32_t getWidth() const override;
uint32_t getHeight() const override;
RenderTexture *getTexture(uint32_t textureIndex) override;

View file

@ -85,6 +85,8 @@ namespace RT64 {
virtual bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) = 0;
virtual bool resize() = 0;
virtual bool needsResize() const = 0;
virtual void setVsyncEnabled(bool vsyncEnabled) = 0;
virtual bool isVsyncEnabled() const = 0;
virtual uint32_t getWidth() const = 0;
virtual uint32_t getHeight() const = 0;
virtual RenderTexture *getTexture(uint32_t textureIndex) = 0;

View file

@ -2047,6 +2047,7 @@ namespace RT64 {
std::vector<VkPresentModeKHR> presentModes(presentModeCount);
vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data());
immediatePresentModeSupported = std::find(presentModes.begin(), presentModes.end(), VK_PRESENT_MODE_IMMEDIATE_KHR) != presentModes.end();
// Check if the format we requested is part of the supported surface formats.
std::vector<VkSurfaceFormatKHR> compatibleSurfaceFormats;
@ -2076,7 +2077,7 @@ namespace RT64 {
}
// FIFO is guaranteed to be supported.
pickedPresentMode = VK_PRESENT_MODE_FIFO_KHR;
requiredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
// Pick an alpha compositing mode, prefer opaque over inherit.
if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) {
@ -2164,7 +2165,7 @@ namespace RT64 {
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
createInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
createInfo.compositeAlpha = pickedAlphaFlag;
createInfo.presentMode = pickedPresentMode;
createInfo.presentMode = requiredPresentMode;
createInfo.clipped = VK_TRUE;
createInfo.oldSwapchain = vk;
@ -2174,6 +2175,9 @@ namespace RT64 {
return false;
}
// Store the chosen present mode to identify later whether the swapchain needs to be recreated.
createdPresentMode = requiredPresentMode;
// Reset present counter.
presentCount = 1;
@ -2222,7 +2226,19 @@ namespace RT64 {
bool VulkanSwapChain::needsResize() const {
uint32_t windowWidth, windowHeight;
getWindowSize(windowWidth, windowHeight);
return (vk == VK_NULL_HANDLE) || (windowWidth != width) || (windowHeight != height);
return (vk == VK_NULL_HANDLE) || (windowWidth != width) || (windowHeight != height) || (requiredPresentMode != createdPresentMode);
}
void VulkanSwapChain::setVsyncEnabled(bool vsyncEnabled) {
// Immediate mode must be supported and the presentation mode will only be used on the next resize.
// needsResize() will return as true as long as the created and required present mode do not match.
if (immediatePresentModeSupported) {
requiredPresentMode = vsyncEnabled ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR;
}
}
bool VulkanSwapChain::isVsyncEnabled() const {
return createdPresentMode == VK_PRESENT_MODE_FIFO_KHR;
}
uint32_t VulkanSwapChain::getWidth() const {

View file

@ -210,15 +210,19 @@ namespace RT64 {
uint32_t height = 0;
VkSwapchainCreateInfoKHR createInfo = {};
VkSurfaceFormatKHR pickedSurfaceFormat = {};
VkPresentModeKHR pickedPresentMode = VK_PRESENT_MODE_FIFO_KHR;
VkPresentModeKHR createdPresentMode = VK_PRESENT_MODE_FIFO_KHR;
VkPresentModeKHR requiredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
VkCompositeAlphaFlagBitsKHR pickedAlphaFlag = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
std::vector<VulkanTexture> textures;
bool immediatePresentModeSupported = false;
VulkanSwapChain(VulkanCommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format);
~VulkanSwapChain() override;
bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override;
bool resize() override;
bool needsResize() const override;
void setVsyncEnabled(bool vsyncEnabled) override;
bool isVsyncEnabled() const override;
uint32_t getWidth() const override;
uint32_t getHeight() const override;
RenderTexture *getTexture(uint32_t textureIndex) override;

View file

@ -837,6 +837,7 @@ static void CreateHostDevice()
g_copyCommandFence = g_device->createCommandFence();
g_swapChain = g_queue->createSwapChain(Window::s_windowHandle, Config::TripleBuffering ? 3 : 2, RenderFormat::B8G8R8A8_UNORM);
g_swapChain->setVsyncEnabled(Config::VSync);
g_swapChainValid = !g_swapChain->needsResize();
for (auto& acquireSemaphore : g_acquireSemaphores)