Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JBR-7237 Fix cyclic dependency of Wayland and Vulkan initialization #396

Merged
merged 3 commits into from
Jun 14, 2024

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
@@ -543,6 +550,16 @@ jboolean VK_FindDevices() {
geInstance->vkGetPhysicalDeviceQueueFamilyProperties(
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.

@@ -741,6 +744,8 @@ Java_sun_awt_wl_WLToolkit_initIDs
(JNIEnv *env, jclass clazz)
{
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.

@@ -741,6 +744,8 @@ Java_sun_awt_wl_WLToolkit_initIDs
(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.

@@ -44,14 +44,16 @@ static const uint32_t REQUIRED_VULKAN_VERSION = VK_MAKE_API_VERSION(0, 1, 2, 0);
#define VALIDATION_LAYER_NAME "VK_LAYER_KHRONOS_validation"
#define COUNT_OF(x) (sizeof(x)/sizeof(x[0]))
#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 mkartashev and avu 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
@@ -44,14 +44,13 @@ static const uint32_t REQUIRED_VULKAN_VERSION = VK_MAKE_API_VERSION(0, 1, 2, 0);
#define VALIDATION_LAYER_NAME "VK_LAYER_KHRONOS_validation"
#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.

@@ -44,14 +44,13 @@ static const uint32_t REQUIRED_VULKAN_VERSION = VK_MAKE_API_VERSION(0, 1, 2, 0);
#define VALIDATION_LAYER_NAME "VK_LAYER_KHRONOS_validation"
#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 Nov 26, 2024
mkartashev pushed a commit that referenced this pull request Nov 27, 2024
vprovodin pushed a commit that referenced this pull request Nov 28, 2024
vprovodin pushed a commit that referenced this pull request Nov 29, 2024
vprovodin pushed a commit that referenced this pull request Nov 30, 2024
vprovodin pushed a commit that referenced this pull request Dec 2, 2024
mkartashev pushed a commit that referenced this pull request Dec 3, 2024
mkartashev pushed a commit that referenced this pull request Dec 3, 2024
mkartashev pushed a commit that referenced this pull request Dec 3, 2024
vprovodin pushed a commit that referenced this pull request Dec 4, 2024
vprovodin pushed a commit that referenced this pull request Dec 5, 2024
vprovodin pushed a commit that referenced this pull request Dec 6, 2024
vprovodin pushed a commit that referenced this pull request Dec 7, 2024
vprovodin pushed a commit that referenced this pull request Dec 8, 2024
vprovodin pushed a commit that referenced this pull request Dec 9, 2024
mkartashev pushed a commit that referenced this pull request Dec 9, 2024
mkartashev pushed a commit that referenced this pull request Dec 9, 2024
mkartashev pushed a commit that referenced this pull request Dec 9, 2024
mkartashev pushed a commit that referenced this pull request Dec 9, 2024
mkartashev pushed a commit that referenced this pull request Dec 9, 2024
mkartashev pushed a commit that referenced this pull request Dec 9, 2024
mkartashev pushed a commit that referenced this pull request Dec 9, 2024
vprovodin pushed a commit that referenced this pull request Dec 10, 2024
NikitkoCent pushed a commit that referenced this pull request Dec 10, 2024
NikitkoCent pushed a commit that referenced this pull request Dec 10, 2024
vprovodin pushed a commit that referenced this pull request Dec 11, 2024
vprovodin pushed a commit that referenced this pull request Dec 12, 2024
vprovodin pushed a commit that referenced this pull request Dec 13, 2024
vprovodin pushed a commit that referenced this pull request Dec 14, 2024
vprovodin pushed a commit that referenced this pull request Dec 15, 2024
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