This will become necessary when we switch away from scissoring. For the
time being, this cleans things up a bit and allows for a trivial
blending implementation for textures when that comes.
Based on five calls:
wlr_render_timer_create - creates a timer which can be reused across
frames on the same renderer
wlr_renderer_begin_buffer_pass - now takes a timer so that backends can
record when the rendering starts and finishes
wlr_render_timer_get_time - should be called as late as possible so that
queries can make their way back from the GPU
wlr_render_timer_destroy - self-explanatory
The timer is exposed as an opaque `struct wlr_render_timer` so that
backends can store whatever they want in there.
We don't actually need the REPEAT mode, and this makes things more
consistent with the YCbCr sampler (which requires CLAMP_TO_EDGE for
spec compliance).
Also drop borderColor which is unused for this mode.
Some formats like sub-sampled YCbCr use a block of bytes to
store the color values for more than one pixel. Update our format
table to be able to handle such formats.
This is implemented by a two-subpass rendering scheme; the first
subpass draws (and blends) onto a linear R16G16B16A16_SFLOAT buffer,
while the second subpass performs linear->srgb conversion, writing
onto the actual output buffer.
This fixes the following validation errors when shutting down Sway:
00:00:01.263 [wlr] [render/vulkan/vulkan.c:65] Validation Error: [ VUID-vkDestroyFramebuffer-framebuffer-00892 ] Object 0: handle = 0x62e00003c400, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xdb308312 | Cannot call vkDestroyFramebuffer on VkFramebuffer 0x2e2cd000000002b[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to framebuffer must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkDestroyFramebuffer-framebuffer-00892) (VUID-vkDestroyFramebuffer-framebuffer-00892)
00:00:01.264 [wlr] [render/vulkan/vulkan.c:65] Validation Error: [ VUID-vkDestroyImage-image-01000 ] Object 0: handle = 0x62e00003c400, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xf2d29b5a | Cannot call vkDestroyImage on VkImage 0x3fbcd60000000028[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to image, either directly or via a VkImageView, must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkDestroyImage-image-01000) (VUID-vkDestroyImage-image-01000)
This ensures that the pool sizes grow exponentially, making the number
of pools needed logarithmic in the number of descriptors, instead of
linear. Since the first pool's size is 256, this change only has an
effect when the compositor creates a large number of textures.
The Vulkan spec doesn't guarantee that the driver will wait for
implicitly synchronized client buffers before texturing from them.
radv happens to perform the wait, but anv doesn't.
Fix this by extracting implicit fences from DMA-BUFs, importing
them into Vulkan as a VkSemaphore objects, and make the render pass
wait on these VkSemaphores.
pre_cb was an alias for stage_cb->vk. Let's just use a single
variable instead.
Additionally, early return when vulkan_record_stage_cb() fails.
We were crashing in vkCmdPipelineBarrier() if that happened.
Skip clears with an empty scissor.
Fixes the following validation error:
00:00:09.734 [wlr] [render/vulkan/vulkan.c:61] Validation Error: [ VUID-vkCmdClearAttachments-rect-02682 ] Object 0: handle = 0x62600001b100, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0xadbd476f | CmdClearAttachments(): pRects[0].rect.extent.width is zero. The Vulkan spec states: The rect member of each element of pRects must have an extent.width greater than 0 (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdClearAttachments-rect-02682) (VUID-vkCmdClearAttachments-rect-02682)
We were filling VkTimelineSemaphoreSubmitInfoKHR.pSignalSemaphoreValues,
but we were missing VkSubmitInfo.pSignalSemaphores.
This was causing VkTimelineSemaphoreSubmitInfoKHR.pSignalSemaphoreValues
to be ignored. By chance, the render command buffer was using the
next timeline point, so we were waiting for that instead.
Right now the Vulkan renderer blocks until the frame is complete
after rendering. This is necessary because Vulkan doesn't
interoperate well with implicit sync we use everywhere else.
Use the new kernel API to import a sync_file into a DMA-BUF to
avoid blocking.
We need to wait for the pending command buffer to complete before
re-using stage buffers. Otherwise we'll overwrite the stage buffer
with new contents before the texture is fully uploaded.
We need to wait for any pending command buffer to complete before
we're able to fully destroy a struct wlr_vk_texture: the Vulkan
spec requires the VkDescriptorSet to be kept alive.
So far we've done this in vulkan_end(), after blocking until the
command buffer completes. We'll soon stop blocking, so move this
logic in get_command_buffer(), where we check which commands buffers
have completed in a non-blocking fashion.
vkCmdCopyBufferToImage requires that the buffer offset be a multiple
of the texel block size, which for single plane uncompressed formats
is the same as the number of bytes per pixel. This commit adds an
alignment parameter to vulkan_get_stage_span which ensures that the
provided span (and the sequence of image copy operations derived which
use it) have this alignment.