Vulkan: fix wayland swapchain size 1x1

From Vulkan spec,
surfaceCapabilities.currentExtent can be 0xFFFFFFFF(-1)

Define a callback to get drawsize from window creator

relate:
https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkSurfaceCapabilitiesKHR.html
https://github.com/KhronosGroup/Vulkan-Docs/issues/590#issuecomment-347932321
This commit is contained in:
catsout 2022-10-15 18:49:45 +08:00
parent cbe31af8cf
commit b0ceeede79
3 changed files with 26 additions and 3 deletions

View File

@ -1011,12 +1011,21 @@ bool VulkanContext::InitSwapchain() {
res = vkGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[physical_device_], surface_, &presentModeCount, presentModes);
_dbg_assert_(res == VK_SUCCESS);
VkExtent2D currentExtent { surfCapabilities_.currentExtent };
// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkSurfaceCapabilitiesKHR.html
// currentExtent is the current width and height of the surface, or the special value (0xFFFFFFFF, 0xFFFFFFFF) indicating that the surface size will be determined by the extent of a swapchain targeting the surface.
if (currentExtent.width == 0xFFFFFFFFu || currentExtent.height == 0xFFFFFFFFu) {
_dbg_assert_((bool)cbGetDrawSize_)
if (cbGetDrawSize_) {
currentExtent = cbGetDrawSize_();
}
}
swapChainExtent_.width = clamp(surfCapabilities_.currentExtent.width, surfCapabilities_.minImageExtent.width, surfCapabilities_.maxImageExtent.width);
swapChainExtent_.height = clamp(surfCapabilities_.currentExtent.height, surfCapabilities_.minImageExtent.height, surfCapabilities_.maxImageExtent.height);
swapChainExtent_.width = clamp(currentExtent.width, surfCapabilities_.minImageExtent.width, surfCapabilities_.maxImageExtent.width);
swapChainExtent_.height = clamp(currentExtent.height, surfCapabilities_.minImageExtent.height, surfCapabilities_.maxImageExtent.height);
INFO_LOG(G3D, "surfCapabilities_.current: %dx%d min: %dx%d max: %dx%d computed: %dx%d",
surfCapabilities_.currentExtent.width, surfCapabilities_.currentExtent.height,
currentExtent.width, currentExtent.height,
surfCapabilities_.minImageExtent.width, surfCapabilities_.minImageExtent.height,
surfCapabilities_.maxImageExtent.width, surfCapabilities_.maxImageExtent.height,
swapChainExtent_.width, swapChainExtent_.height);
@ -1161,6 +1170,10 @@ bool VulkanContext::InitSwapchain() {
return true;
}
void VulkanContext::SetCbGetDrawSize(std::function<VkExtent2D()> cb) {
cbGetDrawSize_ = cb;
}
VkFence VulkanContext::CreateFence(bool presignalled) {
VkFence fence;
VkFenceCreateInfo fenceInfo{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };

View File

@ -4,6 +4,7 @@
#include <string>
#include <vector>
#include <utility>
#include <functional>
#include "Common/Log.h"
#include "Common/GPU/Vulkan/VulkanLoader.h"
@ -190,6 +191,7 @@ public:
VkResult ReinitSurface();
bool InitSwapchain();
void SetCbGetDrawSize(std::function<VkExtent2D()>);
void DestroySwapchain();
void DestroySurface();
@ -363,6 +365,7 @@ private:
// that we really don't want in everything that uses VulkanContext.
void *winsysData1_;
void *winsysData2_;
std::function<VkExtent2D()> cbGetDrawSize_;
VkInstance instance_ = VK_NULL_HANDLE;
VkDevice device_ = VK_NULL_HANDLE;

View File

@ -10,6 +10,7 @@
#include "Common/Data/Text/Parsers.h"
#include "Core/System.h"
#include "SDL_vulkan.h"
#include "SDLVulkanGraphicsContext.h"
#if defined(VK_USE_PLATFORM_METAL_EXT)
@ -72,6 +73,12 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode,
return false;
}
vulkan_->SetCbGetDrawSize([window]() {
int w=1,h=1;
SDL_Vulkan_GetDrawableSize(window, &w, &h);
return VkExtent2D {(uint32_t)w, (uint32_t)h};
});
SDL_SysWMinfo sys_info{};
SDL_VERSION(&sys_info.version); //Set SDL version
if (!SDL_GetWindowWMInfo(window, &sys_info)) {