The two-pass blend image is created with VK_IMAGE_LAYOUT_UNDEFINED, so
on its first use loadOp=LOAD loads uninitialized memory. This oughtn't
be an issue, as we render onto it before we read it. These renders are
blends, so even opaque content is rendered with reference to an uninit
dst. This too ought to be fine: src*1 + dst*0 = src for all finite dst.
But the blend image pixfmt is VK_FORMAT_R16G16B16A16_SFLOAT, so uninit
pixels can be NaN, inf, or -inf, and now src*1 + dst*0 = NaN/inf/-inf.
This is bad enough assuming the uninitialized blend image holds random
bytes (2048/65536 values are not finite), even worse on any driver/GPU
with a framebuffer compression scheme that so happens to reliably read
NaNs from any uninitialized compressed image...
Most Mesa drivers happen not to do this perfectly valid thing, so this
is only reliably a problem (afaict) for honeykrisp i.e. AGX i.e. Asahi
Linux i.e. Apple Silicon, where after an upgrade to wlroots 0.20, sway
renders a black screen forever, unless you get quite lucky spamming VT
switches, in which case there's flickery garbage on exactly one of the
two swapchain buffers.
The blend image persists across frames, so it suffices to clear before
first real use. Rather than clear by hand, make a loadOp=CLEAR variant
of the render pass and use it for that first frame only. Adding a pass
sounds heavy, but render pass compatibility ignores loadOp and layouts
such that the new pass reuses the pipelines and framebuffer, and costs
one VkRenderPass object but not the usual pipeline/shader (re)compile.
Implement a ring-buffer that uses timeline points to track and release
allocated spans. We add larger ring-buffers when it fills, and remove
them when they have been unused for many collection cycles.
Signed-off-by: Kenny Levinsen <kl@kl.wtf>
This allows using the vulkan renderer on platforms that provide all
the necessary Vulkan extensions.
Tested on a Mali G52 platform with Mesa 26.0.0 and 25.3.5, which only
support Vulkan API 1.0.
We'll need to grab textures from there in the next commit.
Also rename it to better reflect what it does: synchronize release
fences after a render pass has been submitted.
Fixes d1c88e9 "render/vulkan: add linear single-subpass"
`find_or_create_render_setup` still assumed a single-buffer setup
always implied use of an srgb format
The important bit here is whether this is using a single or two
sub-passes. The flag isn't used for anything else.
Preparation for an upcoming one-subpass codepath.
Converting the LCMS2 transform to a 3D LUT early causes issues:
- It's a lossy process, the consumer will not be able to pick a
3D LUT size on their own.
- It requires unnecessary conversions and allocations: an intermediate
3D LUT is allocated, but the renderer already allocates one.
- It makes it harder to support arbitrary color transforms in the
renderer, because each type needs to be handled differently.
Instead, expose a function to evaluate a color transform, and use
that to build the 3D LUT in the renderer.
Perform a primitive garbage collection of buffers that have not been
used in the past 10 seconds, an arbitrarily selected number.
As garbage collection also makes span buffer allocation happen much more
often, logging on allocation activity leads to a lot of log noise so get
rid of that while at it.
This change makes it possible to support both the direct srgb-format
pipeline and indirect (color-managed, or non-srgb-format) pipeline
for the same render buffer.
Instead of having separate getters for shm formats and DMA-BUF
formats, use the same pattern as wlr_output_impl.get_primary_formats
with a single function which takes buffer caps as input.
This is the last of a set of commits which ensures that both textures
and render buffers can be accessed through _UNORM and _SRGB image
views. While _UNORM image views are not yet used for 8-bpc image
formats, they will be needed in the future to support color transforms
for both textures and render buffers.