Skip to content

feat(render): port IPCore renderer from OpenGL to QRhi (Metal / Vulkan / D3D12) #70

Description

@mcoliver

Summary

Port the IPCore renderer from OpenGL to Qt's QRhi (Qt 6.11), so UTV renders natively on Metal (macOS), Vulkan (Linux/Windows) and Direct3D 12 (Windows). OpenGL would remain only as a fallback. This is a long-term, multi-phase effort.

Why

  • Everything still renders with OpenGL. The Metal and Vulkan code in UTV today are presenters only. IPCore renders every frame with OpenGL, then hands it across with IOSurface or external-memory interop. That interop is fragile: vendor quirks, AMD Windows caveats, CPU fallbacks.
  • Apple's OpenGL is frozen at 4.1 and deprecated. Linux on Mesa has its own problems with how UTV binds GL (fix(linux): binaries fail to load with Mesa libGL (direct GL extension symbols); utvio FBO fails under llvmpipe #68).
  • HDR needs a non-GL swapchain. Qt's HDR swapchain formats (HDR10, HDRExtendedSrgbLinear, HDRExtendedDisplayP3Linear) only exist on the Metal/Vulkan/D3D backends; the QRhi GL backend is SDR-only. A native renderer gets HDR on every platform without cross-API handoffs. feat(macos): EDR and HDR PQ/HLG presentation modes for the Metal view #69 does macOS EDR/HDR natively in the meantime.
  • One backend-neutral code path instead of GL rendering plus per-platform presenters (MetalView, VulkanView, GLView).
  • Headless machines could use software Vulkan (Mesa lavapipe, SwiftShader) instead of software OpenGL.

Scope (measured)

Area Size
Direct GL calls in IPCore / TwkGLF / RvCommon ~840 (304 / 305 / 171)
GL calls in output plugins (AJA, BMD, NDI readback) ~58
Runtime-composed GLSL snippets (src/lib/ip/IPCore/glsl) 135
ShaderCommon.cpp + ImageRenderer.cpp ~10.9k lines
Bundled Mu/Python packages using the GL module 31 files (17 with immediate-mode glBegin)

The biggest compatibility risk is third-party RV packages that draw with the Mu/Python gl module. A Metal/Vulkan backend can't run their immediate-mode GL directly.

Proposed approach (no regressions)

  1. Golden-image regression suite first. Render reference scenes through utvio and compare with the bundled rmsImageDiff against checked-in references, using per-case tolerances. Cover:

    • every IPCore color node / GLSL snippet, CDL, LUTs, OCIO views, linearize / log / PQ / HLG;
    • compositing (over, add, difference, wipes, tiles), stereo modes, annotations, text / HUD overlays;
    • retime / format / resize.

    Run it in CI on all OSes (builds on test(ci): add CLI smoke and image format round-trip tests; run ctest in CI #64's ctest wiring). This is the "nothing breaks" guarantee, and it's valuable even before any porting.

  2. Abstraction layer. Introduce a thin render-API boundary in TwkGLF / IPCore (textures, FBOs / render targets, uploads, fences, shader programs). The first implementation wraps today's GL calls unchanged, verified against the goldens.

  3. Shaders. Move the GLSL snippets to QRhi's Vulkan-style GLSL, and bake them to SPIR-V / MSL / HLSL with QShaderBaker (QtShaderTools). IPCore composes shaders at runtime, so decide between runtime baking with a cache and pre-baking the finite set of shader combinations.

  4. QRhi on its OpenGL backend first. Output should match the goldens bit for bit (or within tolerance) while the API is still GL underneath.

  5. Switch backends per platform behind a flag: Metal (macOS), Vulkan (Linux), D3D12 (Windows). Keep GL as a selectable fallback. Compare against the goldens on each.

  6. Package compatibility. Keep a GL context for Mu/Python gl overlay drawing: packages draw into a GL texture that's shared/imported into QRhi and composited. Document the deprecation path for immediate-mode GL in packages.

  7. Presentation. Replace MetalView, VulkanView and GLView with one QRhi swapchain presenter (QWindow + QRhiSwapChain via createWindowContainer), including HDR formats and hdrInfo() headroom.

  8. Output devices. Port AJA / BMD / NDI readback from GL PBOs to QRhi readbacks.

  9. Headless. utvio and other offscreen rendering on QRhi with software Vulkan (lavapipe) or the GL fallback on GPU-less machines.

Related

Code of Conduct

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions