Call glGetGraphicsResetStatusKHR in wlr_renderer_begin to figure
out when a GPU reset occurs. Destroy the renderer when this
happens (the OpenGL context is defunct).
Allow to get whether has alpha channel of the VkImage, it can help an
optimization to disable blending when the texture doesn't have alpha.
Because the VkFormat isn't enough because it's always set to
VK_FORMAT_B8G8R8A8_SRGB or VK_FORMAT_R8G8B8A8_SRGB.
`modifiers` and `external_only` are never initialized, and free'd later. This
commit explicitly initializes them to NULL to prevent segfaults on `free()`
It's not safe to destroy any resources which might still be in-use
by the GPU. Wait for any asynchronous tasks to complete before
destroying everything.
Before re-using a VkCommandBuffer, we need to wait for its
operations to complete. Right now we unconditionally wait for
rendering to complete in vulkan_end(), however we have plans to
fix this [1]. To fully avoid blocking, we need to handle multiple
command buffers in flight at the same time (e.g. for multi-output,
or for rendering followed by texture uploads).
Implement a pool of command buffers. When we need to render, we
pick a command buffer from the pool which has completed its
operations. If we don't find one, try to allocate a new command
buffer. If we don't have slots in the pool anymore, block like we
did before.
[1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3574
Up until now we were using a VkFence for GPU-to-CPU
synchronization. This has some limitations that become a blocker
when trying to have multiple command buffers in flight at once
(e.g. for multi-output). It's desirable to implement a command
buffer pool [1], but VkFence cannot be used to track command buffer
completion for individual subpasses.
Let's just switch to timeline semaphores [2], which fix this issue,
make synchronization a lot more ergonomic and are a core Vulkan 1.2
feature.
[1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3802
[2]: https://www.khronos.org/blog/vulkan-timeline-semaphores
If NULL is returned by vkGetDeviceProcAddr(), either the driver
is buggy, either the wlroots code is buggy. For a valid device and
command name, drivers are not allowed to return NULL per the spec.
This mirrors what the GLES2 renderer does in load_gl_proc().
Added wlr_vk_renderer_get_* functions to allow get the VkInstance,
VkPhysicalDevice, VkDevice, queue family of a wlr_vk_renderer.
Added wlr_vk_renderer_get_current_image_attribs function to allow get
the VkImage of current renderer buffer to use on compositors.
Added wlr_renderer_is_vk function, it's like the wlr_renderer_is_gles2,
returns true if the wlr_renderer is a wlr_vk_renderer.
Added wlr_vk_image_get_attribs function to get a VkImage and it's
extras information (e.g. a VkImageLayout and VkImageFormat of the
VkImage) from a wlr_texture.
Instead of filling the fields one by one, use a struct initializer.
This avoids repeating the name of the variable and is more
consistent with the wlroots code style.
find_extensions() is clunky to use when checking only a single
extension, and it's surprising that it returns NULL on success.
Simplify by replacing it with a check_extension() function which
just checks whether a single extension is in the list.
Instead of having a C file with strings for each shader, move each
shader into its own file. Use a small POSIX shell script to convert
the files into C strings (can't wait for C23 #embed...).
The benefits from this are:
- Improved readability and syntax highlighting.
- Line numbers in shader compiler errors are easier to make sense of.
- Consistency with the Vulkan renderer.
- Shaders will become more complicated as we add color management
features.
In the CREATE_DUMB error code-path, we'd only free() the buffer,
however it's already inserted in the alloc->buffers list at this
point.
Instead, make sure finish_buffer() is safe to call (by populating
drm_fd) and call that function.
INVALID means that the modifier is implicit. However dumb buffers
are guaranteed to be LINEAR, so let's just advertise this. Fixes
cursors with the DRM backend: cursor planes usually only support
LINEAR.
When running with the DRM backend, the Pixman renderer needs to
render the cursor buffer. However, DRM drivers only support linear
buffers for these in general, they don't support implicit modifiers
(aka. INVALID).
Advertise support for LINEAR in the Pixman renderer to fix this.
If we have a render node, it means there is a GPU which could be
used. We probably failed GL because of a kernel or Mesa issue.
Instead of automatically falling back to Pixman, error out.
This makes it more obvious to users when something goes wrong,
instead of silently exposing a slow unaccelerated desktop.
References: https://github.com/swaywm/sway/issues/7194
The Vulkan renderer is still experimental. If GL fails, we don't
want to automatically fall back to it by default.
Fixes: 8bd7170fd9 ("Use env helpers")
See the spec at [1]. tl;dr EGL has terrible defaults: eglTerminate()
may have side-effects on completely unrelated EGLDisplay objects.
This extension allows us to opt-in to get the sane behavior:
eglTerminate() only free's our own EGLDisplay without affecting
others.
[1]: https://registry.khronos.org/EGL/extensions/KHR/EGL_KHR_display_reference.txt