Hdr fixes#3023
Conversation
|
Okay, this has an outstanding issue with direct scanout of size mismatched XWayland surfaces, possibly also size mismatched Wayland surfaces, I've committed a fix, will push it once I verify it works correctly. |
ammen99
left a comment
There was a problem hiding this comment.
In general, I am highly doubtful about some of the latest changes. Why skip the zero-copy path if we don't need HDR / special color transfer functions? Maybe the best solution is something like this:
- Extend get_texture() to also include a parameter saying which color spaces the caller expects
- Make sure get_texture() does not go the zero-copy path if the texture does not match the expected color space
- In the GLES2 codepath, expect SRGB or whatever
- In the Vulkan codepath, say we support all transfer functions.
| * colors. Cached so that it is not recreated each frame. | ||
| */ | ||
| wlr_color_transform *output_inverse_eotf = nullptr; | ||
| wlr_color_transfer_function output_inverse_eotf_tf = (wlr_color_transfer_function)0; |
There was a problem hiding this comment.
is 0 a valid color transfer function? if not, seems like a candidate for std::optional<wlr_color_transfer_function> instead of invalid values.
There was a problem hiding this comment.
Still remains a point for improvement
The altered wlroots code base expects linear in the GLES2 code path as well. And maybe it's worth just getting rid of this branch instead, since I doubt that will ever be merged into wlroots, considering it breaks on Nvidia.
|
|
It's quite possible I should just discard everything after 2443c5f ... since that's mostly adapting everything to the GLES2 rewrite that will likely never be approved or employed anywhere. |
|
Could you please review again, I'm not sure how much of the above comments are regarding code I decided to move elsewhere for future dealings. |
ammen99
left a comment
There was a problem hiding this comment.
there are still a few small comments, but overall lgtm. If you fix them and are generally happy with how the PR works on your monitors, we can merge.
Also store color representation v1 pointer.
For future proofing, in case they become useful to the render setup.
Defaulting to sRGB/gamma22 for non-matching parameters.
Since the wlroots Vulkan renderer already supports intermediate float16 render pass, take advantage of it, and support allocating other intermediate buffers with a float16 hint, otherwise falling back on fixed 16 or fixed 8 where the others are unavailable.
Plugin-managed linear-space buffers (Expo's per-workspace aux, the cube's per-workspace framebuffers, the grid crossfade snapshot, view snapshots, and transformer inner_content) had no opinion about their underlying format. With an HDR (PQ) output, the per-source luminance multiplier in render_pass_t::add_texture scales PQ contents up to ~49.26 in the SDR-relative linear domain (PQ peak / SDR reference white) before they land in those buffers. An 8-bit linear backing clipped that to 1.0, dimming HDR highlights. Pass hdr_linear through buffer_allocation_hints_t at each of those sites, gated on the output's committed transfer function being ST2084_PQ. SDR outputs keep their 8-bit allocations. transformer_base_node_t::get_updated_contents gains an optional wf::output_t* parameter so it can make the same decision; the call site in transformer_render_instance_t::get_texture forwards _shown_on. The default nullptr preserves the existing behavior for any out-of-tree callers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Direct scanout commits the surface buffer straight to the primary plane via wlr_output_state_set_buffer, which leaves buffer_src_box / buffer_dst_box unset and lets wlroots default both to the buffer's pixel dimensions. On surfaces where the dimensions do not match the output exactly, some drivers may malfunction and ignore the position and/or dimensions of the direct scanout operation. Fall back to compositing for these surfaces so the renderer can sample the buffer correctly.
wlr_output_state_set_image_description() neither sets allow_reconfiguration nor triggers wlroots' empty-buffer allocation path, so HDR toggles produced atomic commits with no fresh primary buffer and no DRM_MODE_ATOMIC_ALLOW_MODESET flag. amdgpu rejected those, leaving HDR_OUTPUT_METADATA unapplied. Re-pin the current render format and set allow_reconfiguration on the pending state so wlroots attaches a new primary FB and the DRM backend issues a modeset commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The wlroots Vulkan two-pass renderer composites every add_texture into an FP16 blend image with sRGB primaries (it builds a sRGB-target absolute-colorimetric matrix per source primaries in pass.c). Wayfire's output color_transform was a pure linear→inverse-EOTF transform, which the second pass applies with an identity color matrix — leaving the final output buffer with sRGB primaries values that an HDR display configured for Rec.2020 then over-saturates. Build a 2-stage [matrix(sRGB→output_primaries), inverse_eotf] pipeline when the output's committed image description advertises non-sRGB primaries (e.g. BT.2020 on HDR), and fall back to the bare inverse_eotf otherwise. The wlroots Vulkan renderer accepts that pipeline shape via unwrap_color_transform's COLOR_TRANSFORM_PIPELINE branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Plugins computing the FP16-backing hint for linear aux buffers each inlined the same image-description / PQ-transfer check with a different verbose comment. Move the check to a single helper in render.hpp and keep the rationale comment there. v2: Amended to move the checker function to the right place. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
wlr_output_add_software_cursors_to_render_pass submits each cursor via wlr_render_pass_add_texture with only texture / src_box / dst_box / clip / transform set — no .primaries, .transfer_function, or .luminance_multiplier. wlroots therefore treats cursor pixels as already in the output's color space. On PQ outputs the sRGB cursor values are encoded as ~10000 cd/m² absolute Rec.2020, producing dazzlingly bright and oversaturated cursors. Open-code the cursor iteration so each cursor can carry the same sRGB- primaries + gamma2.2 tagging wlr_surface_node applies to regular surfaces, plus the SDR→PQ luminance multiplier from compute_luminance_multiplier. SDR outputs are unaffected: the multiplier resolves to 1.0 and the primaries conversion is identity. The cursor box is built in scaled fb-pixel coords and run through wlr_box_transform exactly as wlroots' helper does, avoiding the floor/ceil rounding errors that a logical-coord roundtrip would introduce on fractionally-scaled outputs. compute_luminance_multiplier is promoted from a static helper in render.cpp to wf:: so render-manager can call it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@kode54 I added some more commits to fix the remaining issues, please take a look at my latest changes, test and if it still works ok, I will merge. |
This branch was:
Co-authored-by: Claude Opus 4.7 (1M context) noreply@anthropic.com
Some of the changes were hand edits or tweaks, such as the gamma 2.2 change to the add_rect color, which required multiple rewrites before I realized what was up with that: