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

Fix Vulkan Instance initialized twice in ProjectDialog #97006

Merged
merged 1 commit into from
Sep 18, 2024

Conversation

Gaktan
Copy link
Contributor

@Gaktan Gaktan commented Sep 14, 2024

Fixes #96722

I refactored a bit to be able to share as much code as possible with other systems that create a local device,

I first wanted to replace the create_local_rendering_device(), but since it's apparently used in GDScript, I did not know if it was possible to pass pointer reference arguments.

Note: this does not fix the leak that still exists in create_local_rendering_device(): #71003

@Gaktan Gaktan requested review from a team as code owners September 14, 2024 16:27
@Gaktan Gaktan force-pushed the project_dialog_vulkan_crash branch 3 times, most recently from 73db84b to fba7f18 Compare September 14, 2024 17:13
Comment on lines 34 to 39
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_context_driver_vulkan.h"
#endif
#if defined(METAL_ENABLED)
#include "drivers/metal/rendering_context_driver_metal.h"
#endif
Copy link
Member

@akien-mga akien-mga Sep 14, 2024

Choose a reason for hiding this comment

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

This is a pre-existing issue, so maybe not blocking, but these includes break code encapsulation. The generic / abstract servers code shouldn't need to access driver code, and instead have virtual methods that drivers can implement.

Also, nitpicking, but if those includes are needed for now, they should come after the block of core/servers includes, by convention.

Copy link
Contributor Author

@Gaktan Gaktan Sep 15, 2024

Choose a reason for hiding this comment

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

I'm trying to think of the best way to do this. Does it make sense to have this in the DisplayServer class?
Since the RenderServer doesn't have children class or API specific code.
I don't know the subtlety between the two classes. Does it even make sense for the RenderServer to have RenderingServer::create_local_rendering_device() to begin with ?

@clayjohn
Copy link
Member

I think this is too much complexity just to solve #96722.

The core issue in #96722 is that creating a RenderingDevice (not a local rendering device) crashes on certain hardware when a RenderingDevice has already been created. The solution is to add a check at the top of can_create_rendering_device() that checks if we are already using the Compatibility renderer. If we are, then it continues and attempts to create a RenderingDevice, if not, it does an early out and returns true.

@Gaktan
Copy link
Contributor Author

Gaktan commented Sep 16, 2024

That's fair.
Although what can_create_rendering_device() is doing is essentially the same steps as creating a local rendering device (literally the same code). I just took the opportunity to cleanup a bit and unify code

@clayjohn
Copy link
Member

That's fair. Although what can_create_rendering_device() is doing is essentially the same steps as creating a local rendering device (literally the same code). I just took the opportunity to cleanup a bit and unify code

Not exactly. can_create_rendering_device() doesn't create a local rendering device so the flow is very different. The new function also makes the user responsible for cleaning up the RenderingDevice and Context which is a big problem for a function like this.

Also, as a bonus, while looking at the code again, I realized that it can done very simply just by checking if the RenderingDevice singleton exists:

RenderingDevice *device = RenderingDevice::get_singleton();
if (device) {
	return true;
}

This is what create_local_rendering_device() does, which is why attempting to create one works for this PR.

@dhoverml
Copy link

@Gaktan can you please rebase?
I wanted to confirm that this fixes #96938, but I am getting a non-trivial merge conflict when I cherry pick.

@Gaktan
Copy link
Contributor Author

Gaktan commented Sep 17, 2024

@dhoverml Should be good now

@dhoverml
Copy link

Thanks @Gaktan .
It looks like the crash is fixed with this PR, however, creating new windows is very slow. It takes about 1 second to create a new window (click on + Create in the Project Manager, or open any menu in the editor when Single Window Mode is false).
I don't know if that is unrelated to this PR though.

@Gaktan
Copy link
Contributor Author

Gaktan commented Sep 17, 2024

@clayjohn I'll do the simple fix for now, and do the refactor in an other PR

Copy link
Member

@clayjohn clayjohn left a comment

Choose a reason for hiding this comment

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

Looks great, thank you!

@clayjohn
Copy link
Member

Thanks @Gaktan . It looks like the crash is fixed with this PR, however, creating new windows is very slow. It takes about 1 second to create a new window (click on + Create in the Project Manager, or open any menu in the editor when Single Window Mode is false). I don't know if that is unrelated to this PR though.

That's unrelated to this PR.

If you are on Windows you can improve the speed of opening new windows a lot by switching to D3D12 instead of Vulkan

@clayjohn
Copy link
Member

@clayjohn I'll do the simple fix for now, and do the refactor in an other PR

Sounds good!

@akien-mga akien-mga merged commit b103381 into godotengine:master Sep 18, 2024
20 checks passed
@akien-mga
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Crash in Project Dialog on Windows - Vulkan
4 participants