vulkan: Add fallback extent for swap chain sizing (#6495)
vulkan: Add fallback extent for swap chain sizing
This commit is contained in:
@@ -27,8 +27,19 @@ namespace filament::backend {
|
||||
|
||||
class VulkanPlatform : public Platform {
|
||||
public:
|
||||
struct SurfaceBundle {
|
||||
void* surface;
|
||||
// On certain platforms, the extent of the surface cannot be queried from Vulkan. In those
|
||||
// situations, we allow the frontend to pass in the extent to use in creating the swap
|
||||
// chains. Platform implementation should set extent to 0 if they do not expect to set the
|
||||
// swap chain extent.
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
};
|
||||
|
||||
// Given a Vulkan instance and native window handle, creates the platform-specific surface.
|
||||
virtual void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept = 0;
|
||||
virtual SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept = 0;
|
||||
|
||||
~VulkanPlatform() override;
|
||||
};
|
||||
|
||||
@@ -29,23 +29,32 @@ using namespace bluevk;
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
Driver* PlatformVkAndroid::createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
|
||||
|
||||
Driver* PlatformVkAndroid::createDriver(void* const sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept {
|
||||
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
|
||||
static const char* requiredInstanceExtensions[] = { "VK_KHR_android_surface" };
|
||||
return VulkanDriverFactory::create(this, requiredInstanceExtensions, 1, driverConfig);
|
||||
}
|
||||
|
||||
void* PlatformVkAndroid::createVkSurfaceKHR(void* nativeWindow, void* vkinstance, uint64_t flags) noexcept {
|
||||
SurfaceBundle PlatformVkAndroid::createVkSurfaceKHR(void* nativeWindow, void* vkinstance,
|
||||
uint64_t flags) noexcept {
|
||||
const VkInstance instance = (VkInstance) vkinstance;
|
||||
ANativeWindow* aNativeWindow = (ANativeWindow*) nativeWindow;
|
||||
VkAndroidSurfaceCreateInfoKHR createInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
|
||||
.window = aNativeWindow
|
||||
};
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
VkResult result = vkCreateAndroidSurfaceKHR(instance, &createInfo, VKALLOC, &surface);
|
||||
SurfaceBundle bundle {
|
||||
.surface = VK_NULL_HANDLE,
|
||||
.width = 0,
|
||||
.height = 0
|
||||
};
|
||||
VkResult result = vkCreateAndroidSurfaceKHR(instance, &createInfo, VKALLOC,
|
||||
(VkSurfaceKHR*) &bundle.surface);
|
||||
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateAndroidSurfaceKHR error.");
|
||||
return (void*) surface;
|
||||
return bundle;
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -29,7 +29,8 @@ public:
|
||||
|
||||
Driver* createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
|
||||
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept override;
|
||||
|
||||
int getOSVersion() const noexcept override { return 0; }
|
||||
};
|
||||
|
||||
@@ -27,7 +27,8 @@ namespace filament::backend {
|
||||
class PlatformVkCocoa final : public VulkanPlatform {
|
||||
public:
|
||||
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
|
||||
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept override;
|
||||
int getOSVersion() const noexcept override { return 0; }
|
||||
};
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ using namespace bluevk;
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
|
||||
|
||||
Driver* PlatformVkCocoa::createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
|
||||
static const char* requiredInstanceExtensions[] = {
|
||||
@@ -42,21 +44,28 @@ Driver* PlatformVkCocoa::createDriver(void* sharedContext, const Platform::Drive
|
||||
return VulkanDriverFactory::create(this, requiredInstanceExtensions, 1, driverConfig);
|
||||
}
|
||||
|
||||
void* PlatformVkCocoa::createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept {
|
||||
SurfaceBundle PlatformVkCocoa::createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept {
|
||||
// Obtain the CAMetalLayer-backed view.
|
||||
NSView* nsview = (__bridge NSView*) nativeWindow;
|
||||
ASSERT_POSTCONDITION(nsview, "Unable to obtain Metal-backed NSView.");
|
||||
|
||||
// Create the VkSurface.
|
||||
ASSERT_POSTCONDITION(vkCreateMacOSSurfaceMVK, "Unable to load vkCreateMacOSSurfaceMVK.");
|
||||
VkSurfaceKHR surface = nullptr;
|
||||
VkMacOSSurfaceCreateInfoMVK createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
||||
createInfo.pView = (__bridge void*) nsview;
|
||||
VkResult result = vkCreateMacOSSurfaceMVK((VkInstance) instance, &createInfo, VKALLOC, &surface);
|
||||
|
||||
SurfaceBundle bundle {
|
||||
.surface = nullptr,
|
||||
.width = 0,
|
||||
.height = 0
|
||||
};
|
||||
VkResult result = vkCreateMacOSSurfaceMVK((VkInstance) instance, &createInfo, VKALLOC,
|
||||
(VkSurfaceKHR*) &bundle.surface);
|
||||
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateMacOSSurfaceMVK error.");
|
||||
|
||||
return surface;
|
||||
return bundle;
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -27,7 +27,8 @@ namespace filament::backend {
|
||||
class PlatformVkCocoaTouch final : public VulkanPlatform {
|
||||
public:
|
||||
Driver* createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
|
||||
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept override;
|
||||
int getOSVersion() const noexcept override { return 0; }
|
||||
};
|
||||
|
||||
|
||||
@@ -39,31 +39,37 @@ using namespace bluevk;
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
|
||||
|
||||
Driver* PlatformVkCocoaTouch::createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
|
||||
static const char* requestedExtensions[] = {"VK_MVK_ios_surface"};
|
||||
return VulkanDriverFactory::create(this, requestedExtensions, 1, driverConfig);
|
||||
}
|
||||
|
||||
void* PlatformVkCocoaTouch::createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept {
|
||||
SurfaceBundle PlatformVkCocoaTouch::createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept {
|
||||
SurfaceBundle bundle {
|
||||
.surface = nullptr,
|
||||
.width = 0,
|
||||
.height = 0
|
||||
};
|
||||
#if METAL_AVAILABLE
|
||||
CAMetalLayer* metalLayer = (CAMetalLayer*) nativeWindow;
|
||||
|
||||
// Create the VkSurface.
|
||||
ASSERT_POSTCONDITION(vkCreateIOSSurfaceMVK, "Unable to load vkCreateIOSSurfaceMVK function.");
|
||||
VkSurfaceKHR surface = nullptr;
|
||||
VkIOSSurfaceCreateInfoMVK createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.pView = metalLayer;
|
||||
VkResult result = vkCreateIOSSurfaceMVK((VkInstance) instance, &createInfo, VKALLOC, &surface);
|
||||
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateIOSSurfaceMVK error.");
|
||||
|
||||
return surface;
|
||||
#else
|
||||
return nullptr;
|
||||
VkResult result = vkCreateIOSSurfaceMVK((VkInstance) instance, &createInfo, VKALLOC,
|
||||
(VkSurfaceKHR*) &bundle.surface);
|
||||
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateIOSSurfaceMVK error.");
|
||||
#endif
|
||||
return bundle;
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -28,6 +28,8 @@ using namespace bluevk;
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
|
||||
|
||||
Driver* PlatformVkLinuxGGP::createDriver(
|
||||
void* const sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept {
|
||||
@@ -46,8 +48,13 @@ Driver* PlatformVkLinuxGGP::createDriver(
|
||||
#endif
|
||||
}
|
||||
|
||||
void* PlatformVkLinuxGGP::createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept {
|
||||
SurfaceBundle PlatformVkLinuxGGP::createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept {
|
||||
SurfaceBundle bundle {
|
||||
.surface = nullptr,
|
||||
.width = 0,
|
||||
.height = 0
|
||||
};
|
||||
#if defined(FILAMENT_SUPPORTS_GGP)
|
||||
VkStreamDescriptorSurfaceCreateInfoGGP surface_create_info = {
|
||||
VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP};
|
||||
@@ -59,16 +66,14 @@ void* PlatformVkLinuxGGP::createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
ASSERT_PRECONDITION(fpCreateStreamDescriptorSurfaceGGP != nullptr,
|
||||
"Error getting VkInstance "
|
||||
"function vkCreateStreamDescriptorSurfaceGGP");
|
||||
VkSurfaceKHR surface = nullptr;
|
||||
VkResult res = fpCreateStreamDescriptorSurfaceGGP(
|
||||
static_cast<VkInstance>(instance), &surface_create_info, nullptr,
|
||||
&surface);
|
||||
(VkSurfaceKHR*) &bundle.surface);
|
||||
ASSERT_PRECONDITION(res == VK_SUCCESS, "Error in vulkan: %d", res);
|
||||
return surface;
|
||||
#else
|
||||
PANIC_PRECONDITION("Filament does not support GGP.");
|
||||
return nullptr;
|
||||
#endif
|
||||
return bundle;
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -30,8 +30,8 @@ class PlatformVkLinuxGGP final : public VulkanPlatform {
|
||||
void* const sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
void* createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept override;
|
||||
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept override;
|
||||
|
||||
int getOSVersion() const noexcept override { return 0; }
|
||||
};
|
||||
|
||||
@@ -27,8 +27,19 @@
|
||||
|
||||
using namespace bluevk;
|
||||
|
||||
namespace {
|
||||
typedef struct _wl {
|
||||
struct wl_display *display;
|
||||
struct wl_surface *surface;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} wl;
|
||||
} // anonymous namespace
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
|
||||
|
||||
Driver* PlatformVkLinuxWayland::createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
|
||||
const char* requiredInstanceExtensions[] = {
|
||||
@@ -38,15 +49,8 @@ Driver* PlatformVkLinuxWayland::createDriver(void* const sharedContext, const Pl
|
||||
sizeof(requiredInstanceExtensions) / sizeof(requiredInstanceExtensions[0]), driverConfig);
|
||||
}
|
||||
|
||||
void* PlatformVkLinuxWayland::createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept {
|
||||
|
||||
typedef struct _wl {
|
||||
struct wl_display *display;
|
||||
struct wl_surface *surface;
|
||||
} wl;
|
||||
|
||||
VkSurfaceKHR surface = nullptr;
|
||||
|
||||
SurfaceBundle PlatformVkLinuxWayland::createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept {
|
||||
wl* ptrval = reinterpret_cast<wl*>(nativeWindow);
|
||||
|
||||
VkWaylandSurfaceCreateInfoKHR createInfo = {
|
||||
@@ -56,11 +60,15 @@ void* PlatformVkLinuxWayland::createVkSurfaceKHR(void* nativeWindow, void* insta
|
||||
.display = ptrval->display,
|
||||
.surface = ptrval->surface
|
||||
};
|
||||
|
||||
VkResult result = vkCreateWaylandSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC, &surface);
|
||||
SurfaceBundle bundle {
|
||||
.surface = VK_NULL_HANDLE,
|
||||
.width = ptrval->width,
|
||||
.height = ptrval->height
|
||||
};
|
||||
VkResult result = vkCreateWaylandSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC,
|
||||
(VkSurfaceKHR*) &bundle.surface);
|
||||
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateWaylandSurfaceKHR error.");
|
||||
|
||||
return surface;
|
||||
return bundle;
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -30,7 +30,8 @@ public:
|
||||
|
||||
Driver* createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
|
||||
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept override;
|
||||
|
||||
int getOSVersion() const noexcept override { return 0; }
|
||||
};
|
||||
|
||||
@@ -29,6 +29,8 @@ using namespace bluevk;
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
|
||||
|
||||
static constexpr const char* LIBRARY_X11 = "libX11.so.6";
|
||||
|
||||
#ifdef FILAMENT_SUPPORTS_XCB
|
||||
@@ -50,7 +52,8 @@ struct X11Functions {
|
||||
void* library = nullptr;
|
||||
} g_x11;
|
||||
|
||||
Driver* PlatformVkLinuxX11::createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
Driver* PlatformVkLinuxX11::createDriver(void* const sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept {
|
||||
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
|
||||
const char* requiredInstanceExtensions[] = {
|
||||
#ifdef FILAMENT_SUPPORTS_XCB
|
||||
@@ -64,7 +67,8 @@ Driver* PlatformVkLinuxX11::createDriver(void* const sharedContext, const Platfo
|
||||
sizeof(requiredInstanceExtensions) / sizeof(requiredInstanceExtensions[0]), driverConfig);
|
||||
}
|
||||
|
||||
void* PlatformVkLinuxX11::createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept {
|
||||
SurfaceBundle PlatformVkLinuxX11::createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept {
|
||||
if (g_x11.library == nullptr) {
|
||||
g_x11.library = dlopen(LIBRARY_X11, RTLD_LOCAL | RTLD_NOW);
|
||||
ASSERT_PRECONDITION(g_x11.library, "Unable to open X11 library.");
|
||||
@@ -85,7 +89,11 @@ void* PlatformVkLinuxX11::createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
|
||||
}
|
||||
|
||||
VkSurfaceKHR surface = nullptr;
|
||||
SurfaceBundle bundle {
|
||||
.surface = nullptr,
|
||||
.width = 0,
|
||||
.height = 0
|
||||
};
|
||||
|
||||
#ifdef FILAMENT_SUPPORTS_XCB
|
||||
#ifdef FILAMENT_SUPPORTS_XLIB
|
||||
@@ -101,8 +109,9 @@ const bool windowIsXCB = true;
|
||||
.connection = mConnection,
|
||||
.window = (xcb_window_t) ptrval,
|
||||
};
|
||||
vkCreateXcbSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC, &surface);
|
||||
return surface;
|
||||
vkCreateXcbSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC,
|
||||
(VkSurfaceKHR*) &bundle.surface);
|
||||
return bundle;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -112,10 +121,11 @@ const bool windowIsXCB = true;
|
||||
.dpy = mDisplay,
|
||||
.window = (Window) nativeWindow,
|
||||
};
|
||||
vkCreateXlibSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC, &surface);
|
||||
vkCreateXlibSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC,
|
||||
(VkSurfaceKHR*) &bundle.surface);
|
||||
#endif
|
||||
|
||||
return surface;
|
||||
return bundle;
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -37,7 +37,8 @@ public:
|
||||
|
||||
Driver* createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
|
||||
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept override;
|
||||
|
||||
int getOSVersion() const noexcept override { return 0; }
|
||||
|
||||
|
||||
@@ -27,15 +27,22 @@ using namespace bluevk;
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
Driver* PlatformVkWindows::createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
using SurfaceBundle = VulkanPlatform::SurfaceBundle;
|
||||
|
||||
Driver* PlatformVkWindows::createDriver(void* const sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept {
|
||||
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
|
||||
const char* requiredInstanceExtensions[] = { "VK_KHR_win32_surface" };
|
||||
return VulkanDriverFactory::create(this, requiredInstanceExtensions, 1, driverConfig);
|
||||
}
|
||||
|
||||
void* PlatformVkWindows::createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept {
|
||||
VkSurfaceKHR surface = nullptr;
|
||||
|
||||
SurfaceBundle PlatformVkWindows::createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept {
|
||||
SurfaceBundle bundle {
|
||||
.surface = nullptr,
|
||||
.width = 0,
|
||||
.height = 0
|
||||
};
|
||||
HWND window = (HWND) nativeWindow;
|
||||
|
||||
VkWin32SurfaceCreateInfoKHR createInfo = {};
|
||||
@@ -43,10 +50,11 @@ void* PlatformVkWindows::createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
createInfo.hwnd = window;
|
||||
createInfo.hinstance = GetModuleHandle(nullptr);
|
||||
|
||||
VkResult result = vkCreateWin32SurfaceKHR((VkInstance) instance, &createInfo, nullptr, &surface);
|
||||
VkResult result = vkCreateWin32SurfaceKHR((VkInstance) instance, &createInfo, nullptr,
|
||||
(VkSurfaceKHR*) &bundle.surface);
|
||||
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateWin32SurfaceKHR error.");
|
||||
|
||||
return surface;
|
||||
return bundle;
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -29,7 +29,8 @@ public:
|
||||
|
||||
Driver* createDriver(void* const sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
|
||||
VulkanPlatform::SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept override;
|
||||
|
||||
int getOSVersion() const noexcept override { return 0; }
|
||||
|
||||
|
||||
@@ -395,9 +395,14 @@ void VulkanDriver::createSyncR(Handle<HwSync> sh, int) {
|
||||
|
||||
void VulkanDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow, uint64_t flags) {
|
||||
const VkInstance instance = mContext.instance;
|
||||
auto vksurface = (VkSurfaceKHR) mContextManager.createVkSurfaceKHR(nativeWindow, instance,
|
||||
flags);
|
||||
construct<VulkanSwapChain>(sch, mContext, mStagePool, vksurface);
|
||||
auto bundle = mContextManager.createVkSurfaceKHR(nativeWindow, instance, flags);
|
||||
VkSurfaceKHR surface = (VkSurfaceKHR) bundle.surface;
|
||||
VkExtent2D fallback{bundle.width, bundle.height};
|
||||
if (fallback.width > 0 && fallback.height > 0) {
|
||||
construct<VulkanSwapChain>(sch, mContext, mStagePool, surface, fallback);
|
||||
} else {
|
||||
construct<VulkanSwapChain>(sch, mContext, mStagePool, surface);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanDriver::createSwapChainHeadlessR(Handle<HwSwapChain> sch,
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
using namespace bluevk;
|
||||
using namespace utils;
|
||||
|
||||
namespace {
|
||||
constexpr uint32_t VULKAN_UNDEFINED_EXTENT = 0xFFFFFFFF;
|
||||
} // anonymous namespace
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
bool VulkanSwapChain::acquire() {
|
||||
@@ -127,8 +131,12 @@ void VulkanSwapChain::create(VulkanStagePool& stagePool) {
|
||||
ASSERT_POSTCONDITION(foundSuitablePresentMode, "Desired present mode is not supported by this device.");
|
||||
|
||||
// Create the low-level swap chain.
|
||||
|
||||
clientSize = caps.currentExtent;
|
||||
if (caps.currentExtent.width == VULKAN_UNDEFINED_EXTENT ||
|
||||
caps.currentExtent.height == VULKAN_UNDEFINED_EXTENT) {
|
||||
clientSize = mFallbackExtent;
|
||||
} else {
|
||||
clientSize = caps.currentExtent;
|
||||
}
|
||||
|
||||
const VkCompositeAlphaFlagBitsKHR compositeAlpha = (caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) ?
|
||||
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR : VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
@@ -297,8 +305,10 @@ static void getPresentationQueue(VulkanContext& mContext, VulkanSwapChain& sc) {
|
||||
}
|
||||
|
||||
// Primary SwapChain constructor. (not headless)
|
||||
VulkanSwapChain::VulkanSwapChain(VulkanContext& context, VulkanStagePool& stagePool, VkSurfaceKHR vksurface) :
|
||||
mContext(context) {
|
||||
VulkanSwapChain::VulkanSwapChain(VulkanContext& context, VulkanStagePool& stagePool, VkSurfaceKHR vksurface,
|
||||
VkExtent2D fallbackExtent) :
|
||||
mContext(context),
|
||||
mFallbackExtent(fallbackExtent) {
|
||||
suboptimal = false;
|
||||
surface = vksurface;
|
||||
firstRenderPass = true;
|
||||
@@ -341,9 +351,15 @@ bool VulkanSwapChain::hasResized() const {
|
||||
if (surface == VK_NULL_HANDLE) {
|
||||
return false;
|
||||
}
|
||||
VkSurfaceCapabilitiesKHR surfaceCapabilities;
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mContext.physicalDevice, surface, &surfaceCapabilities);
|
||||
return !equivalent(clientSize, surfaceCapabilities.currentExtent);
|
||||
VkSurfaceCapabilitiesKHR caps;
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mContext.physicalDevice, surface, &caps);
|
||||
VkExtent2D perceivedExtent = caps.currentExtent;
|
||||
// Create the low-level swap chain.
|
||||
if (caps.currentExtent.width == VULKAN_UNDEFINED_EXTENT ||
|
||||
caps.currentExtent.height == VULKAN_UNDEFINED_EXTENT) {
|
||||
perceivedExtent = mFallbackExtent;
|
||||
}
|
||||
return !equivalent(clientSize, perceivedExtent);
|
||||
}
|
||||
|
||||
VulkanTexture& VulkanSwapChain::getColorTexture() {
|
||||
|
||||
@@ -28,10 +28,14 @@ namespace filament::backend {
|
||||
|
||||
|
||||
struct VulkanSwapChain : public HwSwapChain {
|
||||
VulkanSwapChain(VulkanContext& context, VulkanStagePool& stagePool, VkSurfaceKHR vksurface);
|
||||
// The *fallbackExtent* parameter is for the case where the extent returned by the physical
|
||||
// surface is 0xFFFFFFFF.
|
||||
VulkanSwapChain(VulkanContext& context, VulkanStagePool& stagePool, VkSurfaceKHR vksurface,
|
||||
VkExtent2D fallbackExtent={.width=640, .height=320});
|
||||
|
||||
// Headless constructor.
|
||||
VulkanSwapChain(VulkanContext& context, VulkanStagePool& stagePool, uint32_t width, uint32_t height);
|
||||
VulkanSwapChain(VulkanContext& context, VulkanStagePool& stagePool, uint32_t width,
|
||||
uint32_t height);
|
||||
|
||||
bool acquire();
|
||||
void create(VulkanStagePool& stagePool);
|
||||
@@ -63,6 +67,7 @@ struct VulkanSwapChain : public HwSwapChain {
|
||||
private:
|
||||
VulkanContext& mContext;
|
||||
uint32_t mCurrentSwapIndex = 0u;
|
||||
const VkExtent2D mFallbackExtent = {};
|
||||
|
||||
// Color attachments are swapped, but depth is not. Typically there are 2 or 3 color attachments
|
||||
// in a swap chain.
|
||||
|
||||
@@ -32,15 +32,23 @@ void* getNativeWindow(SDL_Window* sdlWindow) {
|
||||
}
|
||||
else if (wmi.subsystem == SDL_SYSWM_WAYLAND) {
|
||||
#if defined(FILAMENT_SUPPORTS_WAYLAND)
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
SDL_GetWindowSize(sdlWindow, &width, &height);
|
||||
|
||||
// Static is used here to allocate the struct pointer for the lifetime of the program.
|
||||
// Without static the valid struct quickyly goes out of scope, and ends with seemingly
|
||||
// random segfaults.
|
||||
static struct {
|
||||
struct wl_display *display;
|
||||
struct wl_surface *surface;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} wayland {
|
||||
wmi.info.wl.display,
|
||||
wmi.info.wl.surface,
|
||||
static_cast<uint32_t>(width),
|
||||
static_cast<uint32_t>(height)
|
||||
};
|
||||
return (void *) &wayland;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user