Changed vulkan startup order 35/318835/1
authorDavid Steele <david.steele@samsung.com>
Wed, 9 Oct 2024 17:23:26 +0000 (18:23 +0100)
committerDavid Steele <david.steele@samsung.com>
Wed, 9 Oct 2024 17:25:29 +0000 (18:25 +0100)
Instead of creating a physical device, then creating a surface
and asserting if that device can't support the surface,
creates the vulkan surface, and checks against each device to see
if that surface can be presented.

Change-Id: I25c22c6068b2e91f3f7e49cd509c52adcf7cef12
Signed-off-by: David Steele <david.steele@samsung.com>
12 files changed:
dali/internal/graphics/vulkan/vulkan-device.cpp
dali/internal/graphics/vulkan/vulkan-device.h
dali/internal/graphics/vulkan/vulkan-graphics-impl.cpp
dali/internal/graphics/vulkan/vulkan-surface-factory.h
dali/internal/graphics/vulkan/wayland/vk-surface-wayland.cpp
dali/internal/graphics/vulkan/wayland/vk-surface-wayland.h
dali/internal/graphics/vulkan/x11/vk-surface-xcb.cpp
dali/internal/graphics/vulkan/x11/vk-surface-xcb.h
dali/internal/graphics/vulkan/x11/vk-surface-xlib.cpp
dali/internal/graphics/vulkan/x11/vk-surface-xlib.h
dali/internal/graphics/vulkan/x11/vk-surface-xlib2xcb.cpp
dali/internal/graphics/vulkan/x11/vk-surface-xlib2xcb.h

index 5065b96687118a1941fc40128714b3afbe038b72..98f22b9fa30f7d70ec662bd1405ef6505c4b2a0a 100644 (file)
@@ -128,11 +128,12 @@ void Device::Create()
   }
 
   CreateInstance(extensions, validationLayers);
-  PreparePhysicalDevice();
 }
 
-void Device::CreateDevice()
+void Device::CreateDevice(SurfaceImpl* surface)
 {
+  PreparePhysicalDevice(surface);
+
   auto queueInfos = GetQueueCreateInfos();
   {
     auto maxQueueCountPerFamily = 0u;
@@ -236,12 +237,15 @@ Graphics::SurfaceId Device::CreateSurface(
   }
 
   // create surface from the factory
-  auto* surface = new SurfaceImpl(*this, vulkanSurfaceFactory->Create(mInstance, mAllocator.get(), mPhysicalDevice));
+  auto* surface = new SurfaceImpl(*this, vulkanSurfaceFactory->Create(mInstance, mAllocator.get()));
   if(!surface->GetVkHandle())
   {
     return -1;
   }
 
+  // Find a device that can support this surface.
+  CreateDevice(surface);
+
   VkBool32 supported(VK_FALSE);
   for(auto i = 0u; i < mQueueFamilyProperties.size(); ++i)
   {
@@ -251,7 +255,6 @@ Graphics::SurfaceId Device::CreateSurface(
       break;
     }
   }
-
   assert(supported && "There is no queue family supporting presentation!");
 
   surface->GetCapabilities() = VkAssert(mPhysicalDevice.getSurfaceCapabilitiesKHR(surface->GetVkHandle()));
@@ -614,7 +617,7 @@ void Device::DestroyInstance()
   }
 }
 
-void Device::PreparePhysicalDevice()
+void Device::PreparePhysicalDevice(SurfaceImpl* surface)
 {
   auto devices = VkAssert(mInstance.enumeratePhysicalDevices());
   assert(!devices.empty() && "No Vulkan supported device found!");
@@ -627,6 +630,8 @@ void Device::PreparePhysicalDevice()
   }
   else // otherwise look for one which is a graphics device
   {
+    auto vkSurface = surface->GetVkHandle();
+
     for(auto& device : devices)
     {
       auto properties = device.getProperties();
@@ -634,13 +639,20 @@ void Device::PreparePhysicalDevice()
          properties.deviceType == vk::PhysicalDeviceType::eIntegratedGpu)
       {
         auto queueFamilyProperties = device.getQueueFamilyProperties();
+        int  queueIndex            = 0;
         for(const auto& queueFamily : queueFamilyProperties)
         {
           if(queueFamily.queueFlags & vk::QueueFlagBits::eGraphics)
           {
-            mPhysicalDevice = device;
-            break;
+            VkBool32 presentSupported = false;
+            auto     result           = device.getSurfaceSupportKHR(queueIndex, vkSurface, &presentSupported);
+            if((result == vk::Result::eSuccess) && presentSupported)
+            {
+              mPhysicalDevice = device;
+              break;
+            }
           }
+          ++queueIndex;
         }
       }
     }
index e40de4b167594800420faee06884ba3b6dcf5918..04edf83097810d1aea4106f86ede8069c275b4fe 100644 (file)
@@ -62,7 +62,7 @@ public:
 public: // Create methods
   void Create();
 
-  void CreateDevice();
+  void CreateDevice(SurfaceImpl* surface);
 
   Graphics::SurfaceId CreateSurface(Dali::Graphics::SurfaceFactory&           surfaceFactory,
                                     const Dali::Graphics::GraphicsCreateInfo& createInfo);
@@ -143,7 +143,7 @@ private: // Methods
 
   void DestroyInstance();
 
-  void PreparePhysicalDevice();
+  void PreparePhysicalDevice(SurfaceImpl* surface);
 
   void GetPhysicalDeviceProperties();
 
index e9680d745ce033bb9bfa51f7bfefec13df6f69b1..8cdef2a73312d40280dcf7e427a43de9e0f2d77b 100644 (file)
@@ -44,9 +44,6 @@ void VulkanGraphics::Initialize(const Dali::DisplayConnection& displayConnection
 {
   // Pass down depth/stencil req, partial rendering & msaa level
   mGraphicsDevice.Create();
-  mGraphicsDevice.CreateDevice();
-
-  // Create DescriptorSetAllocator
 
   mGraphicsController.Initialize(*this, mGraphicsDevice);
   InitializeGraphicsAPI(displayConnection);
@@ -84,7 +81,8 @@ Graphics::SurfaceId VulkanGraphics::CreateSurface(
   int                            width,
   int                            height)
 {
-  // create surface ( also takes surface factory ownership )
+  // create surface ( also takes surface factory ownership ),
+  // and find viable vulkan device.
   auto createInfo          = mCreateInfo;
   createInfo.surfaceWidth  = width;
   createInfo.surfaceHeight = height;
index c9220b57999e6c8ffabd982c2684bcd8037a55e3..ce62d082afebadd46975392a3a7c03760855f050 100644 (file)
@@ -30,12 +30,10 @@ namespace Dali::Graphics::Vulkan
 class SurfaceFactory : public Dali::Graphics::SurfaceFactory
 {
 public:
-
   SurfaceFactory() = default;
 
-  virtual vk::SurfaceKHR Create( vk::Instance instance,
-                                 const vk::AllocationCallbacks* allocCallbacks,
-                                 vk::PhysicalDevice physicalDevice ) const = 0;
+  virtual vk::SurfaceKHR Create(vk::Instance                   instance,
+                                const vk::AllocationCallbacks* allocCallbacks) const = 0;
 };
 
 } // namespace Dali::Graphics::Vulkan
index 2025f27390c27078813e46b7e52e70731fb7258b..11d76e5978734529d5a69f598e1909a406b338f2 100644 (file)
@@ -45,17 +45,17 @@ namespace Graphics
 namespace Vulkan
 {
 
-VkSurfaceWayland::VkSurfaceWayland( NativeWindowInterface& nativeWindow )
+VkSurfaceWayland::VkSurfaceWayland(NativeWindowInterface& nativeWindow)
 : SurfaceFactory()
 {
 #ifdef ECORE_WAYLAND2
-  Ecore_Wl2_Window *ecoreWl2Window = AnyCast< Ecore_Wl2_Window* >(nativeWindow.GetNativeWindow());
-  w_surface = ecore_wl2_window_surface_get(ecoreWl2Window);
+  Ecore_Wl2_Window* ecoreWl2Window = AnyCast<Ecore_Wl2_Window*>(nativeWindow.GetNativeWindow());
+  w_surface                        = ecore_wl2_window_surface_get(ecoreWl2Window);
 
   Ecore_Wl2_Display* wl2_display = ecore_wl2_window_display_get(ecoreWl2Window);
-  w_display = ecore_wl2_display_get(wl2_display);
+  w_display                      = ecore_wl2_display_get(wl2_display);
 #else
-  Ecore_Wl_Window* ecoreWlWindow = AnyCast< Ecore_Wl_Window* >(nativeWindow.GetNativeWindow());
+  Ecore_Wl_Window* ecoreWlWindow = AnyCast<Ecore_Wl_Window*>(nativeWindow.GetNativeWindow());
 
   w_surface = ecore_wl_window_surface_get(ecoreWlWindow);
   w_display = ecore_wl_display_get();
@@ -69,11 +69,9 @@ VkSurfaceWayland::VkSurfaceWayland(::wl_display* display, ::wl_surface* surface)
   w_surface = surface;
 }
 
-
 vk::SurfaceKHR VkSurfaceWayland::Create(
-  vk::Instance instance,
-  const vk::AllocationCallbacks* allocCallbacks,
-  vk::PhysicalDevice physicalDevice) const
+  vk::Instance                   instance,
+  const vk::AllocationCallbacks* allocCallbacks) const
 {
   vk::WaylandSurfaceCreateInfoKHR info;
 
@@ -85,15 +83,15 @@ vk::SurfaceKHR VkSurfaceWayland::Create(
   return retval;
 }
 
-} // Vulkan
+} // namespace Vulkan
 
-std::unique_ptr<SurfaceFactory> SurfaceFactory::New( NativeWindowInterface& nativeWindow )
+std::unique_ptr<SurfaceFactory> SurfaceFactory::New(NativeWindowInterface& nativeWindow)
 {
-  auto surfaceFactory = std::unique_ptr<Graphics::Vulkan::VkSurfaceWayland>( new Graphics::Vulkan::VkSurfaceWayland( nativeWindow ) );
+  auto surfaceFactory = std::unique_ptr<Graphics::Vulkan::VkSurfaceWayland>(new Graphics::Vulkan::VkSurfaceWayland(nativeWindow));
   return surfaceFactory;
 }
 
-} // Graphics
-} // Dali
+} // namespace Graphics
+} // namespace Dali
 
 #pragma GCC diagnostic pop
index 00c7a1e1dd5e0f79807a42e0f2e26e22242b3ba2..8280111a25967a9dc40fb5ba212bd301fb1bdbc1 100644 (file)
 // INTERNAL INCLUDES
 #include <dali/internal/graphics/vulkan/vulkan-surface-factory.h>
 
-
 // EXTERNAL INCLUDES
 #include <vulkan/vulkan.hpp>
 
-
 namespace Dali
 {
 class RenderSurface;
@@ -41,18 +39,17 @@ namespace Vulkan
 class VkSurfaceWayland final : public SurfaceFactory
 {
 public:
-
   VkSurfaceWayland(NativeWindowInterface& renderSurface);
 
   VkSurfaceWayland(::wl_display* display, ::wl_surface* surface);
 
-  virtual vk::SurfaceKHR Create(vk::Instance instance, const vk::AllocationCallbacks* allocCallbacks,
-                                vk::PhysicalDevice physicalDevice) const override;
-
+  virtual vk::SurfaceKHR Create(
+    vk::Instance                   instance,
+    const vk::AllocationCallbacks* allocCallbacks) const override;
 
 private:
-  wl_display *w_display;
-  wl_surface *w_surface;
+  wl_displayw_display;
+  wl_surfacew_surface;
 };
 
 } // Namespace Vulkan
index be8fff73d843508fe812ea87c6f9c61436c843ab..d56f571841ce3d90dac3e42248e0cd16ce879e96 100644 (file)
@@ -21,9 +21,9 @@
 
 #include <dali/graphics/vulkan/x11/vk-surface-xcb.h>
 
+#include <X11/Xlib-xcb.h>
 #include <dali/integration-api/render-surface.h>
 #include <dali/internal/window-system/common/window-render-surface.h>
-#include <X11/Xlib-xcb.h>
 
 namespace Dali
 {
@@ -32,15 +32,15 @@ namespace Graphics
 namespace Vulkan
 {
 
-VkSurfaceXcb::VkSurfaceXcb( NativeWindowInterface& nativeWindow )
+VkSurfaceXcb::VkSurfaceXcb(NativeWindowInterface& nativeWindow)
 : SurfaceFactory{}
 {
-  mConnection = XGetXCBConnection( XOpenDisplay(nullptr) );
-  mWindow = static_cast<decltype( mWindow )>( nativeWindow.GetNativeWindowId() );
+  mConnection = XGetXCBConnection(XOpenDisplay(nullptr));
+  mWindow     = static_cast<decltype(mWindow)>(nativeWindow.GetNativeWindowId());
 }
 
-vk::SurfaceKHR VkSurfaceXcb::Create( vk::Instance instance, const vk::AllocationCallbacks* allocCallbacks,
-                                     vk::PhysicalDevice physicalDevice) const
+vk::SurfaceKHR VkSurfaceXcb::Create(vk::Instance                   instance,
+                                    const vk::AllocationCallbacks* allocCallbacks) const
 {
   vk::XcbSurfaceCreateInfoKHR info;
   info.setConnection(mConnection).setWindow(mWindow);
@@ -48,15 +48,15 @@ vk::SurfaceKHR VkSurfaceXcb::Create( vk::Instance instance, const vk::Allocation
   return retval;
 }
 
-} // Vulkan
+} // namespace Vulkan
 
-std::unique_ptr<SurfaceFactory> SurfaceFactory::New( NativeWindowInterface& nativeWindow )
+std::unique_ptr<SurfaceFactory> SurfaceFactory::New(NativeWindowInterface& nativeWindow)
 {
-  auto surfaceFactory = std::unique_ptr<Graphics::Vulkan::VkSurfaceXcb>( new Graphics::Vulkan::VkSurfaceXcb( nativeWindow ) );
+  auto surfaceFactory = std::unique_ptr<Graphics::Vulkan::VkSurfaceXcb>(new Graphics::Vulkan::VkSurfaceXcb(nativeWindow));
   return surfaceFactory;
 }
 
-} // Graphics
-} // Dali
+} // namespace Graphics
+} // namespace Dali
 
 #pragma GCC diagnostic pop
index d9408048e1858fb1974712de2cc26ac0ffac8655..390bdce6ab8eca25332c190db71a16b2ab5f5133 100644 (file)
@@ -22,8 +22,8 @@
 #endif
 
 // INTERNAL INCLUDES
-#include <dali/internal/graphics/vulkan/vulkan-surface-factory.h>
 #include <dali/internal/graphics/vulkan/vulkan-hpp-wrapper.h>
+#include <dali/internal/graphics/vulkan/vulkan-surface-factory.h>
 
 namespace Dali
 {
@@ -39,10 +39,10 @@ public:
    * Instantiates surface factory
    * @param[in] renderSurface
    */
-  VkSurfaceXcb( NativeWindowInterface& nativeWindow );
+  VkSurfaceXcb(NativeWindowInterface& nativeWindow);
 
-  virtual vk::SurfaceKHR Create( vk::Instance instance, const vk::AllocationCallbacks* allocCallbacks,
-                                 vk::PhysicalDevice physicalDevice) const override;
+  virtual vk::SurfaceKHR Create(vk::Instance                   instance,
+                                const vk::AllocationCallbacks* allocCallbacks) const override;
 
 private:
   xcb_connection_t* mConnection;
index 74701c4fb01ac9a294381d0b32bf3850cdb1593b..5fbfd4f3f78a8a7e86704df3459b6b4f2c0e23f1 100644 (file)
@@ -30,33 +30,32 @@ namespace Graphics
 namespace Vulkan
 {
 
-VkSurfaceXlib::VkSurfaceXlib( Dali::RenderSurface& renderSurface )
+VkSurfaceXlib::VkSurfaceXlib(Dali::RenderSurface& renderSurface)
 : SurfaceFactory()
 {
-  auto ecoreSurface = dynamic_cast< Dali::Internal::Adaptor::WindowRenderSurface* >( &renderSurface );
-  assert( ecoreSurface != nullptr && "This is not ecore surface!");
-  mWindow = ecoreSurface->GetNativeWindowId();
-  mDisplay = XOpenDisplay( nullptr );
+  auto ecoreSurface = dynamic_cast<Dali::Internal::Adaptor::WindowRenderSurface*>(&renderSurface);
+  assert(ecoreSurface != nullptr && "This is not ecore surface!");
+  mWindow  = ecoreSurface->GetNativeWindowId();
+  mDisplay = XOpenDisplay(nullptr);
 }
 
-vk::SurfaceKHR VkSurfaceXlib::Create( vk::Instance instance, const vk::AllocationCallbacks* allocCallbacks,
-                                      vk::PhysicalDevice physicalDevice ) const
+vk::SurfaceKHR VkSurfaceXlib::Create(vk::Instance instance, const vk::AllocationCallbacks* allocCallbacks) const
 {
   vk::XlibSurfaceCreateInfoKHR info;
-  info.setDpy( mDisplay ).setWindow( mWindow );
-  auto retval = instance.createXlibSurfaceKHR( info, allocCallbacks ).value;
+  info.setDpy(mDisplay).setWindow(mWindow);
+  auto retval = instance.createXlibSurfaceKHR(info, allocCallbacks).value;
   return retval;
 }
 
-} // Vulkan
+} // namespace Vulkan
 
 std::unique_ptr<SurfaceFactory> SurfaceFactory::New(Dali::RenderSurface& renderSurface)
 {
-  auto surfaceFactory = std::unique_ptr<Graphics::Vulkan::VkSurfaceXlib>( new Graphics::Vulkan::VkSurfaceXlib( renderSurface ) );
+  auto surfaceFactory = std::unique_ptr<Graphics::Vulkan::VkSurfaceXlib>(new Graphics::Vulkan::VkSurfaceXlib(renderSurface));
   return surfaceFactory;
 }
 
-} // Graphics
-} // Dali
+} // namespace Graphics
+} // namespace Dali
 
 #pragma GCC diagnostic pop
index 417ed1f3c85bf4f14f6bdf2278cb58ad0f61645a..7f726b5144a44560de49da466cbbcdc3d16e09d3 100644 (file)
@@ -23,8 +23,8 @@
 #endif
 
 // INTERNAL INCLUDES
-#include <dali/internal/graphics/vulkan/vulkan-surface-factory.h>
 #include <dali/internal/graphics/vulkan/vulkan-hpp-wrapper.h>
+#include <dali/internal/graphics/vulkan/vulkan-surface-factory.h>
 
 namespace Dali
 {
@@ -38,10 +38,9 @@ namespace Vulkan
 class VkSurfaceXlib final : public SurfaceFactory
 {
 public:
-  VkSurfaceXlib( Dali::RenderSurface& renderSurface );
+  VkSurfaceXlib(Dali::RenderSurface& renderSurface);
 
-  virtual vk::SurfaceKHR Create( vk::Instance instance, const vk::AllocationCallbacks* allocCallbacks,
-                                 vk::PhysicalDevice physicalDevice ) const override;
+  virtual vk::SurfaceKHR Create(vk::Instance instance, const vk::AllocationCallbacks* allocCallbacks) const override;
 
 private:
   Display*       mDisplay;
index 99f24d6fa7d2bac5d227d60302fc85606c5a3d24..93c465b550ee803082b7851f628b3bf53246f780 100644 (file)
@@ -44,7 +44,7 @@ VkSurfaceXlib2Xcb::VkSurfaceXlib2Xcb(::Display* display, ::Window window)
   mWindow     = static_cast<decltype(mWindow)>(window);
 }
 
-vk::SurfaceKHR VkSurfaceXlib2Xcb::Create(vk::Instance instance, const vk::AllocationCallbacks* allocCallbacks, vk::PhysicalDevice physicalDevice) const
+vk::SurfaceKHR VkSurfaceXlib2Xcb::Create(vk::Instance instance, const vk::AllocationCallbacks* allocCallbacks) const
 {
   vk::XcbSurfaceCreateInfoKHR info;
   info.setConnection(mConnection).setWindow(mWindow);
index 6d47cf9a3832c9047153bfca1dab2e17c181cb1f..ab93415b95ac3174f1ea38990c4f46feb189686e 100644 (file)
@@ -49,7 +49,7 @@ public:
 
   VkSurfaceXlib2Xcb(::Display* display, ::Window window);
 
-  virtual vk::SurfaceKHR Create(vk::Instance instance, const vk::AllocationCallbacks* allocCallbacks, vk::PhysicalDevice physicalDevice) const override;
+  virtual vk::SurfaceKHR Create(vk::Instance instance, const vk::AllocationCallbacks* allocCallbacks) const override;
 
 private:
   xcb_connection_t* mConnection;