Skip to content

Conversation

@YaaZ
Copy link
Member

@YaaZ YaaZ commented May 31, 2024

This adds asynchronous Vulkan initialization.

  1. WLGraphicsEnvironment starts Vulkan initialization in separate thread and proceeds with Wayland initialization
  2. Before vkGetPhysicalDeviceWaylandPresentationSupportKHR Vulkan init waits for the wl_display to become available
  3. VKInstance.isVulkanEnabled() which is used later by WLGraphicsDevice waits for the Vulkan initialization to finish

@YaaZ YaaZ requested review from avu and mkartashev May 31, 2024 23:06
geInstance->physicalDevices[i], &queueFamilyCount, queueFamilies);
int64_t queueFamily = -1;
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
while (!wl_display_initialized) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you measure the performance gain from parallel initialization?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't because I made these changes to solve the cyclic dependency in the first place. Original solution just crashes, so I cannot measure real gain, but I can get a rough estimate.

{
wl_display = wl_display_connect(NULL);
wl_display_initialized = 1;
syscall(SYS_futex, &wl_display_initialized, FUTEX_WAKE_PRIVATE, INT_MAX, NULL, NULL, 0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you use such a kind of synchronization here? (there is only one place in hotspot where JDK use it)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDK, I just though futex is an easy, lightweight and already available tool for the case (waiting for the variable to change).

@@ -0,0 +1,76 @@
/*
* Copyright 2024 JetBrains s.r.o.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oracle copyright is also needed here.

final int deviceNumber = parsedDeviceNumber;
final boolean verbose = "True".equals(vulkanOption);
System.loadLibrary("awt");
new Thread(() -> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use InnocuousThread for all our JRE-internal threads.

(JNIEnv *env, jclass clazz)
{
wl_display = wl_display_connect(NULL);
wl_display_initialized = 1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to early to be certain that it was indeed initialized; wl_display could be NULL at this point.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but Vulkan initialization may already be waiting for the wl_display, so we need to notify it even if Wayland initialization failed. There is a null check in Vulkan code too.

#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
#include <sys/syscall.h>
#include <linux/futex.h>
extern volatile uint32_t wl_display_initialized;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When inter-thread synchronization is spread between the native and Java worlds it becomes especially hard to follow. Maybe we can stay within Java in this instance? By the time WLToolkit::initIDs() exits normally (i.e. not through an exception), the connection to the Wayland server is guaranteed to exist. Possibly this synchronization point can be placed there?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's why I asked about it. Also, we want to extend the Vulkan pipeline to windows, so it's better to have a more general synchronization mechanism.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the time WLToolkit::initIDs() exits normally, Vulkan should already be initialized, because it goes through initIDs->notifyOutputConfigured and creates a WLGraphicsDevice, which needs to know about the Vulkan support to create either WLVKGraphicsConfig, or WLSMGraphicsConfig. And Vulkan initialization needs a wl_display connection to query for presentation support, that's why the synchronization is placed here. This is only specific to Linux, as Windows does not depend on any external connection and therefore does not need such synchronization.

@mkartashev
Copy link
Collaborator

NB: we decided to split WLToolkit initialization in two phases so that the dependency of the toolkit initialization and Vulkan initialization on the Wayland display can be made apparent and easy to impose.
See #397 for the first part.

@YaaZ YaaZ force-pushed the ngubarkov/JBR-7237 branch from 05db8af to 7abdb89 Compare June 7, 2024 14:01
@YaaZ YaaZ requested review from avu and mkartashev June 7, 2024 14:02
@YaaZ YaaZ changed the title JBR-7237 Fix circular dependency of Wayland and Vulkan initialization JBR-7237 Fix cyclic dependency of Wayland and Vulkan initialization Jun 7, 2024
#define COUNT_OF(x) (sizeof(x)/sizeof(x[0]))
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
extern struct wl_display *wl_display;
static struct wl_display *wl_display;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name clashes with extern struct wl_display *wl_display declared in WLToolkit.c
Maybe rename this one with a different prefix?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's even better to put this info as a field into VKGraphicsEnvironment, it's already platform-dependent so one more field would not hurt.

Copy link
Collaborator

@avu avu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overal, LGTM. I think we'll get rid of global data later.

#define COUNT_OF(x) (sizeof(x)/sizeof(x[0]))
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
extern struct wl_display *wl_display;
static struct wl_display *wl_display;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's even better to put this info as a field into VKGraphicsEnvironment, it's already platform-dependent so one more field would not hurt.

@YaaZ YaaZ requested a review from avu June 14, 2024 09:39
Copy link
Collaborator

@avu avu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@YaaZ YaaZ merged commit 6d7f7c9 into jbr21 Jun 14, 2024
@YaaZ YaaZ deleted the ngubarkov/JBR-7237 branch June 14, 2024 10:22
vprovodin pushed a commit that referenced this pull request Sep 27, 2025
vprovodin pushed a commit that referenced this pull request Sep 28, 2025
vprovodin pushed a commit that referenced this pull request Sep 29, 2025
vprovodin pushed a commit that referenced this pull request Sep 30, 2025
vprovodin pushed a commit that referenced this pull request Oct 1, 2025
mkartashev pushed a commit that referenced this pull request Oct 1, 2025
mkartashev pushed a commit that referenced this pull request Oct 1, 2025
vprovodin pushed a commit that referenced this pull request Oct 2, 2025
vprovodin pushed a commit that referenced this pull request Oct 3, 2025
vprovodin pushed a commit that referenced this pull request Oct 4, 2025
vprovodin pushed a commit that referenced this pull request Oct 5, 2025
vprovodin pushed a commit that referenced this pull request Oct 6, 2025
vprovodin pushed a commit that referenced this pull request Oct 7, 2025
vprovodin pushed a commit that referenced this pull request Oct 8, 2025
vprovodin pushed a commit that referenced this pull request Oct 9, 2025
vprovodin pushed a commit that referenced this pull request Oct 10, 2025
vprovodin pushed a commit that referenced this pull request Oct 11, 2025
vprovodin pushed a commit that referenced this pull request Oct 12, 2025
vprovodin pushed a commit that referenced this pull request Oct 14, 2025
vprovodin pushed a commit that referenced this pull request Oct 15, 2025
OnePatchGuy pushed a commit that referenced this pull request Oct 15, 2025
vprovodin pushed a commit that referenced this pull request Oct 16, 2025
vprovodin pushed a commit that referenced this pull request Oct 17, 2025
vprovodin pushed a commit that referenced this pull request Oct 18, 2025
vprovodin pushed a commit that referenced this pull request Oct 19, 2025
vprovodin pushed a commit that referenced this pull request Oct 20, 2025
vprovodin pushed a commit that referenced this pull request Oct 21, 2025
vprovodin pushed a commit that referenced this pull request Oct 22, 2025
vprovodin pushed a commit that referenced this pull request Oct 23, 2025
YaaZ added a commit that referenced this pull request Oct 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants