XR_EXT_spatial_container_self_rendering

Name String

XR_EXT_spatial_container_self_rendering

Type d'extension

Extension d'instance

Numéro d'extension enregistré

814

Révision

1

État de la ratification

Non ratifié

Dépendances d'extension et de version

XR_EXT_spatial_container

Date de dernière modification

2026-08-06

État de l'adresse IP

Aucune réclamation de propriété intellectuelle connue.

Participants

Lachlan Ford, Google
Andreas Loeve Selvik, Meta Platforms
Adam Gousetis, Meta Platforms
Bjorn Swenson, LÖVR
Cass Everitt, Meta Platforms
Christian Kruse, Meta Platforms
Denny Rönngren, Varjo Technologies
Fredia Huya-Kouadio, Godot Engine
Jakob Bornecrantz, NVIDIA
Jared Finder, Google
Jonathan Wright, Meta Platforms
Jian Zhang, ByteDance
Kurtis Eveleigh, Qualcomm
Mauricio Narvaez, Meta Platforms
Nick Klingensmith, Qualcomm
Nikita Lutsenko, Meta Platforms
Praveen Babu J D, ByteDance
Rylie Pavlik, Collabora
Salar Khan, Google
Shuai Liu, ByteDance
Walter Luh, Meta Platforms
Yin Li, Microsoft

Présentation

Cette extension définit l'auto-rendu pour les conteneurs spatiaux. Les pixels d'un conteneur spatial à rendu automatique sont tous générés par une application et envoyés à l'environnement d'exécution à l'aide de swapchains et de couches de composition OpenXR standards. Étant donné que les conteneurs spatiaux n'occupent pas toujours tous les pixels d'un écran, l'environnement d'exécution informe les applications de la résolution et de la configuration d'affichage recommandées pour chaque conteneur spatial afin de leur permettre d'effectuer le rendu plus efficacement.

Cette extension, combinée à XR_EXT_spatial_container, est destinée à offrir un sur-ensemble des fonctionnalités de rendu de la couche de composition principale OpenXR 1.x conventionnelle. Les environnements d'exécution OpenXR 1.x qui prennent en charge l'affichage graphique et cette extension doivent définir XrSystemSpatialContainerPropertiesEXT :: supportsImmersive sur "true" pour indiquer qu'ils sont compatibles avec les conteneurs spatiaux immersifs.

Cycle de vie du rendu des conteneurs spatiaux

Pour utiliser l'auto-rendu pour un conteneur spatial, une application définit XrSpatialContainerCreateInfoEXT :: graphicsPresentation sur XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT lorsqu'elle appelle xrCreateSpatialContainerEXT . Cette application peut ensuite gérer si un conteneur spatial est en cours d'affichage en appelant les fonctions xrBeginSpatialContainerRenderingEXT et xrEndSpatialContainerRenderingEXT. Ces fonctions remplacent xrBeginSession et xrEndSession . Il ne s'agit pas d'opérations par frame, telles que xrBeginFrame et xrEndFrame .

À chaque frame, une application passe par les étapes suivantes :

  • Appelez xrWaitFrame et xrBeginFrame . Ces fonctions n'ont pas de structures spécifiques aux conteneurs et fonctionnent comme dans la spécification de base.
  • Récupérez les poses de vue, les paramètres de projection et les recommandations de rendu pour tous les conteneurs spatiaux qui s'affichent activement avec xrLocateSpatialContainerViewsEXT . Pour chaque conteneur spatial, l'environnement d'exécution indique si ses couches de composition doivent être affichées et la méthode recommandée pour afficher les couches en remplissant XrSpatialContainerViewStateEXT .
  • Affichez les pixels dans les couches de composition normalement. Ces opérations n'ont pas de structures spécifiques aux conteneurs.
  • Envoyez des couches de composition pour tous les conteneurs spatiaux en cours d'affichage en appelant xrEndFrame et en chaînant XrSpatialContainerLayerFrameEndInfoEXT .

La destruction d'un handle XrSpatialContainerEXT le supprime implicitement de l'ensemble de rendu actif. Une application peut détruire un conteneur spatial même si elle a effectué un appel réussi à xrBeginSpatialContainerRenderingEXT non associé à un appel correspondant à xrEndSpatialContainerRenderingEXT . L'environnement d'exécution doit se comporter comme si xrEndSpatialContainerRenderingEXT était appelé implicitement si nécessaire au début de l'implémentation de xrDestroySpatialContainerEXT s'il renvoie un résultat positif.

Lorsqu'une application reçoit un événement XrEventDataSpatialContainerClosedEXT pour un conteneur de l'ensemble de rendu actif, elle doit appeler xrEndSpatialContainerRenderingEXT et détruire le handle XrSpatialContainerEXT.

La fonction xrBeginSpatialContainerRenderingEXT ajoute le conteneur spatial à l'ensemble de rendu actif par session, ce qui permet à une application d'envoyer des couches de composition pour le conteneur spatial à xrEndFrame .

XrResult xrBeginSpatialContainerRenderingEXT(
    XrSession                                   session,
    const XrSpatialContainerBeginInfoEXT*       beginInfo);

Description des paramètres

Les applications appellent généralement cette fonction en réponse à un événement de changement de visibilité avec XrEventDataSpatialContainerVisibleChangedEXT :: visible défini sur "true".

Si le conteneur spatial n'a pas été créé avec XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT lors de l'appel de xrCreateSpatialContainerEXT , l'environnement d'exécution doit renvoyer XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT .

Si le conteneur spatial se trouve déjà dans l'ensemble de rendu actif, l'environnement d'exécution doit renvoyer XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT .

Si xrBeginSpatialContainerRenderingEXT est appelé à un moment où l'application ne peut pas appeler xrWaitFrame (c'est-à-dire dans la fenêtre xrBeginFrame et xrEndFrame), l'environnement d'exécution doit renvoyer XR_ERROR_CALL_ORDER_INVALID .

Utilisation valide (implicite)

Thread safety

Codes renvoyés

Opération réussie

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Échec

  • XR_ERROR_CALL_ORDER_INVALID
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT
  • XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED

La structure XrSpatialContainerBeginInfoEXT permet de spécifier les paramètres de début de rendu d'un conteneur spatial.

typedef struct XrSpatialContainerBeginInfoEXT {
    XrStructureType            type;
    const void*                next;
    XrSpatialContainerEXT      spatialContainer;
    XrViewConfigurationType    primaryViewConfigurationType;
} XrSpatialContainerBeginInfoEXT;

Description du membre

  • type est le XrStructureType de cette structure.
  • next est NULL ou un pointeur vers la structure suivante dans une chaîne de structures.
  • spatialContainer est l'élément XrSpatialContainerEXT pour commencer l'affichage.
  • primaryViewConfigurationType est le XrViewConfigurationType principal à utiliser pour le conteneur spatial.

primaryViewConfigurationType est la configuration de vue que l'application prévoit d'utiliser lors de l'affichage. L'environnement d'exécution peut dégrader la configuration de la vue vers un type comportant moins de vues à des fins d'optimisation (par exemple, un conteneur est très éloigné et petit, de sorte que la stéréo est imperceptible). L'environnement d'exécution renvoie des détails sur la configuration de la vue dégradée à partir des appels à xrLocateSpatialContainerViewsEXT .

Utilisation valide (implicite)

La fonction xrEndSpatialContainerRenderingEXT supprime le conteneur spatial de l'ensemble de rendu actif.

XrResult xrEndSpatialContainerRenderingEXT(
    XrSession                                   session,
    const XrSpatialContainerEndInfoEXT*         endInfo);

Description des paramètres

Les applications appellent généralement cette fonction en réponse à un événement de modification de visibilité avec XrEventDataSpatialContainerVisibleChangedEXT :: visible défini sur "false".

Si le conteneur spatial ne se trouve pas dans l'ensemble de rendu actif, l'environnement d'exécution doit renvoyer XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .

Si xrEndSpatialContainerRenderingEXT est appelé à un moment où l'application n'a pas pu appeler xrWaitFrame (c'est-à-dire entre les appels xrBeginFrame et xrEndFrame), l'environnement d'exécution doit renvoyer XR_ERROR_CALL_ORDER_INVALID.

Utilisation valide (implicite)

Thread safety

Codes renvoyés

Opération réussie

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Échec

  • XR_ERROR_CALL_ORDER_INVALID
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT
  • XR_ERROR_VALIDATION_FAILURE

La structure XrSpatialContainerEndInfoEXT permet de spécifier les paramètres de fin de rendu d'un conteneur spatial.

typedef struct XrSpatialContainerEndInfoEXT {
    XrStructureType          type;
    const void*              next;
    XrSpatialContainerEXT    spatialContainer;
} XrSpatialContainerEndInfoEXT;

Description du membre

  • type est le XrStructureType de cette structure.
  • next est NULL ou un pointeur vers la structure suivante dans une chaîne de structures.
  • spatialContainer est l'XrSpatialContainerEXT pour lequel arrêter l'affichage.

Utilisation valide (implicite)

Localiser des vues via xrLocateSpatialContainerViewsEXT

La fonction xrLocateSpatialContainerViewsEXT localise les vues d'un ensemble de conteneurs spatiaux.

XrResult xrLocateSpatialContainerViewsEXT(
    XrSession                                   session,
    const XrSpatialContainerViewsLocateInfoEXT* locateInfo,
    uint32_t                                    viewStateCount,
    XrSpatialContainerViewStateEXT*             viewStates,
    uint32_t                                    viewCount,
    XrView*                                     views);

Description des paramètres

  • session est l'XrSession .
  • locateInfo est un pointeur vers une structure XrSpatialContainerViewsLocateInfoEXT.
  • viewStateCount est le nombre d'éléments du tableau viewStates.
  • viewStates est un pointeur vers un tableau de structures XrSpatialContainerViewStateEXT à remplir par l'environnement d'exécution.
  • viewCount est le nombre d'éléments du tableau views.
  • views est un pointeur vers un tableau de structures XrView.

Cette fonction remplace xrLocateViews , ce qui permet à une application d'interroger des vues pour plusieurs conteneurs spatiaux simultanément.

Les vues de tous les conteneurs spatiaux sont renvoyées dans le tableau views unique. Les vues sont classées en fonction de l'index du conteneur spatial dans le tableau XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos, puis de l'index de vue de ce conteneur.

Par exemple, si une application fournit trois conteneurs spatiaux dans XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos :

  • Index 0 : XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO (1 vue)
  • Index 1 : XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO (2 vues)
  • Index 2 : XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO_WITH_FOVEATED_INSET (4 vues)

L'environnement d'exécution doit ensuite remplir le tableau views avec sept vues :

  • views [0] est la vue du conteneur 0.
  • views [1] est la vue de l'œil gauche pour le conteneur 1.
  • views [2] est la vue de l'œil droit pour le conteneur 1.
  • views [3] est la vue de l'œil gauche pour le conteneur 2.
  • views [4] est la vue de l'œil droit pour le conteneur 2.
  • views [5] est la vue en incrustation de l'œil gauche pour le conteneur 2.
  • views [6] est la vue en incrustation de l'œil droit pour le conteneur 2.

Si viewCount n'est pas égal à la somme des nombres de vues pour chaque type de configuration de vue demandé du conteneur spatial, l'environnement d'exécution doit renvoyer XR_ERROR_VALIDATION_FAILURE .

L'environnement d'exécution peut dégrader la configuration de la vue vers un type comportant moins de vues à des fins d'optimisation (par exemple, un conteneur est très éloigné et petit, de sorte que la stéréo est imperceptible). Si l'environnement d'exécution dégrade la configuration de la vue, il doit toujours renvoyer le nombre d'origine de vues pour ce conteneur, en remplissant les vues supplémentaires avec des doublons des vues dégradées. Par exemple, si XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO est dégradé en XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO , l'index 0 et l'index 1 contiendront tous deux la vue mono unique. Par conséquent, le nombre total de vues renvoyées dans le tableau views ne dépend pas de la décision de l'environnement d'exécution de dégrader ou non les configurations de vue.

L'environnement d'exécution doit adapter chaque XrView :: fov renvoyé de sorte que le tronc soit aussi petit que possible tout en contenant l'intégralité des limites du conteneur spatial correspondant. Les environnements d'exécution peuvent renvoyer des champs de vision non symétriques, par exemple si un conteneur spatial est incliné par rapport à la vue de l'utilisateur ou s'il est partiellement masqué par un autre objet. Les environnements d'exécution peuvent positionner librement la surface de rendu cible pour le conteneur spatial. En raison de la nature du rendu multi-application, où les conteneurs spatiaux sont détachés de l'utilisateur, l'environnement d'exécution peut renvoyer des valeurs XrView qui ne sont pas adaptées au rendu des pixels. Par exemple, si le conteneur spatial n'est pas visible à l'écran, il n'existe aucune valeur valide pour définir XrView :: fov. Dans ce cas, les environnements d'exécution doivent définir XrSpatialContainerViewStateEXT :: shouldSubmitLayers sur "false".

L'environnement d'exécution renvoie des informations supplémentaires sur l'état de rendu par conteneur spatial dans le tableau viewStates. Si viewStateCount n'est pas égal à XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfoCount , l'environnement d'exécution doit renvoyer XR_ERROR_VALIDATION_FAILURE .

Une fois que l'environnement d'exécution a mis en file d'attente un événement XrEventDataSpatialContainerClosedEXT pour un conteneur spatial, cette fonction doit renvoyer XR_FALSE dans XrSpatialContainerViewStateEXT :: shouldSubmitLayers et 0 dans XrSpatialContainerViewStateEXT :: viewStateFlags pour le conteneur spatial correspondant.

Pour les conteneurs spatiaux dont l'emplacement change activement dans le monde réel, l'environnement d'exécution doit prendre en compte le mouvement du conteneur lors du remplissage de views afin de minimiser les artefacts de reprojection.

Si xrLocateSpatialContainerViewsEXT est appelé pour un ou plusieurs conteneurs spatiaux qui ne figurent pas actuellement dans l'ensemble de rendu actif, l'environnement d'exécution doit renvoyer XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .

Utilisation valide (implicite)

Codes renvoyés

Opération réussie

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Échec

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT
  • XR_ERROR_TIME_INVALID
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED

La structure XrSpatialContainerViewsLocateInfoEXT contient les paramètres permettant de localiser les vues dans une collection de conteneurs spatiaux.

typedef struct XrSpatialContainerViewsLocateInfoEXT {
    XrStructureType                               type;
    const void*                                   next;
    XrTime                                        displayTime;
    uint32_t                                      viewLocateInfoCount;
    const XrSpatialContainerViewLocateInfoEXT*    viewLocateInfos;
} XrSpatialContainerViewsLocateInfoEXT;

Description du membre

  • type est le XrStructureType de cette structure.
  • next est NULL ou un pointeur vers la structure suivante dans une chaîne de structures.
  • displayTime est l'XrTime où se trouvent les vues.
  • viewLocateInfoCount est le nombre d'entrées dans le tableau viewLocateInfos.
  • viewLocateInfos est un pointeur vers un tableau de structures XrSpatialContainerViewLocateInfoEXT.

Utilisation valide (implicite)

La structure XrSpatialContainerViewLocateInfoEXT contient les paramètres d'un conteneur spatial individuel pour lequel localiser des vues.

typedef struct XrSpatialContainerViewLocateInfoEXT {
    XrStructureType            type;
    const void*                next;
    XrViewConfigurationType    viewConfigurationType;
    XrSpace                    space;
    XrSpatialContainerEXT      spatialContainer;
} XrSpatialContainerViewLocateInfoEXT;

Description du membre

  • type est le XrStructureType de cette structure.
  • next est NULL ou un pointeur vers la structure suivante dans une chaîne de structures.
  • viewConfigurationType est un XrViewConfigurationType à utiliser pour le conteneur spatial.
  • space est l'XrSpace dans lequel se trouvent les vues du conteneur spatial.
  • spatialContainer est le handle XrSpatialContainerEXT.

L'application peut fournir n'importe quel XrSpace valide dans space . Toutefois, il est recommandé de fournir l'espace du conteneur spatial pour le XrSpatialContainerEXT correspondant spécifié dans la structure XrSpatialContainerViewLocateInfoEXT.

Utilisation valide (implicite)

La structure XrSpatialContainerViewStateEXT est renseignée par des appels à xrLocateSpatialContainerViewsEXT avec des informations sur l'adéquation du rendu par conteneur spatial.

typedef struct XrSpatialContainerViewStateEXT {
    XrStructureType            type;
    void*                      next;
    XrViewStateFlags           viewStateFlags;
    XrViewConfigurationType    viewConfigurationType;
    XrBool32                   shouldSubmitLayers;
    XrExtent2Di                recommendedImageExtent;
} XrSpatialContainerViewStateEXT;

Description du membre

  • type est le XrStructureType de cette structure.
  • next est NULL ou un pointeur vers la structure suivante dans une chaîne de structures.
  • viewStateFlags est un masque de bits de XrViewStateFlags . Ces indicateurs ont le même objectif que les viewStateFlags de la structure XrViewState principale.
  • viewConfigurationType est un XrViewConfigurationType qui indique le type de configuration de vue que l'environnement d'exécution utilise pour le conteneur spatial, que les environnements d'exécution peuvent dégrader en une configuration de vue avec un nombre de vues inférieur à celui demandé.
  • shouldSubmitLayers est un XrBool32 renvoyé par l'environnement d'exécution. Si XR_FALSE, l'application doit éviter d'envoyer la composition pour ce conteneur spatial, car il n'est actuellement pas visible ou se trouve dans un état où l'affichage n'est pas requis.
  • recommendedImageExtent est une structure XrExtent2Di représentant la résolution recommandée pour le conteneur spatial.

Comme pour l'emplacement de la vue OpenXR de base, l'application doit vérifier XrSpatialContainerViewStateEXT :: viewStateFlags pour s'assurer que la position et l'orientation sont valides et suivies avant d'utiliser les données de la vue pour l'affichage.

L'application doit vérifier shouldSubmitLayers et viewConfigurationType pour éviter d'afficher plus d'éléments que ce que l'environnement d'exécution recommande. Lorsque shouldSubmitLayers est défini sur "false", l'application modifie son comportement d'affichage comme suit :

  • L'application ne doit pas lire l'élément XrView :: fov correspondant.
  • L'application ne doit pas lire recommendedImageExtent .
  • L'application doit éviter d'effectuer le rendu sur des chaînes d'échange et d'envoyer des couches de composition pour le conteneur spatial correspondant.
  • L'application doit définir XrSpatialContainerLayerEXT :: retainPreviousSubmission sur "true". Si l'application choisit quand même d'envoyer des couches, c'est à l'environnement d'exécution de déterminer ce qu'il veut en faire (par exemple, l'environnement d'exécution peut choisir de les supprimer).

recommendedImageExtent est explicitement destiné aux calques qui seront mis à jour en fonction de la position du conteneur ou de la vue de l'utilisateur. Lors de la mise à jour de calques avec du contenu qui dépend de la position du conteneur spatial ou de la vue de l'utilisateur (comme du contenu 3D normal), l'application doit effectuer l'affichage dans cette fenêtre d'affichage plus petite au lieu de la taille de vue recommandée par défaut. Lors de la mise à jour de couches avec du contenu qui ne dépend pas de la position du conteneur spatial ou de la vue de l'utilisateur (comme les couches quad statiques), l'application peut ignorer ces valeurs en toute sécurité. Pour les couches dépendantes de la vue, recommendedImageExtent est une recommandation envoyée à l'application par l'environnement d'exécution, destinée à minimiser l'aliasing et à améliorer les performances de rendu. L'application est libre d'envoyer des images en résolution maximale si elle le souhaite.

XrExtent2Di :: width et XrExtent2Di :: height de recommendedImageExtent doivent toujours être un entier positif inférieur ou égal à XrViewConfigurationView :: recommendedImageRectWidth et XrViewConfigurationView :: recommendedImageRectHeight de XrViewConfigurationView pour la configuration de la vue principale du conteneur spatial. Une application ne doit pas recréer de swapchain uniquement parce que recommendedImageExtent a changé, car il s'agit d'une indication dynamique pour l'application spécifiant le XrSwapchainSubImage :: imageRect à utiliser dans le XrSwapchainSubImage de toutes les couches de composition en résolution maximale qu'elle envoie, et peut changer à chaque frame.

Utilisation valide (implicite)

Afficher l'espace de référence

L'espace de référence de la vue reste inchangé, car il se trouve dans le noyau OpenXR. Comme dans le cas de "core", il n'est pas destiné à être utilisé pour l'affichage.

Envoi de calques via xrEndFrame

Pour afficher les conteneurs spatiaux, l'application doit fournir à xrEndFrame une liste de couches associées à leurs conteneurs spatiaux respectifs. Pour ce faire, utilisez la structure XrSpatialContainerLayerFrameEndInfoEXT.

typedef struct XrSpatialContainerLayerFrameEndInfoEXT {
    XrStructureType                      type;
    const void*                          next;
    uint32_t                             containerLayerCount;
    const XrSpatialContainerLayerEXT*    containerLayers;
} XrSpatialContainerLayerFrameEndInfoEXT;

Description du membre

  • type est le XrStructureType de cette structure.
  • next est NULL ou un pointeur vers la structure suivante dans une chaîne de structures.
  • containerLayerCount est le nombre d'éléments du tableau containerLayers.
  • containerLayers est un pointeur vers un tableau de structures XrSpatialContainerLayerEXT.

Le tableau containerLayers contient un XrSpatialContainerLayerEXT pour chaque conteneur spatial de l'ensemble de rendu actif (les conteneurs gérés par session par xrBeginSpatialContainerRenderingEXT et xrEndSpatialContainerRenderingEXT). Chaque XrSpatialContainerLayerEXT contient une liste de pointeurs XrCompositionLayerBaseHeader associés au conteneur spatial donné. Les environnements d'exécution peuvent composer des conteneurs dans l'ordre de leur choix, indépendamment de l'ordre du containerLayers . Par exemple, les environnements d'exécution peuvent composer des conteneurs en fonction de leur profondeur par rapport à l'utilisateur, faire en sorte qu'un conteneur spatial agisse comme une couche d'arrière-plan ou "épingler" un conteneur spatial de sorte qu'il soit toujours au premier plan, quelle que soit sa profondeur. Les environnements d'exécution peuvent composer des couches à l'aide de différentes stratégies pour les conteneurs spatiaux en mode limité ou immersif. Par exemple, les environnements d'exécution peuvent précomposer les couches de composition de chaque conteneur spatial délimité en une seule couche stéréo quad, qui est combinée avec tous les autres conteneurs lors d'une deuxième étape de composition.

XrFrameEndInfo :: displayTime et XrFrameEndInfo :: environmentBlendMode seront appliqués à tous les conteneurs spatiaux fournis dans XrSpatialContainerLayerFrameEndInfoEXT .

Lorsque cette structure est transmise à xrEndFrame en étant enchaînée à XrFrameEndInfo , les cas d'erreur supplémentaires suivants sont ajoutés en fonction de l'ensemble de rendu actif :

  • Si un conteneur spatial est référencé par plusieurs éléments de containerLayers , les environnements d'exécution doivent renvoyer XR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXT .
  • Si un conteneur spatial de l'ensemble de rendu actif n'est pas référencé par un élément de containerLayers , les environnements d'exécution doivent renvoyer XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT .
  • Si un conteneur spatial référencé par containerLayers n'est pas membre de l'ensemble de rendu actif, les environnements d'exécution doivent renvoyer XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .

De plus, s'il existe des conteneurs spatiaux dans l'ensemble de rendu actif et que cette structure n'est pas enchaînée à XrFrameEndInfo , les environnements d'exécution doivent renvoyer XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT .

Dans l'un des cas d'erreur ci-dessus, l'environnement d'exécution ne doit pas afficher de contenu pour un conteneur spatial.

Si aucun conteneur spatial ne se trouve dans l'ensemble de rendu actif, une application peut appeler xrEndFrame tant qu'elle n'envoie pas de couches de composition.

Notez que des chaînes d'échange individuelles peuvent être envoyées pour plusieurs conteneurs via des couches dans une structure valide (par exemple, une couche quad rendue via une seule chaîne d'échange envoyée à plusieurs conteneurs spatiaux). Ce cas est traité de manière uniforme avec les autres rendus : l'environnement d'exécution doit afficher le quad dans tous ces conteneurs spatiaux.

Utilisation valide (implicite)

La structure XrSpatialContainerLayerEXT regroupe les couches de composition standards et les associe à un conteneur spatial spécifique.

typedef struct XrSpatialContainerLayerEXT {
    XrStructureType                               type;
    const void*                                   next;
    XrSpatialContainerEXT                         spatialContainer;
    XrBool32                                      retainPreviousSubmission;
    uint32_t                                      layerCount;
    const XrCompositionLayerBaseHeader* const*    layers;
} XrSpatialContainerLayerEXT;

Description du membre

  • type est le XrStructureType de cette structure.
  • next est NULL ou un pointeur vers la structure suivante dans une chaîne de structures.
  • spatialContainer est l'XrSpatialContainerEXT identifiant le conteneur cible.
  • retainPreviousSubmission est un XrBool32 . Si la valeur est XR_TRUE , l'environnement d'exécution conserve la dernière image envoyée pour ce conteneur spatial.
  • layerCount est le nombre de couches de composition dans le tableau layers.
  • layers est un pointeur vers un tableau de pointeurs XrCompositionLayerBaseHeader.

Lorsque retainPreviousSubmission est XR_TRUE , l'environnement d'exécution doit réutiliser les couches de composition et le contenu de l'image de la chaîne d'échange tels qu'ils ont été verrouillés lors de l'appel xrEndFrame le plus récent où retainPreviousSubmission était XR_FALSE . Toute modification ultérieure des chaînes d'échange utilisées par les calques conservés ne doit pas être reflétée dans le résultat affiché.

Pour les calques envoyés pour un conteneur spatial individuel (rendu intra-conteneur), l'environnement d'exécution doit suivre les règles déjà spécifiées pour l'ordre de composition des calques. Autrement dit, les couches des conteneurs doivent être dessinées dans l'ordre dans lequel elles sont spécifiées, composées via l'algorithme du peintre.

"Effacer" un conteneur spatial consiste à supprimer tout le contenu d'un conteneur spatial, de sorte que rien ne soit affiché pour ce conteneur dans l'image actuelle. Les environnements d'exécution doivent traiter cette valeur comme si l'application envoyait du noir transparent (tous les bits à 0) pour chaque pixel du conteneur. "Conserver" un conteneur spatial signifie que l'environnement d'exécution continue d'afficher l'ensemble de couches le plus récemment envoyé pour ce conteneur.

Pour chaque conteneur spatial, l'application peut spécifier s'il faut envoyer de nouvelles couches, conserver l'envoi précédent ou vider le conteneur spatial :

  • Pour envoyer de nouvelles couches, l'application fournit un layerCount non nul et un pointeur layers valide.
  • Pour effacer un conteneur spatial, la valeur layerCount de son entrée doit être 0 et la valeur retainPreviousSubmission doit être XR_FALSE .
  • Pour conserver les dernières couches et images de chaîne d'échange envoyées, la valeur layerCount de l'entrée doit être 0 et retainPreviousSubmission doit être XR_TRUE .

Ce contrôle explicite par conteneur garantit que l'intention de l'application est clairement communiquée dans chaque frame.

Si retainPreviousSubmission est défini sur XR_TRUE et que layerCount n'est pas égal à 0, l'environnement d'exécution doit renvoyer XR_ERROR_VALIDATION_FAILURE .

Si XrSpatialContainerCompositionLayerViewConfigurationEXT n'est pas associé à un XrCompositionLayerProjection faisant partie d'un conteneur spatial, l'environnement d'exécution doit renvoyer XR_ERROR_VALIDATION_FAILURE . Cette structure ne s'applique qu'aux couches XrCompositionLayerProjection. S'il est associé à d'autres types de calques (par exemple, des calques quad ou cylindriques), l'environnement d'exécution doit renvoyer XR_ERROR_VALIDATION_FAILURE.

Utilisation valide (implicite)

Spécifier la configuration de la vue pour les couches de projection

La structure XrSpatialContainerCompositionLayerViewConfigurationEXT permet de spécifier la configuration de vue utilisée pour afficher une couche de projection pour un conteneur spatial.

typedef struct XrSpatialContainerCompositionLayerViewConfigurationEXT {
    XrStructureType            type;
    const void*                next;
    XrViewConfigurationType    viewConfigurationType;
} XrSpatialContainerCompositionLayerViewConfigurationEXT;

Description du membre

Lors de l'envoi d'un XrCompositionLayerProjection pour un conteneur spatial, l'application doit spécifier la configuration de vue utilisée pour afficher la couche. Cela est nécessaire, car l'application peut choisir pour chaque frame d'effectuer le rendu avec la configuration de vue principale du conteneur spatial ou avec la configuration de vue dégradée suggérée par l'environnement d'exécution, le cas échéant.

Lorsque XrSpatialContainerCompositionLayerViewConfigurationEXT est chaîné, l'application doit s'assurer que XrCompositionLayerProjection :: viewCount est un nombre de vues valide pour le XrViewConfigurationType spécifié dans la structure chaînée. Le viewConfigurationType spécifié dans la structure enchaînée doit être le XrSpatialContainerBeginInfoEXT :: primaryViewConfigurationType spécifié au début du conteneur, ou le type de configuration de vue dégradée renvoyé par l'environnement d'exécution dans XrSpatialContainerViewStateEXT , ou des valeurs supplémentaires activées via une extension.

Utilisation valide (implicite)

Comportement de découpage des pixels

Les applications doivent informer l'environnement d'exécution si elles affichent ou non des pixels en dehors des limites d'un conteneur spatial en associant XrSpatialContainerLayerVolumeClippingEXT lors de l'envoi des couches de composition.

typedef struct XrSpatialContainerLayerVolumeClippingEXT {
    XrStructureType                        type;
    const void*                            next;
    XrSpatialContainerVolumeClippingEXT    volumeClipping;
} XrSpatialContainerLayerVolumeClippingEXT;

Description du membre

Cette structure sert d'indice pour indiquer si l'application affiche des pixels en dehors des limites d'un conteneur spatial. Lorsqu'un conteneur spatial est en mode immersif, cette indication n'a pas de sens, car les limites sont infinies.

Pour les conteneurs spatiaux délimités utilisant l'auto-rendu, l'environnement d'exécution doit prendre en compte à la fois les limites du volume 3D et les limites des pixels 2D. Les limites du volume 3D sont renvoyées par xrGetSpatialContainerBoundsEXT . Les limites de pixels 2D sont la projection des limites de volume 3D sur chaque écran du système.

Les environnements d'exécution doivent supprimer les pixels des images de la chaîne d'échange en dehors des limites de pixels 2D. Toutefois, les environnements d'exécution ne doivent pas supprimer les pixels qui se trouvent dans les limites de pixels 2D, mais en dehors des limites de volume 3D. Il est possible d'utiliser des effets stéréo où le contenu semble s'étendre au-delà ou devant les limites du volume 3D du conteneur. Les applications peuvent supprimer les pixels en dehors des limites du volume 3D d'un conteneur spatial délimité pour réduire les paradoxes de profondeur et doivent définir volumeClipping en fonction de la manière dont elles le font. Les paradoxes de profondeur provoquent souvent une fatigue oculaire et une gêne pour l'utilisateur.

Les environnements d'exécution peuvent utiliser volumeClipping pour ajuster la façon dont ils affichent un conteneur spatial particulier. Par exemple, lorsqu'il est défini sur XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT, un environnement d'exécution peut afficher les faces arrière des limites du volume 3D, ce qui entraînerait des paradoxes de profondeur si le conteneur spatial dessinait des pixels derrière les limites du volume 3D du conteneur.

Les futures extensions pourront permettre le découpage en fonction des limites du volume 3D si des informations de profondeur sont fournies.

Utilisation valide (implicite)

Nouvelles commandes

Nouvelles structures

Nouvelles constantes d'énumération

  • XR_EXT_SPATIAL_CONTAINER_SELF_RENDERING_EXTENSION_NAME
  • XR_EXT_spatial_container_self_rendering_SPEC_VERSION
  • Extension de XrResult :

    • XR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXT
    • XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT
    • XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT
    • XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT
    • XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT
  • Extension de XrSpatialContainerGraphicsPresentationEXT :

    • XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
  • Extension de XrStructureType :

    • XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_COMPOSITION_LAYER_VIEW_CONFIGURATION_EXT
    • XR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_LAYER_EXT
    • XR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT
    • XR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXT

Exemples de code

// Example: Complete lifecycle, view location, and frame submission for spatial containers
PFN_xrBeginSpatialContainerRenderingEXT xrBeginSpatialContainerRenderingEXT; // previously initialized
PFN_xrEndSpatialContainerRenderingEXT xrEndSpatialContainerRenderingEXT; // previously initialized
PFN_xrLocateSpatialContainerViewsEXT xrLocateSpatialContainerViewsEXT; // previously initialized

XrSession session; // previously initialized

// We want to update this container
XrSpatialContainerEXT containerA; // previously initialized with XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
XrSpace containerASpace; // previously initialized

// We want to retain this container
XrSpatialContainerEXT containerB; // previously initialized with XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
XrSpace containerBSpace; // previously initialized

// 1. Add to active render set when the app is ready to start submitting layers
XrSpatialContainerBeginInfoEXT beginInfoA {
  .type = XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT,
  .spatialContainer = containerA,
  .primaryViewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
};
CHK_XR(xrBeginSpatialContainerRenderingEXT(session, &beginInfoA));

XrSpatialContainerBeginInfoEXT beginInfoB {
  .type = XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT,
  .spatialContainer = containerB,
  .primaryViewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
};
CHK_XR(xrBeginSpatialContainerRenderingEXT(session, &beginInfoB));

// ... Frame Loop ...


XrTime displayTime; // returned from xrWaitFrame

const std::vector<XrSpatialContainerEXT> containers = {containerA, containerB};
const std::vector<XrSpace> containerSpaces = {containerASpace, containerBSpace};
uint32_t containerCount = static_cast<uint32_t>(containers.size());

// 2. Setup individual locate info for each container
std::vector<XrSpatialContainerViewLocateInfoEXT> containerLocateInfos(containerCount, {
  .type = XR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXT,
});

for (uint32_t i = 0; i < containerCount; ++i) {
    containerLocateInfos[i].viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
    containerLocateInfos[i].space = containerSpaces[i]; // Recommended to use container's own space
    containerLocateInfos[i].spatialContainer = containers[i];
}

// Setup bulk locate info
XrSpatialContainerViewsLocateInfoEXT locateInfo {
  .type = XR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXT,
  .displayTime = displayTime,
  .viewLocateInfoCount = containerCount,
  .viewLocateInfos = containerLocateInfos.data(),
};

// Prepare states to be populated by the runtime
std::vector<XrSpatialContainerViewStateEXT> viewStates(containerCount, {
  .type = XR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXT,
});

// Call the dedicated locate views function
// We know the required view count is 2 per container for STEREO
const uint32_t viewsPerConfig = 2;
uint32_t totalViewCount = containerCount * viewsPerConfig;
std::vector<XrView> views(totalViewCount, {.type = XR_TYPE_VIEW});

CHK_XR(xrLocateSpatialContainerViewsEXT(session, &locateInfo, containerCount, viewStates.data(), totalViewCount, views.data()));

// Process results
for (uint32_t i = 0; i < containerCount; ++i) {
    XrBool32 shouldSubmitLayers = viewStates[i].shouldSubmitLayers;
    XrExtent2Di recommendedImageExtent = viewStates[i].recommendedImageExtent;
    XrViewConfigurationType viewConfigurationType = viewStates[i].viewConfigurationType;
    bool isDecayedToMono = (viewConfigurationType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO);
    if (shouldSubmitLayers) {
        // App is expected to also verify viewStates[i].viewStateFlags has valid orientation/position bits before rendering
        XrView& leftView = views[i * viewsPerConfig];
        XrView& rightView = views[i * viewsPerConfig + 1];
        // If isDecayedToMono is true, left and right will be identical.
    } else {
        // Skip layer submission but retain previous submission when calling
        // xrEndFrame.
    }
}

// 3. Setup projection layer for container A
XrCompositionLayerProjection projectionLayer = {.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION};
// ... standard projection layer setup (space, viewCount, views, etc.) ...

// Specify which view configuration was used to render this specific layer
XrSpatialContainerCompositionLayerViewConfigurationEXT containerViewConfig {
  .type = XR_TYPE_SPATIAL_CONTAINER_COMPOSITION_LAYER_VIEW_CONFIGURATION_EXT,
  // Even if the runtime decayed to MONO, we indicate what we actually rendered
  .viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
};

// Chain it to the projection layer
projectionLayer.next = &containerViewConfig;
const XrCompositionLayerBaseHeader* layersA[1] = {reinterpret_cast<const XrCompositionLayerBaseHeader*>(&projectionLayer)};

// Note: In a real app, you are required to submit ALL active containers in the render set.

XrSpatialContainerLayerVolumeClippingEXT containerClippingA = {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT,
  // Set volumeClipping appropriately for the rendering done.
  .volumeClipping = XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT,
};

// Setup container A (Update with new pixels)
XrSpatialContainerLayerEXT containerLayerA {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_EXT,
  .next = &containerClippingA,
  .spatialContainer = containerA,
  .retainPreviousSubmission = XR_FALSE,
  .layerCount = 1,
  .layers = layersA,
};

XrSpatialContainerLayerVolumeClippingEXT containerClippingB {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT,
  // Set volumeClipping appropriately for the rendering done.
  .volumeClipping = XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT,
};

// Setup container B (Explicitly retain previous frame)
XrSpatialContainerLayerEXT containerLayerB {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_EXT,
  .next = &containerClippingB,
  .spatialContainer = containerB,
  .retainPreviousSubmission = XR_TRUE,
  .layerCount = 0, // Required to be 0 when retaining
  .layers = nullptr,
};

// Aggregate all container layers
XrSpatialContainerLayerEXT containerLayers[] = { containerLayerA, containerLayerB };

XrSpatialContainerLayerFrameEndInfoEXT spatialEndInfo {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXT,
  .containerLayerCount = 2, // Must equal the number of active containers
  .containerLayers = containerLayers,
};

XrFrameEndInfo frameEndInfo {
  .type = XR_TYPE_FRAME_END_INFO,
  .next = &spatialEndInfo,
  .displayTime = displayTime,
  .environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND,
  .layerCount = 0, // MANDATORY: Must be 0 for self rendering extension
};

CHK_XR(xrEndFrame(session, &frameEndInfo));

// ... End Frame Loop ...

// 4. Remove from active render set when the container is destroyed or no longer needs rendering
XrSpatialContainerEndInfoEXT endInfoA {
  .type = XR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT,
  .spatialContainer = containerA,
};
CHK_XR(xrEndSpatialContainerRenderingEXT(session, &endInfoA));

XrSpatialContainerEndInfoEXT endInfoB {
  .type = XR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT,
  .spatialContainer = containerB,
};
CHK_XR(xrEndSpatialContainerRenderingEXT(session, &endInfoB));

Historique des versions

  • Révision 1, 06/08/2026 (Lachlan Ford)

    • Description initiale de l'extension