XR_EXT_spatial_container_self_rendering
מחרוזת שם
XR_EXT_spatial_container_self_rendering
סוג התוסף
תוסף למכונה
מספר השלוחה הרשום
814
גרסה
1
סטטוס האישור
לא אושר
תלויות של תוספים וגרסאות
XR_EXT_spatial_container
תאריך השינוי האחרון
2026-08-06
סטטוס IP
אין תלונות ידועות על הפרת קניין רוחני.
שותפים ביצירת התוכן
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
סקירה כללית
התוסף הזה מגדיר "עיבוד עצמי" למאגרים מרחביים. כל הפיקסלים של קונטיינר מרחבי שמעובד באופן עצמאי נוצרים על ידי אפליקציה ונשלחים לסביבת זמן הריצה באמצעות שרשראות החלפה (swapchains) ושכבות קומפוזיציה רגילות של OpenXR. מכיוון שקונטיינרים מרחביים לא תמיד תופסים את כל הפיקסלים של המסך, סביבת זמן הריצה מודיעה לאפליקציות על הרזולוציה המומלצת ועל הגדרת התצוגה של כל קונטיינר מרחבי, כדי לאפשר לאפליקציות לעבד בצורה יעילה יותר.
התוסף הזה, בשילוב עם XR_EXT_spatial_container, נועד להציע קבוצת-על של היכולות של רינדור שכבת קומפוזיציה רגילה של OpenXR 1.x. בסביבות זמן ריצה של OpenXR 1.x שתומכות ברינדור גרפי ובתוסף הזה, חובה להגדיר את XrSystemSpatialContainerPropertiesEXT :: supportsImmersive כ-true כדי לציין שהן תומכות בקונטיינרים מרחביים סוחפים.
מחזור החיים של רינדור קונטיינר מרחבי
כדי להשתמש ברינדור עצמי של קונטיינר מרחבי, האפליקציה מגדירה את XrSpatialContainerCreateInfoEXT :: graphicsPresentation ל-XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT כשמפעילים את xrCreateSpatialContainerEXT . לאחר מכן, האפליקציה הזו יכולה לנהל את העיבוד של מאגר מרחבי על ידי קריאה לפונקציות xrBeginSpatialContainerRenderingEXT ו-xrEndSpatialContainerRenderingEXT. הפונקציות האלה מחליפות את xrBeginSession ואת xrEndSession . הן לא פעולות לכל פריים, כמו xrBeginFrame ו-xrEndFrame .
בכל פריים, האפליקציה מבצעת את השלבים הבאים:
- מפעילים את xrWaitFrame ואת xrBeginFrame . לפונקציות האלה אין מבנים ספציפיים למאגר, והן פועלות כמו במפרט הליבה.
- אחזור של תנוחות תצוגה, פרמטרים של הקרנה והמלצות לעיבוד (rendering) לכל מאגרי הנתונים המרחביים שמעובדים באופן פעיל באמצעות xrLocateSpatialContainerViewsEXT . לכל מאגר מרחבי, זמן הריצה מדווח אם צריך לעבד את שכבות הקומפוזיציה שלו ואת הדרך המומלצת לעבד את השכבות על ידי מילוי XrSpatialContainerViewStateEXT .
- עיבוד פיקסלים לשכבות קומפוזיציה כרגיל. לפעולות האלה אין מבנים ספציפיים למאגר.
- שולחים שכבות קומפוזיציה לכל הקונטיינרים המרחביים שמעובדים באופן פעיל על ידי קריאה ל-xrEndFrame ושרשור של XrSpatialContainerLayerFrameEndInfoEXT .
השמדה של נקודת אחיזה (handle) של XrSpatialContainerEXT מסירה אותה באופן משתמע מקבוצת הרינדור הפעילה. אפליקציה עשויה להרוס מאגר מרחבי גם אם היא ביצעה קריאה מוצלחת ל-xrBeginSpatialContainerRenderingEXT שלא משויכת לקריאה תואמת ל-xrEndSpatialContainerRenderingEXT . זמן הריצה חייב להתנהג כאילו מתבצעת קריאה משתמעת ל-xrEndSpatialContainerRenderingEXT, אם יש צורך בכך בשלב מוקדם בהטמעה של xrDestroySpatialContainerEXT, אם היא מוחזרת בהצלחה.
כשאפליקציה מקבלת אירוע XrEventDataSpatialContainerClosedEXT בשביל מאגר בקבוצת הרינדור הפעילה, האפליקציה צריכה להפעיל את xrEndSpatialContainerRenderingEXT ולהשמיד את נקודת האחיזה XrSpatialContainerEXT.
הפונקציה xrBeginSpatialContainerRenderingEXT מוסיפה את מאגר הנתונים המרחבי לקבוצת הרינדור הפעילה לכל סשן, וכך מאפשרת לאפליקציה לשלוח שכבות קומפוזיציה של מאגר הנתונים המרחבי אל xrEndFrame .
XrResult xrBeginSpatialContainerRenderingEXT(
XrSession session,
const XrSpatialContainerBeginInfoEXT* beginInfo);
תיאורי פרמטרים
-
sessionהוא ה-XrSession . -
beginInfoהוא מצביע למבנה XrSpatialContainerBeginInfoEXT.
בדרך כלל, אפליקציות קוראות לפונקציה הזו בתגובה לאירוע visible-changed, כשהערך של XrEventDataSpatialContainerVisibleChangedEXT :: visible מוגדר כ-true.
אם המאגר המרחבי לא נוצר עם XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT כשקוראים ל-xrCreateSpatialContainerEXT , זמן הריצה חייב להחזיר את XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT .
אם הקונטיינר המרחבי כבר נמצא בקבוצת הרינדור הפעילה, זמן הריצה חייב להחזיר את הערך XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT .
אם הפונקציה xrBeginSpatialContainerRenderingEXT נקראת בזמן שבו האפליקציה לא יכולה לקרוא ל-xrWaitFrame (כלומר בתוך החלון xrBeginFrame ו-xrEndFrame), זמן הריצה חייב להחזיר את XR_ERROR_CALL_ORDER_INVALID .
שימוש תקין (משתמע)
- חובה להפעיל את התוסף
XR_EXT_spatial_container_self_renderingלפני שקוראים ל-xrBeginSpatialContainerRenderingEXT -
sessionחייב להיות כינוי תקין של XrSession -
beginInfoחייב להיות מצביע למבנה XrSpatialContainerBeginInfoEXT תקין
Thread Safety
- הגישה לפרמטר
sessionבאמצעות כל קריאה אחרת ל-xrBeginSpatialContainerRenderingEXT, ל-xrEndSpatialContainerRenderingEXT או ל-xrEndFrame חייבת להיות מסונכרנת באופן חיצוני
קודי החזרה
XR_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_CALL_ORDER_INVALIDXR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_RUNTIME_FAILUREXR_ERROR_SESSION_LOSTXR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXTXR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXTXR_ERROR_VALIDATION_FAILUREXR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED
המבנה XrSpatialContainerBeginInfoEXT משמש לציון הפרמטרים לתחילת העיבוד של קונטיינר מרחבי.
typedef struct XrSpatialContainerBeginInfoEXT {
XrStructureType type;
const void* next;
XrSpatialContainerEXT spatialContainer;
XrViewConfigurationType primaryViewConfigurationType;
} XrSpatialContainerBeginInfoEXT;
תיאור המשתמש
-
typeהוא ה-XrStructureType של המבנה הזה. -
nextהואNULLאו מצביע למבנה הבא בשרשרת מבנים. -
spatialContainerהוא ה-XrSpatialContainerEXT שבו מתחיל העיבוד. -
primaryViewConfigurationTypeהוא הערך הראשי של XrViewConfigurationType שמשמש למאגר המרחבי.
primaryViewConfigurationType היא הגדרת התצוגה שהאפליקציה מתכוונת להשתמש בה במהלך העיבוד. למטרות אופטימיזציה, זמן הריצה עשוי להפחית את הגדרת התצוגה לסוג עם פחות תצוגות (למשל, קונטיינר רחוק מאוד וקטן, כך שלא ניתן להבחין בסטריאו). זמן הריצה מחזיר פרטים על הגדרת התצוגה שהתיישנה מקריאות ל-xrLocateSpatialContainerViewsEXT .
שימוש תקין (משתמע)
- חובה להפעיל את התוסף
XR_EXT_spatial_container_self_renderingלפני שמשתמשים ב-XrSpatialContainerBeginInfoEXT -
typeחייב להיותXR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT -
nextחייב להיותNULLאו מצביע תקין למבנה הבא בשרשרת מבנים -
spatialContainerחייב להיות כינוי תקין של XrSpatialContainerEXT -
primaryViewConfigurationTypeחייב להיות ערך XrViewConfigurationType תקין
הפונקציה xrEndSpatialContainerRenderingEXT מסירה את מאגר הנתונים המרחבי מקבוצת העיבוד הפעילה.
XrResult xrEndSpatialContainerRenderingEXT(
XrSession session,
const XrSpatialContainerEndInfoEXT* endInfo);
תיאורי פרמטרים
-
sessionהוא ה-XrSession . -
endInfoהוא מצביע למבנה XrSpatialContainerEndInfoEXT.
בדרך כלל, אפליקציות קוראות לפונקציה הזו בתגובה לאירוע visible-changed, כשהערך של XrEventDataSpatialContainerVisibleChangedEXT :: visible מוגדר כ-false.
אם הקונטיינר המרחבי לא נמצא בקבוצת הרינדור הפעילה, זמן הריצה חייב להחזיר את הערך XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .
אם הפונקציה xrEndSpatialContainerRenderingEXT נקראת בזמן שבו האפליקציה לא יכולה לקרוא לפונקציה xrWaitFrame (כלומר, בתקופה שבין הקריאות לפונקציות xrBeginFrame ו-xrEndFrame), זמן הריצה חייב להחזיר את הערך XR_ERROR_CALL_ORDER_INVALID .
שימוש תקין (משתמע)
- צריך להפעיל את התוסף
XR_EXT_spatial_container_self_renderingלפני שקוראים לפונקציה xrEndSpatialContainerRenderingEXT -
sessionחייב להיות כינוי תקין של XrSession -
endInfoחייב להיות מצביע למבנה XrSpatialContainerEndInfoEXT תקין
Thread Safety
- הגישה לפרמטר
sessionבאמצעות כל קריאה אחרת ל-xrBeginSpatialContainerRenderingEXT, ל-xrEndSpatialContainerRenderingEXT או ל-xrEndFrame חייבת להיות מסונכרנת באופן חיצוני
קודי החזרה
XR_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_CALL_ORDER_INVALIDXR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_RUNTIME_FAILUREXR_ERROR_SESSION_LOSTXR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXTXR_ERROR_VALIDATION_FAILURE
המבנה XrSpatialContainerEndInfoEXT משמש לציון הפרמטרים לסיום העיבוד של קונטיינר מרחבי.
typedef struct XrSpatialContainerEndInfoEXT {
XrStructureType type;
const void* next;
XrSpatialContainerEXT spatialContainer;
} XrSpatialContainerEndInfoEXT;
תיאור המשתמש
-
typeהוא ה-XrStructureType של המבנה הזה. -
nextהואNULLאו מצביע למבנה הבא בשרשרת מבנים. -
spatialContainerהוא ה-XrSpatialContainerEXT שבו העיבוד מסתיים.
שימוש תקין (משתמע)
- חובה להפעיל את התוסף
XR_EXT_spatial_container_self_renderingלפני שמשתמשים ב-XrSpatialContainerEndInfoEXT -
typeחייב להיותXR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT -
nextחייב להיותNULLאו מצביע תקין למבנה הבא בשרשרת מבנים -
spatialContainerחייב להיות כינוי תקין של XrSpatialContainerEXT
איתור תצוגות באמצעות xrLocateSpatialContainerViewsEXT
הפונקציה xrLocateSpatialContainerViewsEXT מאתרת תצוגות של קבוצת מאגרים מרחביים.
XrResult xrLocateSpatialContainerViewsEXT(
XrSession session,
const XrSpatialContainerViewsLocateInfoEXT* locateInfo,
uint32_t viewStateCount,
XrSpatialContainerViewStateEXT* viewStates,
uint32_t viewCount,
XrView* views);
תיאורי פרמטרים
-
sessionהוא ה-XrSession . -
locateInfoהוא מצביע למבנה XrSpatialContainerViewsLocateInfoEXT. -
viewStateCountהוא מספר הפריטים במערךviewStates. -
viewStatesהוא מצביע למערך של מבני XrSpatialContainerViewStateEXT שמאוכלסים על ידי סביבת זמן הריצה. -
viewCountהוא מספר הפריטים במערךviews. -
viewsהוא מצביע למערך של מבני XrView.
הפונקציה הזו מחליפה את xrLocateViews , ומאפשרת לאפליקציה לשלוח שאילתות לגבי תצוגות של כמה קונטיינרים מרחביים בו-זמנית.
התצוגות של כל המכלים המרחביים מוחזרות במערך views היחיד. התצוגות מסודרות לפי האינדקס של הקונטיינר המרחבי במערך XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos, ואז לפי אינדקס התצוגה של הקונטיינר הזה.
לדוגמה, אם אפליקציה מספקת שלושה מאגרי נתונים מרחביים ב-XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos :
- אינדקס 0:
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO(צפייה אחת) - אינדקס 1:
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO(2 צפיות) - אינדקס 2:
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO_WITH_FOVEATED_INSET(4 צפיות)
לאחר מכן, סביבת זמן הריצה חייבת למלא את המערך views ב-7 תצוגות:
-
views[0] היא התצוגה של מאגר 0. -
views[1] הוא התצוגה של העין השמאלית במאגר 1. -
views[2] הוא התצוגה של העין הימנית במאגר 1. -
views[3] הוא התצוגה של העין השמאלית במאגר 2. -
views[4] הוא התצוגה של העין הימנית במאגר 2. -
views[5] הוא התצוגה הפנימית של העין השמאלית במאגר 2. -
views[6] היא תצוגת האינסרט של העין הימנית של מאגר 2.
אם viewCount לא שווה לסכום של מספרי הצפיות של כל סוג של הגדרת תצוגה מבוקשת של מאגר מרחבי, זמן הריצה חייב להחזיר XR_ERROR_VALIDATION_FAILURE .
למטרות אופטימיזציה, זמן הריצה עשוי להפחית את תצורת התצוגה לסוג עם פחות תצוגות (למשל, קונטיינר רחוק מאוד וקטן, כך שאי אפשר להבחין בסטריאו). אם סביבת זמן הריצה מפחיתה את הגדרת התצוגה, סביבת זמן הריצה עדיין חייבת להחזיר את מספר התצוגות המקורי של מאגר התגים הזה, ולאכלס את התצוגות הנוספות בעותקים משוכפלים של התצוגות שהופחתו. לדוגמה, אם XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO מופחת ל-XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO , גם אינדקס 0 וגם אינדקס 1 יכילו את התצוגה המונופונית היחידה. לכן, מספר הצפיות הכולל שמוחזר במערך views לא תלוי בהחלטה של זמן הריצה אם להפחית את הערך של הגדרות תצוגה כלשהן או לא.
סביבת זמן הריצה צריכה להתאים כל XrView :: fov שמוחזר, כך שהפירמידה הקטומה תהיה קטנה ככל האפשר ועדיין תכיל את כל הגבולות של המאגר המרחבי התואם. זמני ריצה עשויים להחזיר שדות ראייה לא סימטריים, למשל אם קונטיינר מרחבי נמצא בזווית אלכסונית לתצוגה של המשתמש, או אם הוא מוסתר חלקית על ידי אובייקט אחר. סביבות זמן ריצה יכולות למקם באופן חופשי את משטח הרינדור של מאגר המידע המרחבי. בגלל האופי של רינדור בכמה אפליקציות, שבו קונטיינרים מרחביים מנותקים מהמשתמש, יכול להיות שזמן הריצה יחזיר ערכי XrView שלא מתאימים לרינדור פיקסלים. לדוגמה, אם הקונטיינר המרחבי לא גלוי במסך, אין ערכים חוקיים שאפשר להגדיר בהם את XrView :: fov. במקרים כאלה, סביבות זמן הריצה חייבות להגדיר את XrSpatialContainerViewStateEXT :: shouldSubmitLayers כ-false.
זמן הריצה מחזיר מידע נוסף על מצב העיבוד של כל מאגר מרחבי במערך viewStates. אם viewStateCount לא שווה ל-XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfoCount , זמן הריצה חייב להחזיר את XR_ERROR_VALIDATION_FAILURE .
אחרי שסביבת זמן הריצה מוסיפה לתור אירוע XrEventDataSpatialContainerClosedEXT של מאגר מרחבי, הפונקציה הזו חייבת להחזיר את הערך XR_FALSE ב-XrSpatialContainerViewStateEXT :: shouldSubmitLayers ואת הערך 0 ב-XrSpatialContainerViewStateEXT :: viewStateFlags של המאגר המרחבי התואם.
במכלים מרחביים עם מיקומים שמשתנים באופן פעיל בעולם האמיתי, זמן הריצה צריך להביא בחשבון את התנועה של המכל כשממלאים את views כדי למזער את פגמי ההיטל מחדש.
אם הפונקציה xrLocateSpatialContainerViewsEXT נקראת עבור קונטיינר מרחבי אחד או יותר שלא נמצא כרגע בקבוצת הרינדור הפעילה, זמן הריצה חייב להחזיר את הערך XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .
שימוש תקין (משתמע)
- חובה להפעיל את התוסף
XR_EXT_spatial_container_self_renderingלפני שקוראים לפונקציה xrLocateSpatialContainerViewsEXT -
sessionחייב להיות כינוי תקין של XrSession -
locateInfoחייב להיות מצביע למבנה XrSpatialContainerViewsLocateInfoEXT תקין -
viewStatesחייב להיות מצביע למערך של מבניviewStateCountXrSpatialContainerViewStateEXT -
viewsחייב להיות מצביע למערך של מבניviewCountXrView - הפרמטר
viewStateCountחייב להיות גדול מ-0 - הפרמטר
viewCountחייב להיות גדול מ-0
קודי החזרה
XR_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_RUNTIME_FAILUREXR_ERROR_SESSION_LOSTXR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXTXR_ERROR_TIME_INVALIDXR_ERROR_VALIDATION_FAILUREXR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED
המבנה XrSpatialContainerViewsLocateInfoEXT מכיל את הפרמטרים לאיתור תצוגות באוסף של קונטיינרים מרחביים.
typedef struct XrSpatialContainerViewsLocateInfoEXT {
XrStructureType type;
const void* next;
XrTime displayTime;
uint32_t viewLocateInfoCount;
const XrSpatialContainerViewLocateInfoEXT* viewLocateInfos;
} XrSpatialContainerViewsLocateInfoEXT;
תיאור המשתמש
-
typeהוא ה-XrStructureType של המבנה הזה. -
nextהואNULLאו מצביע למבנה הבא בשרשרת מבנים. -
displayTimeהוא ה-XrTimeשבו נמצאות התצוגות. -
viewLocateInfoCountהוא מספר הרשומות במערךviewLocateInfos. -
viewLocateInfosהוא מצביע למערך של מבני XrSpatialContainerViewLocateInfoEXT.
שימוש תקין (משתמע)
- חובה להפעיל את התוסף
XR_EXT_spatial_container_self_renderingלפני שמשתמשים ב-XrSpatialContainerViewsLocateInfoEXT -
typeחייב להיותXR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXT -
nextחייב להיותNULLאו מצביע תקין למבנה הבא בשרשרת מבנים -
viewLocateInfosחייב להיות מצביע למערך של מבני XrSpatialContainerViewLocateInfoEXT תקינים שלviewLocateInfoCount - הפרמטר
viewLocateInfoCountחייב להיות גדול מ-0
המבנה XrSpatialContainerViewLocateInfoEXT מכיל את הפרמטרים של מאגר מרחבי ספציפי כדי לאתר תצוגות.
typedef struct XrSpatialContainerViewLocateInfoEXT {
XrStructureType type;
const void* next;
XrViewConfigurationType viewConfigurationType;
XrSpace space;
XrSpatialContainerEXT spatialContainer;
} XrSpatialContainerViewLocateInfoEXT;
תיאור המשתמש
-
typeהוא ה-XrStructureType של המבנה הזה. -
nextהואNULLאו מצביע למבנה הבא בשרשרת מבנים. -
viewConfigurationTypeהוא XrViewConfigurationType שמשמש למאגר המרחבי. -
spaceהוא ה-XrSpace שבו נמצאות התצוגות של הקונטיינר המרחבי. -
spatialContainerהוא נקודת האחיזה של XrSpatialContainerEXT.
האפליקציה יכולה לספק כל XrSpace חוקי ב-space , אבל מומלץ שהיא תספק את המרחב של המאגר המרחבי ל-XrSpatialContainerEXT התואם שצוין במבנה XrSpatialContainerViewLocateInfoEXT.
שימוש תקין (משתמע)
- חובה להפעיל את התוסף
XR_EXT_spatial_container_self_renderingלפני שמשתמשים ב-XrSpatialContainerViewLocateInfoEXT -
typeחייב להיותXR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXT -
nextחייב להיותNULLאו מצביע תקין למבנה הבא בשרשרת מבנים -
viewConfigurationTypeחייב להיות ערך XrViewConfigurationType תקין -
spaceחייב להיות כינוי תקין ב-XrSpace -
spatialContainerחייב להיות כינוי תקין של XrSpatialContainerEXT - גם
spaceוגםspatialContainerחייבים להיווצר, להיות מוקצים או להישלף מאותו XrSession
המבנה XrSpatialContainerViewStateEXT מאוכלס על ידי קריאות ל-xrLocateSpatialContainerViewsEXT עם מידע על התאמת העיבוד לכל מאגר מרחבי.
typedef struct XrSpatialContainerViewStateEXT {
XrStructureType type;
void* next;
XrViewStateFlags viewStateFlags;
XrViewConfigurationType viewConfigurationType;
XrBool32 shouldSubmitLayers;
XrExtent2Di recommendedImageExtent;
} XrSpatialContainerViewStateEXT;
תיאור המשתמש
-
typeהוא ה-XrStructureType של המבנה הזה. -
nextהואNULLאו מצביע למבנה הבא בשרשרת מבנים. -
viewStateFlagsהיא מסכת ביטים של XrViewStateFlags . לדגלים האלה יש אותה מטרה כמו ל-viewStateFlags במבנה הליבה של XrViewState. -
viewConfigurationTypeהוא XrViewConfigurationType שמציין את סוג הגדרת התצוגה שבה משתמש זמן הריצה של מאגר הנתונים המרחבי. זמני ריצה עשויים להפחית את הגדרת התצוגה למספר תצוגות נמוך יותר מזה שהתבקש. -
shouldSubmitLayersהואXrBool32שמוחזר על ידי זמן הריצה. אםXR_FALSE, האפליקציה צריכה להימנע משליחת קומפוזיציה למאגר המרחבי הזה כי הוא לא גלוי כרגע או שהוא במצב שבו לא נדרש רינדור. -
recommendedImageExtentהוא מבנה XrExtent2Di שמייצג את הרזולוציה המומלצת למאגר המרחבי.
כמו במיקום התצוגה של ליבת OpenXR, האפליקציה חייבת לבדוק את XrSpatialContainerViewStateEXT :: viewStateFlags כדי לוודא שהמיקום והכיוון תקינים ומתבצע אחריהם מעקב לפני השימוש בנתוני התצוגה לעיבוד.
האפליקציה צריכה לבדוק את shouldSubmitLayers ואת viewConfigurationType כדי להימנע מעיבוד של יותר ממה שמומלץ בזמן הריצה. כשהערך של shouldSubmitLayers הוא false, האפליקציה משנה את אופן העיבוד (rendering) שלה באופן הבא:
- האפליקציה לא יכולה לקרוא את XrView ::
fovהתואם. - האפליקציה לא יכולה לקרוא את
recommendedImageExtent. - האפליקציה לא אמורה לעבד לשרשראות החלפה (swapchains) ולשלוח שכבות קומפוזיציה למאגר המרחבי המתאים.
- האפליקציה צריכה להגדיר את XrSpatialContainerLayerEXT ::
retainPreviousSubmissionכ-true. אם האפליקציה בוחרת לשלוח שכבות בכל זאת, סביבת זמן הריצה תקבע מה לעשות עם השכבות (למשל, סביבת זמן הריצה עשויה לבחור להשמיט אותן).
המאפיין recommendedImageExtent מיועד במפורש לשכבות שיעודכנו על סמך מיקום מאגר התגים או התצוגה של המשתמש. כשמעדכנים שכבות עם תוכן שתלוי במיקום של הקונטיינר המרחבי או בתצוגה של המשתמש (כמו תוכן תלת-ממדי רגיל), האפליקציה צריכה לעבד את התוכן לאזור התצוגה הקטן יותר במקום לגודל התצוגה המומלץ שמוגדר כברירת מחדל. כשמעדכנים שכבות עם תוכן שלא תלוי במיקום של מאגר המידע המרחבי או בתצוגה של המשתמש (כמו שכבות מרובעות סטטיות), האפליקציה יכולה להתעלם מהערכים האלה בלי בעיה. בשכבות שתלויות בתצוגה, recommendedImageExtent היא המלצה לאפליקציה מסביבת זמן הריצה שנועדה לצמצם את ההתחזות ולשפר את ביצועי העיבוד. האפליקציה יכולה לשלוח את התמונות ברזולוציה מלאה אם היא רוצה.
XrExtent2Di :: width ו-XrExtent2Di :: height של recommendedImageExtent חייבים תמיד להיות מספר שלם חיובי שקטן או שווה ל-XrViewConfigurationView :: recommendedImageRectWidth ול-XrViewConfigurationView :: recommendedImageRectHeight של XrViewConfigurationView להגדרת התצוגה הראשית של מאגר הנתונים המרחבי. אפליקציה לא אמורה ליצור מחדש swapchain רק בגלל ש-recommendedImageExtent השתנה, כי זה רמז דינמי לאפליקציה שמציין את XrSwapchainSubImage :: imageRect לשימוש ב-XrSwapchainSubImage של כל שכבות הקומפוזיציה ברזולוציה מלאה שהיא שולחת, ויכולה לשנות כל פריים.
שימוש תקין (משתמע)
- חובה להפעיל את התוסף
XR_EXT_spatial_container_self_renderingלפני שמשתמשים ב-XrSpatialContainerViewStateEXT -
typeחייב להיותXR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXT -
nextחייב להיותNULLאו מצביע תקין למבנה הבא בשרשרת מבנים -
viewStateFlagsחייב להיות שילוב תקין של ערכי XrViewStateFlagBits -
viewStateFlagsלא יכול להיות0 -
viewConfigurationTypeחייב להיות ערך XrViewConfigurationType תקין
הצגת מרחב העזר
מרחב ההתייחסות של התצוגה נשאר ללא שינוי, כמו שהוא בליבה של OpenXR. כמו בליבה, הוא לא מיועד לעיבוד.
שליחת שכבות באמצעות xrEndFrame
כדי לעבד קונטיינרים מרחביים, האפליקציה חייבת לספק ל-xrEndFrame רשימה של שכבות שמשויכות לקונטיינרים המרחביים שלהן. כדי לעשות את זה, משתמשים במבנה XrSpatialContainerLayerFrameEndInfoEXT.
typedef struct XrSpatialContainerLayerFrameEndInfoEXT {
XrStructureType type;
const void* next;
uint32_t containerLayerCount;
const XrSpatialContainerLayerEXT* containerLayers;
} XrSpatialContainerLayerFrameEndInfoEXT;
תיאור המשתמש
-
typeהוא ה-XrStructureType של המבנה הזה. -
nextהואNULLאו מצביע למבנה הבא בשרשרת מבנים. -
containerLayerCountהוא מספר הרכיבים במערךcontainerLayers. -
containerLayersהוא מצביע למערך של מבני XrSpatialContainerLayerEXT.
המערך containerLayers מכיל XrSpatialContainerLayerEXT לכל מאגר מרחבי בקבוצת הרינדור הפעילה (המאגרים שמנוהלים בכל סשן על ידי xrBeginSpatialContainerRenderingEXT ו-xrEndSpatialContainerRenderingEXT). כל XrSpatialContainerLayerEXT מכיל רשימה של מצביעי XrCompositionLayerBaseHeader שמשויכים למאגר המרחבי הנתון. סביבות זמן ריצה עשויות לשלב קונטיינרים בכל סדר שהן בוחרות, ללא קשר לסדר של containerLayers . לדוגמה, סביבות זמן ריצה עשויות לשלב קונטיינרים על סמך העומק שלהם ביחס למשתמש, להגדיר קונטיינר מרחבי כשכבת רקע או "להצמיד" קונטיינר מרחבי כך שהוא תמיד יהיה למעלה, בלי קשר לעומק שלו. סביבות זמן ריצה עשויות לשלב שכבות באמצעות אסטרטגיות שונות למאגרים מרחביים במצבים מוגבלים או אימרסיביים. לדוגמה, סביבות זמן ריצה עשויות לבצע קומפוזיציה מראש של שכבות הקומפוזיציה של כל מאגר מרחבי מוגבל לשכבת סטריאו מרובעת אחת, שמשולבת עם כל המאגרים האחרים בשלב קומפוזיציה שני.
הערכים XrFrameEndInfo :: displayTime ו-XrFrameEndInfo :: environmentBlendMode יחולו על כל מאגרי הנתונים המרחביים שסופקו ב-XrSpatialContainerLayerFrameEndInfoEXT .
כשמעבירים את המבנה הזה אל xrEndFrame על ידי שרשור אל XrFrameEndInfo , מתווספים מקרי השגיאה הבאים על סמך קבוצת הרינדור הפעילה:
- אם יש הפניה למאגר מרחבי מיותר מרכיב אחד של
containerLayers, זמני הריצה חייבים להחזיר את הערךXR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXT. - אם קונטיינר מרחבי בקבוצת הרינדור הפעילה לא מקושר לאלמנט של
containerLayers, זמני הריצה חייבים להחזיר את הערךXR_ERROR_SPATIAL_CONTAINER_MISSING_EXT. - אם מאגר מרחבי שאליו מפנה
containerLayersלא שייך לקבוצת הרינדור הפעילה, זמני הריצה חייבים להחזיר אתXR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT.
בנוסף, אם יש קונטיינרים מרחביים בקבוצת הרינדור הפעילה והמבנה הזה לא משורשר אל XrFrameEndInfo , סביבות זמן הריצה חייבות להחזיר את הערך XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT .
בכל אחד ממקרי השגיאה שלמעלה, סביבת זמן הריצה לא צריכה לעבד תוכן לאף מאגר מרחבי.
אם אין קונטיינרים מרחביים בקבוצת הרינדור הפעילה, אפליקציה יכולה לקרוא ל-xrEndFrame כל עוד היא לא שולחת שכבות קומפוזיציה.
שימו לב שאפשר לשלוח שרשראות החלפה נפרדות לכמה קונטיינרים דרך שכבות במבנה תקין. לדוגמה, שכבת Quad שעברה רינדור דרך שרשרת החלפה אחת שנשלחה לכמה קונטיינרים מרחביים. המקרה הזה מטופל באופן אחיד עם עיבוד אחר: זמן הריצה חייב לעבד את המרובע בכל המכלים המרחביים האלה.
שימוש תקין (משתמע)
- חובה להפעיל את התוסף
XR_EXT_spatial_container_self_renderingלפני שמשתמשים ב-XrSpatialContainerLayerFrameEndInfoEXT -
typeחייב להיותXR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXT -
nextחייב להיותNULLאו מצביע תקין למבנה הבא בשרשרת מבנים -
containerLayersחייב להיות מצביע למערך של מבני XrSpatialContainerLayerEXT תקינים שלcontainerLayerCount - הפרמטר
containerLayerCountחייב להיות גדול מ-0
המבנה XrSpatialContainerLayerEXT מקבץ שכבות קומפוזיציה סטנדרטיות ומשייך אותן לקונטיינר מרחבי ספציפי.
typedef struct XrSpatialContainerLayerEXT {
XrStructureType type;
const void* next;
XrSpatialContainerEXT spatialContainer;
XrBool32 retainPreviousSubmission;
uint32_t layerCount;
const XrCompositionLayerBaseHeader* const* layers;
} XrSpatialContainerLayerEXT;
תיאור המשתמש
-
typeהוא ה-XrStructureType של המבנה הזה. -
nextהואNULLאו מצביע למבנה הבא בשרשרת מבנים. -
spatialContainerהוא ה-XrSpatialContainerEXT שמזהה את מאגר היעד. -
retainPreviousSubmissionהואXrBool32. אםXR_TRUE, סביבת זמן הריצה תשמור את הפריים האחרון שנשלח למאגר המרחבי הזה. -
layerCountהוא מספר שכבות הקומפוזיציה במערךlayers. -
layersהוא מצביע למערך של מצביעי XrCompositionLayerBaseHeader.
כאשר retainPreviousSubmission הוא XR_TRUE , זמן הריצה חייב לעשות שימוש חוזר בשכבות הקומפוזיציה ובתוכן התמונה של שרשרת ההחלפה כפי שננעל במהלך הקריאה האחרונה של xrEndFrame שבה retainPreviousSubmission היה XR_FALSE . שינויים שבוצעו לאחר מכן בשרשראות החלפה שמשמשות שכבות שנשמרו לא צריכים להשתקף בפלט שעבר רינדור.
בשכבות שנשלחות למכל מרחבי נפרד (רינדור בתוך המכל), סביבת זמן הריצה חייבת לפעול לפי הכללים שכבר צוינו לגבי סדר הקומפוזיציה של השכבות. כלומר, השכבות בתוך מאגרים חייבות להיות משורטטות באותו סדר שבו הן צוינו, ומורכבות באמצעות אלגוריתם הצייר.
"ניקוי" של מאגר מרחבי מתייחס להסרה של כל התוכן ממאגר מרחבי, כך ששום דבר לא מוצג במאגר הזה בפריים הנוכחי. סביבות זמן ריצה חייבות להתייחס לכך באופן שווה ערך לאפליקציה ששולחת שחור שקוף (כל הביטים 0) לכל פיקסל בתוך מאגר התגים. "שמירה" של קונטיינר מרחבי מתייחסת לכך שסביבת זמן הריצה ממשיכה להציג את קבוצת השכבות האחרונה שנשלחה עבור הקונטיינר הזה.
בכל מאגר מרחבי, האפליקציה יכולה לציין אם לשלוח שכבות חדשות, לשמור את השליחה הקודמת או לנקות את המאגר המרחבי:
- כדי לשלוח שכבות חדשות, האפליקציה מספקת
layerCountשאינו אפס ומצביעlayersחוקי. - כדי לנקות מאגר מרחבי, הערך של
layerCountברשומה שלו חייב להיות 0 והערך שלretainPreviousSubmissionחייב להיותXR_FALSE. - כדי לשמור את השכבות ואת תמונות ה-swapchain שנשלחו לאחרונה (שמירה), הערך של
layerCountעבור הרשומה שלו חייב להיות 0 והערך שלretainPreviousSubmissionחייב להיותXR_TRUE.
אמצעי הבקרה המפורש הזה לכל מאגר מבטיח שהכוונה של האפליקציה תועבר בצורה ברורה בכל פריים.
אם retainPreviousSubmission הוא XR_TRUE ו-layerCount הוא לא 0, זמן הריצה חייב להחזיר את הערך XR_ERROR_VALIDATION_FAILURE .
אם XrSpatialContainerCompositionLayerViewConfigurationEXT לא משורשר ל-XrCompositionLayerProjection שהוא חלק ממכל מרחבי, זמן הריצה חייב להחזיר את XR_ERROR_VALIDATION_FAILURE . המבנה הזה רלוונטי רק לשכבות XrCompositionLayerProjection. אם היא משורשרת לסוגי שכבות אחרים (למשל שכבות מרובעות או גליליות), זמן הריצה חייב להחזיר את הערך XR_ERROR_VALIDATION_FAILURE .
שימוש תקין (משתמע)
- צריך להפעיל את התוסף
XR_EXT_spatial_container_self_renderingלפני שמשתמשים ב-XrSpatialContainerLayerEXT -
typeחייב להיותXR_TYPE_SPATIAL_CONTAINER_LAYER_EXT -
nextחייב להיותNULLאו מצביע תקין למבנה הבא בשרשרת מבנים . מידע נוסף: XrSpatialContainerLayerVolumeClippingEXT -
spatialContainerחייב להיות כינוי תקין של XrSpatialContainerEXT - אם
layerCountהוא לא0,layersחייב להיות מצביע למערך של מבנים מבוססי-XrCompositionLayerBaseHeader תקינים שלlayerCount. מידע נוסף: XrCompositionLayerCubeKHR , XrCompositionLayerCylinderKHR , XrCompositionLayerEquirect2KHR , XrCompositionLayerEquirectKHR , XrCompositionLayerPassthroughANDROID , XrCompositionLayerPassthroughFB , XrCompositionLayerPassthroughHTC , XrCompositionLayerProjection , XrCompositionLayerQuad
הגדרת תצוגה לשכבות של היטלים
המבנה XrSpatialContainerCompositionLayerViewConfigurationEXT משמש לציון הגדרת התצוגה שמשמשת לעיבוד של שכבת היטל למאגר מרחבי.
typedef struct XrSpatialContainerCompositionLayerViewConfigurationEXT {
XrStructureType type;
const void* next;
XrViewConfigurationType viewConfigurationType;
} XrSpatialContainerCompositionLayerViewConfigurationEXT;
תיאור המשתמש
-
typeהוא ה-XrStructureType של המבנה הזה. -
nextהואNULLאו מצביע למבנה הבא בשרשרת מבנים. -
viewConfigurationTypeהוא הערך של XrViewConfigurationType ששימש לעיבוד של XrCompositionLayerProjection .
כששולחים XrCompositionLayerProjection למאגר מרחבי, האפליקציה חייבת לציין באיזו הגדרת תצוגה נעשה שימוש כדי לעבד את השכבה. זה הכרחי כי האפליקציה יכולה לבחור בכל פריים אם לעבד באמצעות הגדרת התצוגה הראשית של מאגר המידע המרחבי או הגדרת התצוגה המומלצת של זמן הריצה, אם יש כזו.
כש-XrSpatialContainerCompositionLayerViewConfigurationEXT משורשר, האפליקציה חייבת לוודא ש-XrCompositionLayerProjection :: viewCount הוא מספר צפיות תקין ל-XrViewConfigurationType שצוין במבנה המשורשר. ה-viewConfigurationType שצוין במבנה המשורשר חייב להיות XrSpatialContainerBeginInfoEXT :: primaryViewConfigurationType שצוין כשהקונטיינר התחיל, או סוג הגדרת התצוגה המופחתת שהוחזר על ידי זמן הריצה ב-XrSpatialContainerViewStateEXT , או ערכים נוספים שהופעלו באמצעות תוסף.
שימוש תקין (משתמע)
- חובה להפעיל את התוסף
XR_EXT_spatial_container_self_renderingלפני שמשתמשים ב-XrSpatialContainerCompositionLayerViewConfigurationEXT -
typeחייב להיותXR_TYPE_SPATIAL_CONTAINER_COMPOSITION_LAYER_VIEW_CONFIGURATION_EXT -
nextחייב להיותNULLאו מצביע תקין למבנה הבא בשרשרת מבנים -
viewConfigurationTypeחייב להיות ערך XrViewConfigurationType תקין
התנהגות של חיתוך פיקסלים
האפליקציות צריכות להודיע לסביבת זמן הריצה אם הן מעבדות פיקסלים מחוץ לגבולות של מאגר מרחבי או לא, על ידי שרשור של XrSpatialContainerLayerVolumeClippingEXT בזמן שליחת שכבות הקומפוזיציה.
typedef struct XrSpatialContainerLayerVolumeClippingEXT {
XrStructureType type;
const void* next;
XrSpatialContainerVolumeClippingEXT volumeClipping;
} XrSpatialContainerLayerVolumeClippingEXT;
תיאור המשתמש
-
typeהוא ה-XrStructureType של המבנה הזה. -
nextהואNULLאו מצביע למבנה הבא בשרשרת מבנים. -
volumeClippingהוא XrSpatialContainerVolumeClippingEXT שהאפליקציה החילה.
המבנה הזה משמש כרמז אם האפליקציה מעבדת פיקסלים מחוץ לגבולות של קונטיינר מרחבי. כשמאגר מרחבי נמצא במצב אימרסיבי, הגבולות הם אינסופיים ולכן לרמז הזה אין משמעות.
במכלים מרחביים מוגבלים שמשתמשים ברינדור עצמי, זמן הריצה צריך להביא בחשבון גם את גבולות הנפח התלת-ממדי וגם את גבולות הפיקסלים הדו-ממדיים. גבולות הנפח התלת-ממדי מוחזרים מ-xrGetSpatialContainerBoundsEXT . גבולות הפיקסלים הדו-ממדיים הם ההיטל של גבולות הנפח התלת-ממדיים על כל מסך במערכת.
סביבות זמן ריצה חייבות למחוק פיקסלים מתמונות של שרשרת החלפה (swapchain) שנמצאות מחוץ לגבולות הפיקסלים הדו-ממדיים, אבל סביבות זמן ריצה לא יכולות למחוק פיקסלים שנמצאים בתוך גבולות הפיקסלים הדו-ממדיים אבל מחוץ לגבולות הנפח התלת-ממדי. אפשר להשתמש באפקטים סטריאוסקופיים שבהם נראה שהתוכן חורג מהגבולות של הנפח התלת-ממדי של הקונטיינר או מופיע לפניהם. אפליקציות יכולות להשמיט פיקסלים מחוץ לגבולות הנפח התלת-ממדי של מאגר מרחבי מוגבל כדי לצמצם פרדוקסים של עומק, וצריכות להגדיר את volumeClipping על סמך האופן שבו הן עושות זאת. פרדוקסים של עומק גורמים לעיתים קרובות למאמץ בעיניים ולאי-נוחות למשתמשים.
סביבות זמן ריצה עשויות להשתמש ב-volumeClipping כדי לשנות את האופן שבו הן מציגות קונטיינר מרחבי מסוים. לדוגמה, אם המדיניות מוגדרת לערך XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT, סביבת זמן ריצה יכולה לעבד את הפנים האחוריות של גבולות הנפח התלת-ממדי, מה שיגרום לפרדוקסים של עומק אם המאגר המרחבי ישרטט פיקסלים מאחורי גבולות הנפח התלת-ממדי של המאגר.
יכול להיות שתוספים עתידיים יאפשרו חיתוך על סמך גבולות הנפח התלת-ממדי אם יישלח מידע על העומק.
שימוש תקין (משתמע)
- חובה להפעיל את התוסף
XR_EXT_spatial_container_self_renderingלפני שמשתמשים ב-XrSpatialContainerLayerVolumeClippingEXT -
typeחייב להיותXR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT -
nextחייב להיותNULLאו מצביע תקין למבנה הבא בשרשרת מבנים -
volumeClippingחייב להיות ערך XrSpatialContainerVolumeClippingEXT תקין
פקודות חדשות
- xrBeginSpatialContainerRenderingEXT
- xrEndSpatialContainerRenderingEXT
- xrLocateSpatialContainerViewsEXT
מבנים חדשים
- XrSpatialContainerBeginInfoEXT
- XrSpatialContainerEndInfoEXT
- XrSpatialContainerLayerEXT
- XrSpatialContainerViewLocateInfoEXT
- XrSpatialContainerViewStateEXT
- XrSpatialContainerViewsLocateInfoEXT
הרחבה של XrCompositionLayerProjection :
הרחבה של XrFrameEndInfo :
הרחבה של XrSpatialContainerLayerEXT :
קבועי Enum חדשים
XR_EXT_SPATIAL_CONTAINER_SELF_RENDERING_EXTENSION_NAMEXR_EXT_spatial_container_self_rendering_SPEC_VERSIONהרחבת XrResult :
XR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXTXR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXTXR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXTXR_ERROR_SPATIAL_CONTAINER_MISSING_EXTXR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT
הרחבה של XrSpatialContainerGraphicsPresentationEXT :
XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
הרחבה של XrStructureType :
XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXTXR_TYPE_SPATIAL_CONTAINER_COMPOSITION_LAYER_VIEW_CONFIGURATION_EXTXR_TYPE_SPATIAL_CONTAINER_END_INFO_EXTXR_TYPE_SPATIAL_CONTAINER_LAYER_EXTXR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXTXR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXTXR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXTXR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXTXR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXT
דוגמאות קוד
// 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));
היסטוריית הגרסאות
גרסה 1, 06.08.2026 (Lachlan Ford)
- תיאור התוסף הראשוני