Add HDR10 GPU rendering on Windows11, HiDPI zoom-box fix, distortion playback, and 16-bit PNG suppor#671
Open
supernova-jpg wants to merge 1 commit into
Open
Conversation
Introduce GPU-accelerated HDR10 rendering for 10-bit YUV sources using Qt RHI (D3D12), with PQ/HLG tone mapping, raw YUV caching, and overlay integration in SplitViewWidget. Includes YUV pipeline refactor and shader build rules. HDR capability detection uses DXGI on Windows. Co-authored-by: Cursor <cursoragent@cursor.com>
d1d7591 to
d11ee24
Compare
Author
|
Hi @ChristianFeldmann, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR extends YUView with a GPU-accelerated HDR10 viewing pipeline for 10-bit YUV sources, built on Qt 6 RHI (D3D12 on Windows). It also includes several complementary improvements developed alongside the HDR work:
YUVDataManager,YUVColorConverter, etc.) as the foundation for GPU upload and per-pixel toolsMotivation
YUView is widely used for codec development and subjective quality analysis of 10-bit BT.2020 content. The existing CPU
QPainterpath quantizes to 8-bit SDR and cannot drive a native HDR10 display. This PR adds a parallel HDR overlay window that:HDR Rendering
Supported render modes (
QSettings: HDRMode)All modes share a unified RGBA16F (scRGB linear light) internal rendering path and an HDR10 swap chain (
R10G10B10A2+ PQ color space on Windows).Shader pipeline (
hdr_rhi_yuv_fragment.frag)Supported YUV input formats (
HDRTextureUploader):YUV420p10le,YUV422p10le,YUV444p10le(planar)P010le(semi-planar; MSB-aligned samples normalized to internal 10-bit layout)Performance optimizations
videoHandler::CacheMode::RawYUV): whenEnable10BitDisplayis on and source is 10-bit planar, frames are cached as raw YUV (~25% smaller than RGBA for 4:2:0) instead of CPU-convertedQImageupdateHDRFrameYUVMove()moves frame buffers into the upload path, avoiding ~50 MB memcpy per 4K frame (~50 ms saved)m_enable10BitDisplayCachedavoids per-frameQSettingsdisk I/OUI controls (
videoHandlerYUV.ui)Enable10BitDisplayQSurfaceFormatset at startup inyuviewapp.cpp)HDRModeHDRExposureNitsHDR activates only when all of the following are true:
Enable10BitDisplay(and restarted)isHDR10Candidate())HDR detection & fallback
HDRDetectionWorkerruns DXGI enumeration off the GUI threadsignalDisplayHDRSupportChanged→MainWindowauto-disables HDRArchitecture
New module under
YUViewLib/src/video/hdr/:HDRRenderingManagerSplitViewWidgetattach → frame forwardingHDR_RhiVideoWindowQWindow+ QRhi render surface; overlay state;tryInitialize()for delayed expose handlingHDR_RhiVideoWindow_Overlays.cppHDRRhiPipelineHDRColorConversionHDRTextureUploaderHDRDetection/HDRDetectionWorkerIntegration with
SplitViewWidgetQWidget::createWindowContainer()as a full-widget overlaypaintEvent: when HDR active, pushes overlay state toHDR_RhiVideoWindowand skips SDR base draw to prevent double renderingupdateHDRVisibilityForSelection()immediately after embedding (not only onwidgetInitialized)tryInitialize()at 50 / 150 / 300 ms as fallback for delayed expose eventsHiDPI Zoom Box & Canvas Consistency
Problem
On Windows with 125%/150%/200% display scaling, Qt reports
devicePixelRatio() > 1. Without compensation, the same logical zoom factor maps to different pixel densities, causing:Solution (
splitViewWidget)Introduces dual zoom semantics:
zoomFactor(raw)effectiveZoomFactor()zoomFactor / devicePixelRatiom_parentZoom)devicePixelRatioForCurrentScreen()resolves DPR via cascade:windowHandle()→screen()→ primary screen →logicalDpiX() / 96Applied in:
paintEvent,setMoveOffset,zoomToFitInternal(physical widget size = logical × DPR)HDR_RhiVideoWindow::updateTransform(renderZoom, offset, displayZoom)— render uses DPI-compensated zoom; overlay label shows raw zoomZoom box behavior (SDR + HDR)
effectiveZoom >= 32(already at pixel level)m_overlayPatchProvidercallsvideoHandlerYUV::getCurrentFramePatchAsImage(region)— converts only the 5×5 patch viaYUVPixelRenderer, not the full framem_overlayYuvPixelProvider→getYuvPixelValueAt()for the info panel1/DPRsnapping for crisp 1-px lines on HiDPI displaysDistortion Playback (First-level / Second-level)
Extracted into
DistortionPlaybackController(YUViewLib/src/video/yuv/).Workflow:
splitViewWidgetinstancesUI located in
videoHandlerYUV.ui(pushButtonFirstLevel,pushButtonSecondLevel,revertButton_L1/L2).16-bit PNG / BMP Support
Implemented in
FrameHandler.cpp:load16BitPng()QImage::Format_RGBA64orFormat_Grayscale16load16BitBmp()Format_RGBA64loadImagePreservingHighBitDepth().png/.bmp, falls back toQImageReadergetImageRgbSample()configureHighBitDepthRendering()User-visible effect: image sequences and single frames retain full 16-bit sample precision (not clamped to 8-bit). Pixel-value overlay shows extended range. HDR window accepts
QImage::Format_RGBA16FPx4for RGB upload.YUV Pipeline Refactor
Monolithic
videoHandlerYUV.cpplogic split into focused modules:YUVDataManagershouldUseRawYUVCache()policyYUVColorConverterYUVPixelRendererYUVDifferenceCalculatorYUVConversionCore/Planes/RGB.hvideoHandlerYUV_UI.cppDistortionPlaybackControllerEnables both the HDR GPU path and efficient zoom-box / pixel-value tools without full-frame CPU conversion.
Other Notable Changes
VideoCache/LoadingWorkerguards against races when dragging files during 4K 10-bit buffer loadingPacketItemModeluses valid index ranges (avoidsdataChanged()warnings)PlaylistTreeWidget:viewport()->update()instead of invaliddataChanged()indicesYUViewLib.proaddsqsbcompile rule for.vert/.frag→.qsb(requires Qtshadertools)gui-private(QRhi), Windows libsdxgi,user32,ole32Platform Support
isHDRSupported = false)Requirements: Qt 6.4+ (6.6+ recommended for public QRhi API),
shadertoolsfor shader compilation.Settings Reference
Enable10BitDisplayfalseHDRMode0HDRExposureNits1000ToneMapTargetNits1000Test Plan
Build
shadertools; MSVC build succeeds;qsbshaders generatedHDR core
HiDPI / Zoom box
Distortion playback
16-bit images
Regression
Known Limitations & Future Work
getHDRRenderedImage()returns emptyQImage(stub)PR Scope Note
This branch also includes the YUV pipeline refactor and minor Qt warning fixes that were developed as prerequisites for the HDR GPU upload path. Non-HDR debug-macro cleanups in decoder/parser files are included only where they were part of the same development branch; happy to isolate further on request.