Utiliser DirectX avec des couleurs avancées sur des affichages à plage dynamique étendues/standard

Cette rubrique explique comment utiliser DirectX avec des scénarios de couleurs avancées, notamment la gamme dynamique élevée (HDR), la gamme de couleurs étendue (WCG) avec gestion automatique des couleurs du système et la profondeur de bits élevée. Les écrans d'ordinateurs personnels haut de gamme dotés d'au moins une des améliorations susmentionnées sont de plus en plus répandus et offrent une fidélité des couleurs nettement supérieure à celle des écrans traditionnels à gamme dynamique standard (SDR).

Dans cette rubrique, vous obtiendrez une vue d'ensemble des concepts techniques clés qui sous-tendent la prise en charge de Windows Advanced Color. Vous découvrirez les exigences et les instructions relatives au rendu des contenus HDR, WCG et DirectX à haute profondeur de bits sur l'un de ces écrans. Si vous avez une application gérant les couleurs (par exemple, en utilisant des profils ICC), vous apprendrez alors comment la gestion automatique des couleurs permet une meilleure précision des couleurs pour vos scénarios.

Introduction à la couleur avancée dans Windows

Advanced Color est un terme générique désignant les technologies des systèmes d'exploitation (OS) pour les écrans dont la fidélité des couleurs est nettement supérieure à celle des écrans standard. Les principales fonctionnalités étendues sont décrites dans les sections ci-dessous. Les fonctionnalités Advanced Color ont été introduites pour la première fois pour les écrans HDR avec Windows 10, version 1709 (Fall Creators Update), et pour les écrans SDR spécialement provisionnés avec la version 22H2 (10.0 ; Build 22621) de Windows 11.

Plage dynamique élevée

La plage dynamique fait référence à la différence entre la luminance maximale et minimale d'une scène ; elle est souvent mesurée en nits (candelas par centimètre carré). Les scènes réelles, comme ce coucher de soleil, ont souvent des plages dynamiques de 10 ordres de grandeur de luminance ; l'œil humain peut discerner une plage encore plus grande après adaptation.

Image d'un coucher de soleil avec les points les plus lumineux et les plus sombres de la scène étiquetés.

Depuis Direct3D 9, les moteurs graphiques sont capables d'effectuer un rendu interne de leurs scènes avec ce niveau de fidélité physique. Cependant, un écran typique à gamme dynamique standard ne peut reproduire qu'un peu plus de 3 ordres de grandeur de luminance, et tout contenu rendu HDR doit donc être tonemappé (compressé) dans la gamme limitée de l'écran. Les nouveaux écrans HDR, y compris ceux qui sont conformes à la norme HDR10 (BT.2100), dépassent cette limite ; par exemple, les écrans auto-émissifs de haute qualité peuvent atteindre plus de 6 ordres de grandeur.

Large gamme de couleurs

La gamme de couleurs fait référence à l'étendue et à la saturation des teintes qu'un écran peut reproduire. Les couleurs naturelles les plus saturées que l'œil humain peut percevoir sont celles de la lumière pure et monochromatique, telle que celle produite par les lasers. Cependant, les écrans grand public ne peuvent souvent reproduire les couleurs que dans la gamme sRGB, qui ne représente qu'environ 35 % de toutes les couleurs perceptibles par l'homme. Le diagramme ci-dessous est une représentation du « lieu spectral » humain, ou de toutes les couleurs perceptibles (à un niveau de luminance donné), où le triangle le plus petit représente la gamme sRGB.

diagramme du lieu spectral humain et de la gamme sRGB

Les écrans PC professionnels haut de gamme prennent depuis longtemps en charge des gammes de couleurs nettement plus larges que sRGB, telles que Adobe RGB et DCI-P3, qui couvrent environ la moitié des couleurs perceptibles par l'homme. Ces écrans à large gamme de couleurs sont de plus en plus courants.

Gestion automatique des couleurs du système

La gestion des couleurs est la technologie et la pratique qui permettent d'assurer une reproduction précise et cohérente des couleurs sur l'ensemble des appareils. Si vous êtes un créateur de contenu numérique, il est essentiel que les couleurs de votre contenu visuel, comme une photo, une image de produit ou un logo, apparaissent de la même manière sur votre écran que sur la grande variété d'appareils numériques de votre public.

Windows fournit des API de gestion des couleurs depuis Windows 2000 avec les API Image Color Management (ICM) et plus tard Windows Color System (WCS). Cependant, ces API n'étaient que des aides pour les applications qui souhaitaient ou devaient gérer les couleurs, alors que la plupart des applications et des contenus numériques utilisaient simplement l'espace colorimétrique sRGB standard de l'industrie et n'étaient jamais gérés par le système d'exploitation. C'était une hypothèse raisonnable dans le passé, mais les écrans à large gamme de couleurs de haute qualité sont de plus en plus courants.

Les nouvelles versions de Windows prennent en charge la gestion automatique des couleurs du système, ce qui garantit que toutes les couleurs de toutes les applications Windows, qu'elles soient ou non sensibles à la couleur, s'affichent avec précision et cohérence sur tous les écrans pris en charge.

Remarque

La gestion automatique des couleurs n'est pas une propriété du matériel d'affichage ; il s'agit d'une fonctionnalité de Windows qui permet de prendre en charge correctement les écrans dont la gamme de couleurs est plus large que sRGB.

Précision/profondeur de bits

La précision numérique, ou profondeur de bits, fait référence à la quantité d'informations utilisées pour identifier les couleurs de manière unique. Une profondeur de bits plus élevée signifie que vous pouvez distinguer des couleurs très similaires sans artefacts tels que l'effet de bande. Les écrans d'ordinateur courants prennent en charge 8 bits par chaîne de couleur, alors que l'œil humain a besoin d'une précision d'au moins 10 à 12 bits pour éviter les distorsions perceptibles.

Image de moulins à vent à une simulation de 2 bits par canal de couleur contre 8 bits par canal

Avant Advanced Color, le gestionnaire de fenêtres du bureau (DWM) limitait les applications fenêtrées à 8 bits par chaîne de couleur, même si l'écran prenait en charge une profondeur de bits supérieure. Lorsque la fonction Advanced Color est activée, le DWM effectue sa composition en utilisant la virgule flottante IEEE en demi-précision (FP16), ce qui élimine les goulets d'étranglement et permet d'utiliser toute la précision de l'écran.

Architecture du système Windows Advanced Color

Les informations contenues dans cette section sont facultatives pour la création d'applications Advanced Color, mais il est utile de comprendre le fonctionnement de la technologie afin d'optimiser le rendu et le comportement de votre application.

Dans cette section, nous utiliserons un diagramme simplifié pour décrire les composants pertinents de la pile graphique de Windows :

Schéma de la pile graphique de Windows : de l'application au DWM en passant par le noyau d'affichage

Windows actuel : écrans 8 bits / sRGB

Pendant des décennies, les écrans grand public et la pile graphique Windows ont été basés sur un contenu sRGB à 8 bits par chaîne (24 bits par pixel). Les applications utilisant des API graphiques telles que DirectX pouvaient effectuer un rendu interne en utilisant des profondeurs de bits élevées et des espaces colorimétriques étendus ; cependant, le système d'exploitation ne prenait en charge que les entiers 8 bits avec sRGB implicite et aucune gestion des couleurs du système :

diagramme de la pile d'affichage SDR : limitée à sRGB, 8 bits, sans gestion des couleurs

Cela signifiait que toute donnée de couleur supplémentaire rendue par une application serait perdue lors de l'affichage ; et que l'application devait effectuer elle-même la gestion des couleurs pour assurer une reproduction précise sur un écran.

Windows 10, version 1703 : écrans HDR avec Advanced Color

Windows 10, version 1703 a introduit la première version des capacités Advanced Color pour les écrans HDR. Cela a nécessité plusieurs avancées significatives dans la pile graphique du système d'exploitation :

  • Prise en charge de la signalisation d'affichage HDR
  • Composition du système à l'aide d'un espace colorimétrique canonique à grande profondeur de bits
  • Gestion automatique des couleurs du système

diagramme de bloc de la pile d'affichage HDR : FP16, scRGB, avec gestion automatique des couleurs

Chaque avancée est décrite dans les sous-sections ci-dessous. Le résultat net est que les données de couleur de l'application étendue sont maintenant correctement préservées par le système d'exploitation et reproduites avec précision sur les écrans HDR.

Prise en charge de la signalisation d'affichage HDR

La signalisation HDR sur les connecteurs d'affichage tels que DisplayPort et HDMI utilise principalement une précision de 10 bits par chaîne (ou plus) et l'espace colorimétrique BT.2100 ST.2084. Le noyau d'affichage, le pilote d'affichage et le matériel GPU sous-jacent doivent tous prendre en charge la détection, la sélection et le lecteur de ce mode de signalisation.

Composition du système à l'aide d'un espace colorimétrique canonique à grande profondeur de bits

L'espace colorimétrique BT.2100 ST.2084 est une norme efficace pour le codage des couleurs HDR, mais il n'est pas adapté à de nombreuses opérations de rendu et de composition (mélange). Nous voulons également que le système d'exploitation soit à l'épreuve du temps pour prendre en charge des technologies et des espaces colorimétriques bien au-delà de la norme BT.2100, qui couvre moins de 2/3 des couleurs visibles par l'homme. Enfin, dans la mesure du possible, nous voulons minimiser la consommation des ressources du GPU afin d'améliorer la puissance et les performances.

En mode HDR, le gestionnaire de fenêtres du bureau (DWM) utilise un espace colorimétrique de composition canonique (CCCS) défini comme suit :

  • espace colorimétrique scRGB (primaires BT.709/sRGB avec gamma linéaire)
  • Demi précision IEEE (profondeur de bit FP16)

Cet espace offre un bon équilibre entre tous les objectifs susmentionnés. CCCS autorise les valeurs de couleur en dehors de la plage numérique [0, 1] ; étant donné la plage de valeurs FP16 valides, il peut représenter des ordres de grandeur de plus de couleurs que la plage visuelle humaine naturelle, y compris des valeurs de luminance supérieures à 5 millions de nits. FP16 offre une excellente précision pour les opérations de mélange gamma linéaire, mais consomme deux fois moins de mémoire GPU et de bande passante qu'une simple précision traditionnelle (FP32), sans perte de qualité perceptible.

Gestion automatique des couleurs du système

Windows est un environnement multitâche dans lequel l'utilisateur peut exécuter un nombre quelconque d'applications SDR et HDR en même temps avec des fenêtres qui se chevauchent. Il est donc essentiel que tous les types de contenu soient corrects et de qualité maximale lorsqu'ils sont transmis à un écran ; par exemple, une application de productivité sRGB (SDR) avec une fenêtre vidéo BT.2100 ST.2084 (HDR) qui se superpose.

En mode HDR, Windows effectue des opérations de gestion des couleurs en deux étapes :

  1. Le DWM convertit chaque application de son espace colorimétrique natif en CCCS avant de procéder au mélange.
  2. Le noyau d'affichage convertit le tampon de trame du système d'exploitation de CCCS à l'espace colorimétrique du format filaire (BT.2100 ST.2084).

diagramme de bloc de la gestion automatique des couleurs dans le DWM et le noyau d'affichagediagramme de bloc de la gestion automatique des couleurs dans le DWM et le noyau d'affichage, partie 2

Remarque

Dans les deux étapes, l'opération de gestion des couleurs consiste en une conversion de l'espace colorimétrique (matrice et 1DLUT). Les couleurs qui dépassent la gamme de couleurs cible de l'écran sont numériquement coupées.

Windows 11, version 22H2 : écrans SDR avec Advanced Color

Bien que la prévalence des écrans HDR augmente rapidement, les écrans SDR resteront importants pour les années à venir. La prise en charge du HDR dans Windows 10, version 1703, a posé la plupart des bases nécessaires pour améliorer également les écrans SDR. Windows 11, version 22H2, étend les fonctionnalités Advanced Color et la gestion automatique des couleurs à certains écrans SDR admissibles. Le diagramme de blocs graphiques des écrans SDR Advanced Color ressemble beaucoup à celui du HDR :

diagramme de bloc de la pile d'affichage SDR AC : FP16, scRGB, avec gestion automatique des couleurs

Prise en charge de la signalisation des écrans SDR avec une profondeur de bits élevée

La signalisation sous-jacente des écrans SDR est inchangée, bien que la version 22H2 de Windows 11 prenne en charge 10 bits par chaîne et plus, en fonction des capacités de l'écran.

Composition du système à l'aide d'un espace colorimétrique canonique à grande profondeur de bits

La fonctionnalité DWM Advanced Color, y compris le mélange dans CCCS, est presque entièrement inchangée par rapport aux écrans HDR. La principale différence est que le DWM utilise la luminance référencée par l'affichage avec les écrans SDR, et la luminance référencée par la scène avec les écrans HDR. Cela modifie la façon dont votre contenu rendu Advanced Color est interprété par le système d'exploitation :

Type d'affichage Comportement de la luminance Comment est interprété 1.0f
SDR Luminance référencée par l'écran Comme le niveau de blanc de référence de l'écran
HDR En référence à la scène Comme 80 nits (blanc de référence nominal)

Gestion automatique des couleurs du système

Les capacités de gestion des couleurs du système d'exploitation sont pour la plupart inchangées par rapport aux écrans HDR. La principale différence est que le noyau d'affichage convertit vers l'espace colorimétrique référencé par l'affichage, tel que défini par les données de colorimétrie et d'étalonnage de l'affichage, au lieu de l'espace colorimétrique standard BT.2100 ST.2084 pour les affichages HDR.

Provisionnement de l'affichage requis

Des données précises provenant d'un profil ICC MHC sont nécessaires pour définir l'opération de gestion des couleurs de sortie du noyau d'affichage. Par conséquent, seuls les écrans SDR qui ont été spécifiquement fournis par le fabricant ou un fournisseur d'étalonnage d'écran avec un profil valide sont éligibles pour la gestion automatique des couleurs. Pour plus d'informations, consultez la section Comportement des profils ICC avec Advanced Color.

Configuration requise et prise en charge du système d'exploitation

Windows 10, version 1709 a d'abord livré la prise en charge des couleurs avancées pour les écrans HDR. La version 22H2 de Windows 11 ajoute la prise en charge des couleurs avancées pour les écrans SDR dont les données de provisionnement sont exactes.

Cette rubrique suppose que votre application cible Windows 10, version 2004 (ou ultérieure) pour les écrans HDR, et la version Windows 11, version 22H2 (ou ultérieure) pour les écrans SDR.

Affichage

Un écran à plage dynamique élevée doit mettre en œuvre la norme HDR10, ou BT.2100 ST.2084. La qualité d'affichage HDR peut varier considérablement et nous recommandons fortement les écrans certifiés, tels que VESA DisplayHDR. À partir de la version 22H2 de Windows 11, Windows affiche l'état de certification des écrans connus dans l'application Paramètres.

Un écran à plage dynamique standard doit disposer de données de provisionnement des couleurs précises pour la prise en charge des couleurs avancées. Dans la version 22H2 de Windows 11, la seule méthode prise en charge pour remplacer ces données est le profil ICC MHC ; en outre, l'utilisateur ou le fabricant de l'écran doit avoir activé la gestion automatique des couleurs. Pour plus d'informations, consultez la section Comportement des profils ICC avec Advanced Color.

Processeur graphique (GPU)

Pour une fonctionnalité Advanced Color complète sur les écrans SDR et HDR, un GPU récent est nécessaire :

  • AMD Radeon RX 400 (Polaris) ou plus récent
  • NVIDIA GeForce 10 (Pascal), ou plus récent
  • Intel Core 10e génération (Ice Lake), ou plus récent*.

Remarque

Les chipsets Intel Comet Lake (code de modèle à 5 chiffres) n'offrent pas toutes les fonctionnalités.

Des exigences matérielles supplémentaires peuvent s'appliquer, selon les scénarios, notamment l'accélération matérielle des codecs (HEVC 10 bits, VP9 10 bits, etc.) et la prise en charge de PlayReady (SL3000). Contactez votre fournisseur de GPU pour obtenir des informations plus spécifiques.

Pilote graphique (WDDM)

Il est fortement recommandé d'utiliser le dernier pilote graphique disponible, soit à partir de Windows Update, soit à partir du site web du fournisseur du GPU ou du fabricant du PC. Cette rubrique s'appuie sur les fonctionnalités du pilote WDDM 2.7 (Windows 10, version 2004) pour les écrans HDR, et WDDM 3.0 (Windows 11, version 21H2) pour les écrans SDR.

API de rendu prises en charge

Windows 10 prend en charge une grande variété d'API et de frameworks de rendu. La prise en charge avancée des couleurs repose fondamentalement sur la capacité de votre application à effectuer une présentation moderne à l'aide de DXGI ou des API de la couche visuelle.

Par conséquent, toute API de rendu capable d'utiliser l'une de ces méthodes de présentation peut prendre en charge Advanced Color. Cela inclut (mais n'est pas limité à) ce qui suit.

  • Direct3D 11
  • Direct3D 12
  • Direct2D
  • Win2D
    • Nécessite l'utilisation des API CanvasSwapChain ou CanvasSwapChainPanel de niveau inférieur.
  • Windows.UI.Input.Inking
    • Prise en charge du rendu personnalisé à l'encre sèche à l'aide de DirectX.
  • XAML
    • Prise en charge de la lecture de vidéos HDR à l'aide de MediaPlayerElement.
    • Prise en charge du décodage des images JPEG XR à l'aide de l'élément Image.
    • Prise en charge de l'interopérabilité DirectX à l'aide de SwapChainPanel.

Gestion des capacités d'affichage dynamique

Windows 10 prend en charge une vaste gamme d'écrans compatibles avec Advanced Color, depuis les panneaux intégrés à faible consommation d'énergie jusqu'aux moniteurs et téléviseurs de jeu haut de gamme. Les utilisateurs de Windows s'attendent à ce que votre application gère de manière transparente toutes ces variations, y compris les écrans SDR existants omniprésents.

Windows 10 permet à l'utilisateur de contrôler les capacités HDR et Advanced Color. Votre application doit détecter la configuration actuelle de l'affichage et répondre de manière dynamique à tout changement de capacité. Cela peut se produire pour de nombreuses raisons, par exemple parce que l'utilisateur a activé ou désactivé une fonctionnalité, ou déplacé l'application entre différents écrans, ou encore parce que l'état d'alimentation du système a changé.

Option 1 : AdvancedColorInfo

Remarque

L'API d'exécution Windows AdvancedColorInfo est utilisable indépendamment de l'API de rendu, prend en charge Advanced Color pour les écrans SDR et utilise des événements pour signaler les changements de capacités. Cependant, il n'est disponible que pour les applications de la plateforme universelle Windows (UWP) ; les applications de bureau (qui n'ont pas de CoreWindow) ne peuvent pas l'utiliser. Pour plus d'informations, consultez les API du moteur d'exécution Windows qui ne sont pas prises en charge dans les applications de bureau.

Tout d'abord, obtenez une instance d'AdvancedColorInfo à partir de DisplayInformation::GetAdvancedColorInfo.

Pour vérifier quel type de couleur avancée est actuellement actif, utilisez la propriété AdvancedColorInfo::CurrentAdvancedColorKind. C'est la propriété la plus importante à vérifier, et vous devez configurer votre pipeline de rendu et de présentation en fonction du type actif :

Type de couleur avancé Capacités d'affichage
SDR Affichage SDR sans capacités de couleurs avancées
WCG Affichage SDR avec profondeur de bits élevée et gestion automatique des couleurs
HDR Affichage HDR avec toutes les fonctionnalités Advanced Color

Pour vérifier quels types de couleurs avancées sont pris en charge, mais pas nécessairement actifs, appelez AdvancedColorInfo::IsAdvancedColorKindAvailable. Vous pourriez utiliser ces informations, par exemple, pour inviter l'utilisateur à se rendre dans l'application Paramètres de Windows afin qu'il puisse activer le HDR ou la gestion automatique des couleurs.

Les autres membres d'AdvancedColorInfo fournissent des informations quantitatives sur le volume de couleur physique du panneau (luminance et chrominance), correspondant aux métadonnées HDR statiques SMPTE ST.2086. Même si la norme ST.2086 a été conçue à l'origine pour les écrans HDR, ces informations sont utiles et sont disponibles pour les écrans HDR et SDR. Vous devriez utiliser ces informations pour configurer le mappage des tons et des gamuts de votre application.

Pour gérer les modifications des capacités de couleurs avancées, inscrivez-vous à l'événement DisplayInformation::AdvancedColorInfoChanged. Cet événement est déclenché si l'un des paramètres des capacités avancées de couleur de l'écran est modifié pour une raison quelconque.

Gérez cet événement en obtenant une nouvelle instance d'AdvancedColorInfo et en vérifiant quelles valeurs ont été modifiées.

IDXGIOutput6

Remarque

L'interface DirectX Graphics Infrastructure IDXGIOutput6 est disponible pour toute application qui utilise DirectX, qu'il s'agisse d'un ordinateur de bureau ou d'une plateforme Windows universelle (UWP). Cependant, IDXGIOutput6 ne prend pas en charge les écrans SDR dotés de fonctionnalités Advanced Color telles que la gestion automatique des couleurs ; il ne peut identifier que les écrans HDR.

Si vous écrivez une application de bureau Win32 et que vous utilisez DirectX pour le rendu, utilisez DXGI_OUTPUT_DESC1 pour obtenir des capacités d'affichage. Obtenez une instance de cette structure via IDXGIOutput6::GetDesc1.

Pour vérifier quel type de couleur avancée est actuellement actif, utilisez la propriété ColorSpace, qui est de type DXGI_COLOR_SPACE_TYPE et contient l'une des valeurs suivantes :

DXGI_COLOR_SPACE_TYPE Capacités d'affichage
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 Affichage SDR sans capacités de couleurs avancées
DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 Affichage HDR avec toutes les fonctionnalités Advanced Color

Remarque

Les écrans SDR dotés de capacités de couleurs avancées sont également signalés comme DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; DXGI ne vous permet pas de faire la distinction entre les deux types.

Remarque

DXGI ne vous permet pas de vérifier quels types de couleurs avancées sont pris en charge mais non actifs pour le moment.

La plupart des autres membres de DXGI_OUTPUT_DESC1 fournissent des informations quantitatives sur le volume de couleur physique du panneau (luminance et chrominance), correspondant aux métadonnées HDR statiques SMPTE ST.2086. Même si la norme ST.2086 a été conçue à l'origine pour les écrans HDR, cette information est utile et est disponible pour les écrans HDR et SDR. Vous devriez utiliser ces informations pour configurer le mappage des tons et des gamuts de votre application.

Les applications de bureau Win32 ne disposent pas d'un mécanisme natif pour répondre aux changements de capacité des couleurs avancées. En revanche, si votre application utilise une boucle de rendu, vous devez interroger IDXGIFactory1::IsCurrent à chaque trame. S'il indique FALSE, vous devez obtenir un nouveau DXGI_OUTPUT_DESC1 et vérifier quelles valeurs ont été modifiées.

En outre, votre pompe à messages Win32 doit gérer le message WM_SIZE, qui indique que votre application a pu passer d'un écran à l'autre.

Remarque

Pour obtenir un nouveau DXGI_OUTPUT_DESC1, vous devez obtenir l'affichage actuel. Cependant, vous ne devez pas appeler IDXGISwapChain::GetContainingOutput. En effet, les chaînes d'échange renvoient une sortie DXGI périmée une fois que DXGIFactory::IsCurrent est faux ; et recréer la chaîne d'échange pour obtenir une sortie actuelle se traduit par un écran temporairement noir. Nous vous recommandons plutôt d'énumérer les limites de toutes les sorties DXGI et de déterminer celle qui présente la plus grande intersection avec les limites de la fenêtre de votre application.

L'exemple de code suivant provient de l'application d'exemple Direct3D 12 HDR sur GitHub.

// Retrieve the current default adapter.
ComPtr<IDXGIAdapter1> dxgiAdapter;
ThrowIfFailed(m_dxgiFactory->EnumAdapters1(0, &dxgiAdapter));

// Iterate through the DXGI outputs associated with the DXGI adapter,
// and find the output whose bounds have the greatest overlap with the
// app window (i.e. the output for which the intersection area is the
// greatest).

UINT i = 0;
ComPtr<IDXGIOutput> currentOutput;
ComPtr<IDXGIOutput> bestOutput;
float bestIntersectArea = -1;

while (dxgiAdapter->EnumOutputs(i, &currentOutput) != DXGI_ERROR_NOT_FOUND)
{
    // Get the retangle bounds of the app window
    int ax1 = m_windowBounds.left;
    int ay1 = m_windowBounds.top;
    int ax2 = m_windowBounds.right;
    int ay2 = m_windowBounds.bottom;

    // Get the rectangle bounds of current output
    DXGI_OUTPUT_DESC desc;
    ThrowIfFailed(currentOutput->GetDesc(&desc));
    RECT r = desc.DesktopCoordinates;
    int bx1 = r.left;
    int by1 = r.top;
    int bx2 = r.right;
    int by2 = r.bottom;

    // Compute the intersection
    int intersectArea = ComputeIntersectionArea(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2);
    if (intersectArea > bestIntersectArea)
    {
        bestOutput = currentOutput;
        bestIntersectArea = static_cast<float>(intersectArea);
    }

    i++;
}

// Having determined the output (display) upon which the app is primarily being 
// rendered, retrieve the HDR capabilities of that display by checking the color space.
ComPtr<IDXGIOutput6> output6;
ThrowIfFailed(bestOutput.As(&output6));

DXGI_OUTPUT_DESC1 desc1;
ThrowIfFailed(output6->GetDesc1(&desc1));

Configurer votre chaîne d'échange DirectX

Une fois que vous avez déterminé que l'écran prend actuellement en charge les fonctionnalités Advanced Color, configurez votre chaîne d'échange comme suit.

Utilisez un effet de modèle de présentation flip

Lorsque vous créez votre chaîne d'échange à l'aide de l'une des méthodes CreateSwapChainFor[Hwnd|Composition|CoreWindow], vous devez utiliser le modèle de retournement DXGI en sélectionnant l'option DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL ou DXGI_SWAP_EFFECT_FLIP_DISCARD, ce qui permet à votre chaîne d'échange de bénéficier du traitement Advanced Color de DWM et de diverses optimisations pour le plein écran Pour plus d'informations, voir Pour de meilleures performances, utilisez le modèle de basculement DXGI.

Option 1. Utilisez le format de pixel FP16 et l'espace colorimétrique scRGB

Windows 10 prend en charge deux combinaisons principales de format de pixel et d'espace colorimétrique pour Advanced Color. Sélectionnez-en une en fonction des exigences spécifiques de votre application.

Nous recommandons aux applications à usage général d'utiliser l'option 1. C'est la seule option qui fonctionne pour tous les types d'écrans, de contenus et d'API de rendu Advanced Color. Lors de la création de votre chaîne d'échange, spécifiez DXGI_FORMAT_R16G16B16A16_FLOAT dans votre DXGI_SWAP_CHAIN_DESC1. Par défaut, une chaîne d'échange créée avec un format de pixels en virgule flottante est traitée comme si elle utilisait l'espace colorimétrique DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709. Il s'agit du même format de pixel et du même espace colorimétrique que ceux utilisés par le DWM.

Cette combinaison vous offre la plage numérique et la précision nécessaires pour spécifier toute couleur physiquement possible et effectuer un traitement arbitraire, y compris le mélange.

Cependant, cette option consomme 64 bits par pixel, ce qui double la bande passante du GPU et la consommation de mémoire par rapport aux formats de pixels UINT8 traditionnels. En outre, scRGB utilise des valeurs numériques en dehors de la plage normalisée [0, 1] pour représenter les couleurs qui ne font pas partie de la gamme sRGB et/ou dont la luminance est supérieure à 80 nits. Par exemple, scRGB (1.0, 1.0, 1.0) code le blanc D65 standard à 80 nits ; mais scRGB (12.5, 12.5, 12.5) code le même blanc D65 à une luminance beaucoup plus élevée de 1000 nits. Certaines opérations graphiques nécessitent une plage numérique normalisée, et vous devez soit modifier l'opération, soit renormaliser les valeurs de couleur.

La manière dont les valeurs de luminance sont interprétées avec cette option diffère entre les écrans SDR et HDR ; voir ci-dessous.

Option 2 : utilisez le format de pixel UINT10/RGB10 et l'espace colorimétrique HDR10/BT.2100

L'option 2 est une optimisation des performances qui n'est disponible que si votre application remplit toutes les conditions suivantes :

  • vise un affichage HDR
  • Utilise Direct3D 12 ou Direct3D 11
  • La chaîne d'échange ne nécessite pas de mélange avec alpha/transparence.

Si votre application ne remplit pas toutes ces conditions, vous devez utiliser l'option 1.

Mais si votre application remplit les conditions de l'option 2, alors cela pourrait offrir de meilleures performances si votre application consomme du contenu encodé en HDR10, comme un lecteur vidéo, ou si elle sera principalement utilisée dans des scénarios plein écran, comme un jeu. Lors de la création de votre chaîne d'échange, vous devriez envisager de spécifier DXGI_FORMAT_R10G10B10A2_UNORM dans DXGI_SWAP_CHAIN_DESC1. Par défaut, cela revient à utiliser l'espace colorimétrique sRGB ; vous devez donc appeler explicitement IDXGISwapChain3::SetColorSpace1, et définir comme espace colorimétrique DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020, également connu sous le nom de HDR10/BT.2100.

Cette option consomme les mêmes 32 bits par pixel que les formats de pixels SDR UINT8 traditionnels. En outre, sur certains GPU, cela permet d'éliminer une partie du traitement nécessaire pour convertir le contenu au format de fil HDR10.

Utilisation d'une chaîne d'échange de couleurs avancée lorsque l'écran est en mode SDR

Vous pouvez utiliser une chaîne d'échange Advanced Color même si l'écran ne prend pas en charge toutes les fonctionnalités Advanced Color. Dans ces cas, le gestionnaire de fenêtres bureau (DWM) convertira votre contenu vers le bas pour l'adapter aux capacités de l'affichage en effectuant un écrêtage numérique. Par exemple, si vous effectuez un rendu vers une chaîne d'échange FP16 scRGB et que vous ciblez un écran standard, tout ce qui se trouve en dehors de la plage numérique [0, 1] est écrêté.

Ce comportement de conversion vers le bas se produira également si la fenêtre de votre application est à cheval sur deux écrans ou plus avec des capacités de couleurs avancées différentes. AdvancedColorInfo et IDXGIOutput6 sont abstraits pour ne signaler que les caractéristiques de l'affichage principal (principal étant défini comme l'affichage contenant le centre de la fenêtre).

Faites correspondre le blanc de référence de votre application au niveau de blanc de référence SDR du système d'exploitation.

Remarque

Le blanc de référence ne s'applique qu'aux écrans HDR ; pour les écrans SDR Advanced Color, (1.0, 1.0, 1.0) signifie toujours la luminance blanche maximale que l'écran peut reproduire.

Dans de nombreux scénarios, votre application voudra rendre à la fois le contenu SDR et HDR ; par exemple, le rendu des sous-titres ou des commandes de transport sur une vidéo HDR, ou l'interface utilisateur dans une scène de jeu. Il est important de comprendre le concept de niveau de blanc de référence SDR pour s'assurer que votre contenu SDR s'affiche correctement sur un écran HDR. Le blanc de référence indique la luminosité à laquelle un objet blanc diffus (comme une feuille de papier, ou parfois une interface utilisateur) apparaît dans une scène HDR. Étant donné que les valeurs de couleur HDR ont une luminosité référencée par la scène, une valeur de couleur particulière doit être affichée à un niveau de luminance absolu, et non pas par rapport à la valeur maximale possible du panneau. Par exemple, scRGB (1.0, 1.0, 1.0) et HDR10 (497, 497, 497) codent tous deux exactement le blanc D65 à une luminance de 80 nits. Windows permet à l'utilisateur de régler le niveau de blanc de référence SDR selon ses préférences ; c'est la luminance à laquelle Windows rendra sRGB (1.0, 1.0, 1.0). Sur les moniteurs HDR de bureau, les niveaux de blanc de référence SDR sont généralement fixés à environ 200 nits.

Votre application HDR doit permettre à l'utilisateur de définir le niveau de blanc de référence de son choix ou de lire la valeur configurée par le système. Vous devez mapper vos valeurs de couleur blanche diffuse dans votre scène au niveau de blanc de référence SDR. Cela implique de multiplier votre framebuffer d'application dans l'espace gamma linéaire.

Remarque

Sur un écran qui prend en charge un contrôle de la luminosité, comme sur un ordinateur portable, Windows ajuste également la luminance du contenu HDR (référencé par la scène) pour qu'il corresponde au niveau de luminosité souhaité par l'utilisateur, mais cela n'est pas visible pour l'application. À moins que vous n'essayiez de garantir une reproduction précise du signal HDR, vous pouvez généralement ignorer ce point.

Si votre application effectue toujours le rendu SDR et HDR sur des surfaces séparées, et qu'elle s'appuie sur la composition du système d'exploitation, alors Windows effectuera automatiquement le bon ajustement pour augmenter le contenu SDR jusqu'au niveau de blanc souhaité. Par exemple, si votre application utilise XAML et rend le contenu HDR dans son propre SwapChainPanel.

En revanche, si votre application effectue sa propre composition du contenu SDR et HDR en une seule surface, il vous incombe d'effectuer vous-même l'ajustement du niveau de blanc de référence SDR. Dans le cas contraire, le contenu SDR risque d'apparaître trop faible dans les conditions d'affichage typiques d'un ordinateur de bureau. Vous devez d'abord obtenir le niveau de blanc de référence SDR actuel, puis ajuster les valeurs de couleur de tout contenu SDR dont vous effectuez le rendu.

Étape 1. Obtenir le niveau de blanc de référence SDR actuel

Vous pouvez obtenir le niveau de blanc de référence SDR actuel de l'une des manières suivantes :

Étape 2. Ajustez les valeurs de couleur du contenu SDR

Windows définit le niveau de blanc de référence nominal, ou par défaut, à 80 nits. Par conséquent, si vous effectuez le rendu d'un blanc sRGB standard (1,0, 1,0, 1,0) sur une chaîne d'échange FP16, il sera reproduit à une luminance de 80 nits. Pour faire correspondre le niveau de blanc de référence défini par l'utilisateur, vous devez ajuster le contenu SDR de 80 nits au niveau spécifié par AdvancedColorInfo.SdrWhiteLevelInNits.

Si vous effectuez le rendu en utilisant FP16 et scRGB, ou tout autre espace couleur qui utilise un gamma linéaire (1.0), vous pouvez simplement multiplier la valeur de la couleur SDR par AdvancedColorInfo.SdrWhiteLevelInNits / 80. Si vous utilisez Direct2D, il existe une constante prédéfinie D2D1_SCENE_REFERRED_SDR_WHITE_LEVEL, qui a une valeur de 80.

D2D1_VECTOR_4F inputColor; // Input SDR color value.
D2D1_VECTOR_4F outputColor; // Output color adjusted for SDR white level.
auto acInfo = ...; // Obtain an AdvancedColorInfo.

float sdrAdjust = acInfo->SdrWhiteLevelInNits / D2D1_SCENE_REFERRED_SDR_WHITE_LEVEL;

// Normally in DirectX, color values are manipulated in shaders on GPU textures.
// This example performs scaling on a CPU color value.
outputColor.r = inputColor.r * sdrAdjust; // Assumes linear gamma color values.
outputColor.g = inputColor.g * sdrAdjust;
outputColor.b = inputColor.b * sdrAdjust;
outputColor.a = inputColor.a;

Si vous effectuez le rendu à l'aide d'un espace colorimétrique gamma non linéaire tel que HDR10, l'ajustement du niveau de blanc SDR est plus complexe. Si vous écrivez votre propre pixel shader, envisagez de le convertir en gamma linéaire pour appliquer l'ajustement.

Adaptez le contenu HDR aux capacités de l'écran à l'aide du mappage des tons.

Les capacités des écrans HDR et Advanced Color varient considérablement. Par exemple, en ce qui concerne la luminance minimale et maximale et la gamme de couleurs qu'ils sont capables de reproduire. Dans de nombreux cas, votre contenu HDR contiendra des couleurs qui dépassent les capacités de l'écran. Pour obtenir une qualité d'image optimale, il est important que vous procédiez au mappage des tons HDR, c'est-à-dire que vous compressiez la gamme de couleurs pour l'adapter à l'écran tout en préservant au mieux l'intention visuelle du contenu.

Le paramètre le plus important à adapter est la luminance maximale, également connue sous le nom de MaxCLL (niveau de luminosité du contenu) ; les mappeurs de tons plus sophistiqués adapteront également la luminance minimale (MinCLL) et/ou les primaires de couleur.

Étape 1. Obtenez les capacités de volume de couleur de l'écran

Applications de la plateforme Windows universelle (UWP)

Utilisez AdvancedColorInfo pour obtenir le volume des couleurs de l'écran.

Applications Win32 (bureau) DirectX

Utilisez DXGI_OUTPUT_DESC1 pour obtenir le volume des couleurs de l'écran.

Étape 2. Obtenez les informations sur le volume des couleurs du contenu

Selon l'origine de votre contenu HDR, il existe plusieurs façons de déterminer les informations relatives à la luminance et à la gamme de couleurs. Certains fichiers vidéo et image HDR contiennent des métadonnées SMPTE ST.2086. Si votre contenu a fait l'objet d'un rendu dynamique, vous pouvez extraire des informations sur la scène à partir des étapes de rendu internes, par exemple la source lumineuse la plus brillante de la scène.

Une solution plus générale, mais plus coûteuse en termes de calcul, consiste à exécuter un histogramme ou une autre passe d'analyse sur la trame rendue. L'application d'exemple de rendu d'image couleur avancé Direct2D sur GitHub montre comment faire cela en utilisant Direct2D ; les extraits de code les plus pertinents sont inclus ci-dessous :

// Perform histogram pipeline setup; this should occur as part of image resource creation.
// Histogram results in no visual output but is used to calculate HDR metadata for the image.
void D2DAdvancedColorImagesRenderer::CreateHistogramResources()
{
    auto context = m_deviceResources->GetD2DDeviceContext();

    // We need to preprocess the image data before running the histogram.
    // 1. Spatial downscale to reduce the amount of processing needed.
    DX::ThrowIfFailed(
        context->CreateEffect(CLSID_D2D1Scale, &m_histogramPrescale)
        );

    DX::ThrowIfFailed(
        m_histogramPrescale->SetValue(D2D1_SCALE_PROP_SCALE, D2D1::Vector2F(0.5f, 0.5f))
        );

    // The right place to compute HDR metadata is after color management to the
    // image's native colorspace but before any tonemapping or adjustments for the display.
    m_histogramPrescale->SetInputEffect(0, m_colorManagementEffect.Get());

    // 2. Convert scRGB data into luminance (nits).
    // 3. Normalize color values. Histogram operates on [0-1] numeric range,
    //    while FP16 can go up to 65504 (5+ million nits).
    // Both steps are performed in the same color matrix.
    ComPtr<ID2D1Effect> histogramMatrix;
    DX::ThrowIfFailed(
        context->CreateEffect(CLSID_D2D1ColorMatrix, &histogramMatrix)
        );

    histogramMatrix->SetInputEffect(0, m_histogramPrescale.Get());

    float scale = sc_histMaxNits / sc_nominalRefWhite;

    D2D1_MATRIX_5X4_F rgbtoYnorm = D2D1::Matrix5x4F(
        0.2126f / scale, 0, 0, 0,
        0.7152f / scale, 0, 0, 0,
        0.0722f / scale, 0, 0, 0,
        0              , 0, 0, 1,
        0              , 0, 0, 0);
    // 1st column: [R] output, contains normalized Y (CIEXYZ).
    // 2nd column: [G] output, unused.
    // 3rd column: [B] output, unused.
    // 4th column: [A] output, alpha passthrough.
    // We explicitly calculate Y; this deviates from the CEA 861.3 definition of MaxCLL
    // which approximates luminance with max(R, G, B).

    DX::ThrowIfFailed(histogramMatrix->SetValue(D2D1_COLORMATRIX_PROP_COLOR_MATRIX, rgbtoYnorm));

    // 4. Apply a gamma to allocate more histogram bins to lower luminance levels.
    ComPtr<ID2D1Effect> histogramGamma;
    DX::ThrowIfFailed(
        context->CreateEffect(CLSID_D2D1GammaTransfer, &histogramGamma)
        );

    histogramGamma->SetInputEffect(0, histogramMatrix.Get());

    // Gamma function offers an acceptable tradeoff between simplicity and efficient bin allocation.
    // A more sophisticated pipeline would use a more perceptually linear function than gamma.
    DX::ThrowIfFailed(histogramGamma->SetValue(D2D1_GAMMATRANSFER_PROP_RED_EXPONENT, sc_histGamma));
    // All other channels are passthrough.
    DX::ThrowIfFailed(histogramGamma->SetValue(D2D1_GAMMATRANSFER_PROP_GREEN_DISABLE, TRUE));
    DX::ThrowIfFailed(histogramGamma->SetValue(D2D1_GAMMATRANSFER_PROP_BLUE_DISABLE, TRUE));
    DX::ThrowIfFailed(histogramGamma->SetValue(D2D1_GAMMATRANSFER_PROP_ALPHA_DISABLE, TRUE));

    // 5. Finally, the histogram itself.
    HRESULT hr = context->CreateEffect(CLSID_D2D1Histogram, &m_histogramEffect);
    
    if (hr == D2DERR_INSUFFICIENT_DEVICE_CAPABILITIES)
    {
        // The GPU doesn't support compute shaders and we can't run histogram on it.
        m_isComputeSupported = false;
    }
    else
    {
        DX::ThrowIfFailed(hr);
        m_isComputeSupported = true;

        DX::ThrowIfFailed(m_histogramEffect->SetValue(D2D1_HISTOGRAM_PROP_NUM_BINS, sc_histNumBins));

        m_histogramEffect->SetInputEffect(0, histogramGamma.Get());
    }
}

// Uses a histogram to compute a modified version of MaxCLL (ST.2086 max content light level).
// Performs Begin/EndDraw on the D2D context.
void D2DAdvancedColorImagesRenderer::ComputeHdrMetadata()
{
    // Initialize with a sentinel value.
    m_maxCLL = -1.0f;

    // MaxCLL is not meaningful for SDR or WCG images.
    if ((!m_isComputeSupported) ||
        (m_imageInfo.imageKind != AdvancedColorKind::HighDynamicRange))
    {
        return;
    }

    // MaxCLL is nominally calculated for the single brightest pixel in a frame.
    // But we take a slightly more conservative definition that takes the 99.99th percentile
    // to account for extreme outliers in the image.
    float maxCLLPercent = 0.9999f;

    auto ctx = m_deviceResources->GetD2DDeviceContext();

    ctx->BeginDraw();

    ctx->DrawImage(m_histogramEffect.Get());

    // We ignore D2DERR_RECREATE_TARGET here. This error indicates that the device
    // is lost. It will be handled during the next call to Present.
    HRESULT hr = ctx->EndDraw();
    if (hr != D2DERR_RECREATE_TARGET)
    {
        DX::ThrowIfFailed(hr);
    }

    float *histogramData = new float[sc_histNumBins];
    DX::ThrowIfFailed(
        m_histogramEffect->GetValue(D2D1_HISTOGRAM_PROP_HISTOGRAM_OUTPUT,
            reinterpret_cast<BYTE*>(histogramData),
            sc_histNumBins * sizeof(float)
            )
        );

    unsigned int maxCLLbin = 0;
    float runningSum = 0.0f; // Cumulative sum of values in histogram is 1.0.
    for (int i = sc_histNumBins - 1; i >= 0; i--)
    {
        runningSum += histogramData[i];
        maxCLLbin = i;

        if (runningSum >= 1.0f - maxCLLPercent)
        {
            break;
        }
    }

    float binNorm = static_cast<float>(maxCLLbin) / static_cast<float>(sc_histNumBins);
    m_maxCLL = powf(binNorm, 1 / sc_histGamma) * sc_histMaxNits;

    // Some drivers have a bug where histogram will always return 0. Treat this as unknown.
    m_maxCLL = (m_maxCLL == 0.0f) ? -1.0f : m_maxCLL;
}

Étape 3. Effectuez l'opération de conversion de ton HDR

La cartographie des tons est par nature un processus avec perte et peut être optimisée pour un certain nombre de mesures perceptuelles ou objectives, de sorte qu'il n'existe pas d'algorithme standard unique. Windows fournit un effet de tonemapper HDR intégré dans Direct2D ainsi que dans le pipeline de lecture vidéo HDR de Media Foundation. Parmi les autres algorithmes couramment utilisés, citons ACES Filmic, Reinhard et ITU-R BT.2390-3 EETF (fonction de transfert électrique-électrique).

Un opérateur de tonemapper Reinhard simplifié est présenté dans l'exemple de code suivant.

// This example uses C++. A typical DirectX implementation would port this to HLSL.
D2D1_VECTOR_4F simpleReinhardTonemapper(
    float inputMax, // Content's maximum luminance in scRGB values, e.g. 1.0 = 80 nits.
    float outputMax, // Display's maximum luminance in scRGB values, e.g. 1.0 = 80 nits.
    D2D1_VECTOR_4F input // scRGB color.
)
{
    D2D1_VECTOR_4F output = input;

    // Vanilla Reinhard normalizes color values to [0, 1].
    // This modification scales to the luminance range of the display.
    output.r /= inputMax;
    output.g /= inputMax;
    output.b /= inputMax;

    output.r = output.r / (1 + output.r);
    output.g = output.g / (1 + output.g);
    output.b = output.b / (1 + output.b);

    output.r *= outputMax;
    output.g *= outputMax;
    output.b *= outputMax;

    return output;
}

Capture du contenu de l'écran HDR et WCG

Les API qui prennent en charge la spécification des formats de pixels, telles que celles de l'espace noms Windows.Graphics.Capture, et la méthode IDXGIOutput5::DuplicateOutput1, permettent de capturer du contenu HDR et WCG sans perdre d'informations sur les pixels. Notez qu'après l'acquisition de trames de contenu, un traitement supplémentaire est nécessaire. Par exemple, le mappage des tons HDR vers SDR (par exemple, la copie d'écran SDR pour le partage sur Internet) et l'enregistrement du contenu dans le format approprié (par exemple, JPEG XR).

Modifications de la gestion des couleurs et du comportement des profils ICC

La gestion avancée des couleurs et la gestion automatique des couleurs garantissent des couleurs d'affichage cohérentes et précises d'un point de vue colorimétrique pour toutes les applications, qu'elles soient anciennes ou modernes. Cependant, certaines applications peuvent effectuer leur propre gestion explicite des couleurs en utilisant les profils de couleur de l'International Color Consortium (ICC).

Lorsque la fonction Advanced Color est activée sur les écrans SDR ou HDR, le comportement des profils ICC d'affichage change de manière non rétro-compatible. Si votre application utilise des profils ICC d'affichage, Windows propose des aides à la compatibilité pour garantir que votre application continue à se comporter correctement.

Pour plus d'informations sur les changements de comportement des profils ICC et sur la façon dont vous pouvez adapter votre application pour maximiser la compatibilité avec Advanced Color, reportez-vous à Comportement des profils ICC avec Advanced Color.

Ressources supplémentaires