Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions docs/specs/extensions/XR_DXR_weave.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,28 @@ typedef struct XrWeaveSubmitOverlayUnchangedDXR {
- D3D11 service path today (`set_overlay_2d(..., layer_unchanged)`); the Vulkan weave engines
accept and ignore it until their DP slot exists.

### Filter strength (v15)

The lens filter trades aliasing against softness, and the best point depends on the content
(text and UI want more filtering, photos and video less). `XrWeaveSubmitOverlayFilterDXR`
(1004999291), chained next to the overlay, sets it per submit:

```c
typedef struct XrWeaveSubmitOverlayFilterDXR {
XrStructureType type; // XR_TYPE_WEAVE_SUBMIT_OVERLAY_FILTER_DXR
const void* next;
float filterStrength; // 0 = no lens filtering .. 1 = the DP's full filter
} XrWeaveSubmitOverlayFilterDXR;
```

- **Omit it unless you know your content.** Omitted = the display processor's own default, a
vendor value tuned by eye on its panel (Leia SR: 0.6). The runtime passes "not set", never a
number of its own.
- `filterStrength` outside [0,1] or NaN is `XR_ERROR_VALIDATION_FAILURE`.
- Per submit, no latch. Carried to the DP by the appended D3D11 slot
`set_overlay_2d_filter_strength` (negative = default), called before `set_overlay_2d` each
frame the layer goes to the DP.



Each submit carries a fixed cost independent of the rect area: the runtime IPC round-trip,
Expand Down Expand Up @@ -882,8 +904,12 @@ any unknown chained struct. One `weave(v13)` WARN in the service log per edge.
| 11 | `xrWeaveSnapWindowGridDXR` + `XrWeaveSnapGridInfoDXR` / `XrWeaveSnapGridPointDXR` — bulk grid snap: the per-point snap evaluated over a grid by the runtime, one call (one IPC round trip) instead of one per point (§5c, #1723). |
| 12 | `XrWeaveOutputOriginDXR` (out, per frame: the origin each woven output was woven for + a serial) and `XrWeaveWindowLogicalOriginDXR` (in: the caller's logical origin + scale, echoed verbatim) — so a present-owner can tag its own Wayland commit for move-synchronised drag (§5e, browser-pvt#180). |
| 13 | `XrWeaveSubmitMonoIn2DDXR` — one flat view (stereo: the left view; N > 2: the view nearest the display axis) instead of the weave while the session's hardware state is 2D (§5f). Desktop Linux; accepted and ignored elsewhere. |
| 15 | `XrWeaveSubmitOverlayFilterDXR` — the caller's lens-filter strength for the 2D overlay, 0..1; omitted = the DP's own default (§2d). |
| 14 | `XrWeaveSubmitOverlayUnchangedDXR` — the v4 overlay atlas holds the previous accepted submit's pixels, so a DP may reuse its lens prefilter of the 2D layer (ADR-027 Amendment; §2d). |

**v15 needs no gate either**: omitting the struct, or a runtime/DP that predates it, means
the display processor's default strength.

**v14 needs no gate**: a pre-v14 runtime skips the unknown struct, which is the "may have
changed" behaviour, so a caller can always send it.

Expand Down
2 changes: 1 addition & 1 deletion src/external/openxr_includes/openxr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Rules:
| 1004999260–269 | `XR_DXR_depth_budget` | 260 = `XR_TYPE_REAR_DEPTH_BUDGET_DXR`, 261 = `XR_TYPE_CONTENT_BOUNDS_DXR`, 262 = `XR_TYPE_EVENT_DATA_REAR_DEPTH_BUDGET_STATE_CHANGED_DXR`, 263 = `XR_TYPE_CONTENT_MASK_DXR` (ADR-040). Was taken without a registry row — recorded retroactively in #1486 PR 2 |
| 1004999270–279 | `XR_DXR_lift` | 270 = `XR_TYPE_LIFT_PROPERTIES_DXR`, 271 = `XR_TYPE_LIFT_STREAM_CREATE_INFO_DXR`, 272 = `XR_TYPE_LIFT_FRAME_SUBMIT_INFO_DXR`, 273 = `XR_TYPE_LIFT_OPTIONS_DXR`, 274 = `XR_TYPE_LIFT_RESULT_DXR`, 275 = `XR_TYPE_WEAVE_SUBMIT_LIFT_RECTS_DXR`, 276 = `XR_TYPE_WEAVE_RECT_LIFT_DXR`, 277 = `XR_TYPE_LIFT_BLOB_DXR` (spec v1, ADR-042). 278 = `XR_OBJECT_TYPE_LIFT_STREAM_DXR` — an `XrObjectType`, not an `XrStructureType`. 279 = `XR_LIFT_NOT_READY_DXR` — a **success**-class `XrResult` (positive) |
| 1004999280–289 | `XR_DXR_lift` (continued) | 280 = `XR_TYPE_LIFT_STREAM_STATS_DXR` (spec v1). A second decade because 270–279 is full |
| 1004999290–299 | `XR_DXR_weave` (v14+ additions) | 290 = `XR_TYPE_WEAVE_SUBMIT_OVERLAY_UNCHANGED_DXR` (the v4 overlay atlas is unchanged since the previous submit, so a DP may reuse its lens prefilter of the 2D layer, spec v14, ADR-027 Amendment). The third weave decade (240–249 is full) |
| 1004999290–299 | `XR_DXR_weave` (v14+ additions) | 290 = `XR_TYPE_WEAVE_SUBMIT_OVERLAY_UNCHANGED_DXR` (the v4 overlay atlas is unchanged since the previous submit, so a DP may reuse its lens prefilter of the 2D layer, spec v14, ADR-027 Amendment); 291 = `XR_TYPE_WEAVE_SUBMIT_OVERLAY_FILTER_DXR` (the caller's lens-filter strength for the 2D layer, 0..1, omitted = the DP's default, spec v15). The third weave decade (240–249 is full) |
| 1004999300+ | **next free** | |

`XR_DXR_android_surface_binding` was implemented in #1037 and now has its own
Expand Down
37 changes: 36 additions & 1 deletion src/external/openxr_includes/openxr/XR_DXR_weave.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,12 @@
* back verbatim), so a present-owner can tag its own Wayland commit for
* move-synchronised drag.
*
* Overlay filter strength (SPEC_VERSION 15). XrWeaveSubmitOverlayFilterDXR, chained
* next to an XrWeaveSubmitOverlaysDXR: how strongly a display processor that
* band-limits the 2D layer for its lens filters it, 0..1 (0 = no lens filtering,
* 1 = the full lens cell). Absent = the display processor's own default, which
* is what a caller that does not know better should use.
*
* Overlay unchanged (SPEC_VERSION 14). XrWeaveSubmitOverlayUnchangedDXR, chained
* on XrWeaveSubmitInfoDXR next to an XrWeaveSubmitOverlaysDXR: the caller declares
* that this submit's overlay atlas holds exactly the pixels of the previous
Expand Down Expand Up @@ -275,7 +281,7 @@ extern "C" {
#endif

#define XR_DXR_weave 1
#define XR_DXR_weave_SPEC_VERSION 14
#define XR_DXR_weave_SPEC_VERSION 15
#define XR_DXR_WEAVE_EXTENSION_NAME "XR_DXR_weave"

// Reserved 1004999190..199. Final values reconcile with the Khronos registry
Expand Down Expand Up @@ -314,6 +320,8 @@ extern "C" {
// Reserved 1004999290..299 — the third weave decade (240..249 is full). Same registry.
// Spec v14 (ADR-027 Amendment): the overlay atlas is unchanged since the last submit.
#define XR_TYPE_WEAVE_SUBMIT_OVERLAY_UNCHANGED_DXR ((XrStructureType)1004999290)
// Spec v15 (ADR-027 Amendment): the caller's lens-filter strength for the 2D layer.
#define XR_TYPE_WEAVE_SUBMIT_OVERLAY_FILTER_DXR ((XrStructureType)1004999291)

//! Upper bound on eye positions carried by XrWeaveSubmitInfoDXR (mirrors the
//! runtime's XRT_MAX_VIEWS). Phase 1: carried but unused.
Expand Down Expand Up @@ -1038,6 +1046,33 @@ typedef struct XrWeaveSubmitOverlayUnchangedDXR {
XrBool32 overlayUnchanged; //!< XR_TRUE: same overlay pixels as the previous accepted submit
} XrWeaveSubmitOverlayUnchangedDXR;

/*!
* @brief Lens-filter strength for the v4 overlay atlas (spec v15).
*
* Chain onto XrWeaveSubmitInfoDXR::next, in the same submit as an
* XrWeaveSubmitOverlaysDXR. A display processor that band-limits the 2D layer
* for its lens (ADR-027 Amendment) trades aliasing against softness; this sets
* where on that curve THIS submit sits:
*
* 0.0 — no lens filtering (the layer is composited as-is: sharpest, aliases)
* 1.0 — the display processor's full anti-aliasing filter (softest)
*
* Omitting the struct selects the DISPLAY PROCESSOR's default, a vendor-tuned
* value chosen by eye on its panel (Leia SR ships 0.6). That is the right choice
* for a caller that does not know its content better; set it only to tune for
* known content (text/UI wants more filtering, photos/video can take less).
*
* Per submit, no latch. @c filterStrength outside [0,1] or NaN is
* XR_ERROR_VALIDATION_FAILURE. A display processor without a strength control
* ignores it, as does a pre-v15 runtime (unknown chained struct) — both behave
* as the default, so no version gate is needed to send it.
*/
typedef struct XrWeaveSubmitOverlayFilterDXR {
XrStructureType type; //!< XR_TYPE_WEAVE_SUBMIT_OVERLAY_FILTER_DXR
const void* XR_MAY_ALIAS next;
float filterStrength; //!< 0 = no lens filtering .. 1 = full; omit = DP default
} XrWeaveSubmitOverlayFilterDXR;

typedef XrResult (XRAPI_PTR *PFN_xrWeaveBindWindowDXR)(
XrSession session, void* windowHandle);

Expand Down
20 changes: 20 additions & 0 deletions src/xrt/compositor/d3d11_service/comp_d3d11_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,9 @@ struct d3d11_client_render_resources
//! XR_DXR_weave v14: the next submit's overlay is unchanged (set by
//! comp_d3d11_service_weave_set_overlay_unchanged, consumed by the submit).
bool weave_overlay_unchanged_next;
//! XR_DXR_weave v15: the next submit's overlay lens-filter strength [0,1];
//! negative = the DP's default. Consumed (reset to -1) by the submit.
float weave_overlay_filter_strength_next;

//! DXR_WEAVE_GPU_TIMING=1 diagnostic (ADR-027 Amendment perf A/B): a ring of
//! disjoint + 3 timestamp queries per weave_submit — T0 before the ingest
Expand Down Expand Up @@ -25220,6 +25223,17 @@ comp_d3d11_service_weave_set_overlay_unchanged(struct xrt_compositor *xc, bool o
c->render.weave_overlay_unchanged_next = overlay_unchanged;
}

void
comp_d3d11_service_weave_set_overlay_filter_strength(struct xrt_compositor *xc, float strength)
{
if (xc == nullptr || xc->destroy != compositor_destroy) {
return;
}
struct d3d11_service_compositor *c = d3d11_service_compositor_from_xrt(xc);
// The wire is untrusted: anything outside [0,1] (incl. NaN) means "default".
c->render.weave_overlay_filter_strength_next = (strength >= 0.0f && strength <= 1.0f) ? strength : -1.0f;
}

bool
comp_d3d11_service_weave_set_screen_flat_regions(struct xrt_compositor *xc,
uint32_t rect_count,
Expand Down Expand Up @@ -25691,6 +25705,8 @@ comp_d3d11_service_weave_submit(struct xrt_compositor *xc,
// "unchanged" for the next submit (per submit, no latch).
const bool ov_unchanged = c->render.weave_overlay_unchanged_next;
c->render.weave_overlay_unchanged_next = false;
const float ov_filter_strength = c->render.weave_overlay_filter_strength_next;
c->render.weave_overlay_filter_strength_next = -1.0f;
struct d3d11_service_system *sys = c->sys;
if (sys == nullptr) {
return false;
Expand Down Expand Up @@ -26243,6 +26259,10 @@ comp_d3d11_service_weave_submit(struct xrt_compositor *xc,
bool ov_in_dp = false;
auto hand_overlay_to_dp = [&]() {
const bool fits = (ov_srv != nullptr && ov_w == win_w && ov_h == win_h);
if (fits) {
// v15: per frame, before the layer itself (the slot is stateless).
xrt_display_processor_d3d11_set_overlay_2d_filter_strength(dp, ov_filter_strength);
}
ov_in_dp = xrt_display_processor_d3d11_set_overlay_2d(dp, sys->context.get(), fits ? ov_srv : nullptr,
fits ? ov_w : 0, fits ? ov_h : 0,
XRT_ATLAS_ENCODING_ENCODED, fits && ov_unchanged) &&
Expand Down
9 changes: 9 additions & 0 deletions src/xrt/compositor/d3d11_service/comp_d3d11_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,15 @@ comp_d3d11_service_weave_set_screen_flat_regions(struct xrt_compositor *xc,
void
comp_d3d11_service_weave_set_overlay_unchanged(struct xrt_compositor *xc, bool overlay_unchanged);

/*!
* XR_DXR_weave v15 (XrWeaveSubmitOverlayFilterDXR): the lens-filter strength
* the NEXT @ref comp_d3d11_service_weave_submit asks for its overlay, [0,1];
* negative = the display processor's own default. Per submit: consumed and
* reset by the submit, same pattern as the v14 setter above.
*/
void
comp_d3d11_service_weave_set_overlay_filter_strength(struct xrt_compositor *xc, float strength);

/*!
* Export the persistent server-allocated weaved-output texture handle (+ dims)
* for the caller to import once and present each frame. Returns false until the
Expand Down
47 changes: 46 additions & 1 deletion src/xrt/include/xrt/xrt_display_processor_d3d11.h
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,26 @@ struct xrt_display_processor_d3d11
uint32_t height,
enum xrt_atlas_encoding encoding,
bool layer_unchanged);

/*!
* Lens-filter strength for the 2D over-layer of the NEXT @ref process_atlas
* (XR_DXR_weave v15, ADR-027 Amendment). A DP that band-limits the layer
* for its lens trades aliasing against softness; @p strength picks the
* point: 0 = no lens filtering, 1 = the DP's full filter. NEGATIVE = the
* DP's own default (a vendor-tuned value; the caller did not set one).
*
* Stateless, per frame: called right before @ref set_overlay_2d whenever an
* overlay goes to the DP, so a DP that keeps the value sticky must take it
* from here every frame. Separate from set_overlay_2d because that slot
* shipped (v2.25.2) and its signature is frozen (ADR-020).
*
* Optional — absent slot or NULL ⟹ the DP's default is used. Appended per
* ADR-020 (append-only within a major).
*
* @param xdp Pointer to self.
* @param strength [0,1], or negative for the DP's default.
*/
void (*set_overlay_2d_filter_strength)(struct xrt_display_processor_d3d11 *xdp, float strength);
};


Expand Down Expand Up @@ -817,7 +837,8 @@ XRT_DP_ABI_ASSERT(offsetof(struct xrt_display_processor_d3d11, lift_stream_destr
XRT_DP_ABI_ASSERT(offsetof(struct xrt_display_processor_d3d11, lift_convert) == XRT_DP_D3D11_BASE_OFF + 28 * sizeof(void *), XRT_DP_ABI_MSG);
XRT_DP_ABI_ASSERT(offsetof(struct xrt_display_processor_d3d11, lift_convert_blob) == XRT_DP_D3D11_BASE_OFF + 29 * sizeof(void *), XRT_DP_ABI_MSG);
XRT_DP_ABI_ASSERT(offsetof(struct xrt_display_processor_d3d11, set_overlay_2d) == XRT_DP_D3D11_BASE_OFF + 30 * sizeof(void *), XRT_DP_ABI_MSG);
XRT_DP_ABI_ASSERT(sizeof(struct xrt_display_processor_d3d11) == XRT_DP_D3D11_BASE_OFF + 31 * sizeof(void *), XRT_DP_ABI_MSG);
XRT_DP_ABI_ASSERT(offsetof(struct xrt_display_processor_d3d11, set_overlay_2d_filter_strength) == XRT_DP_D3D11_BASE_OFF + 31 * sizeof(void *), XRT_DP_ABI_MSG);
XRT_DP_ABI_ASSERT(sizeof(struct xrt_display_processor_d3d11) == XRT_DP_D3D11_BASE_OFF + 32 * sizeof(void *), XRT_DP_ABI_MSG);

/*!
* Defined when this header carries the five lift slots (lift_get_caps,
Expand Down Expand Up @@ -864,6 +885,13 @@ XRT_DP_ABI_ASSERT(sizeof(struct xrt_display_processor_d3d11)
*/
#define XRT_DP_D3D11_HAS_OVERLAY_2D 1

/*!
* Defined when this header carries the set_overlay_2d_filter_strength slot
* (XR_DXR_weave v15), so a plug-in built against an older runtime can
* #ifdef-guard its implementation. Purely additive (ADR-020).
*/
#define XRT_DP_D3D11_HAS_OVERLAY_2D_FILTER_STRENGTH 1

// clang-format on

/*!
Expand Down Expand Up @@ -1397,6 +1425,23 @@ xrt_display_processor_d3d11_set_overlay_2d(struct xrt_display_processor_d3d11 *x
return xdp->set_overlay_2d(xdp, d3d11_context, overlay_srv, width, height, encoding, layer_unchanged);
}

/*!
* @copydoc xrt_display_processor_d3d11::set_overlay_2d_filter_strength
*
* Helper for calling through the function pointer; a no-op (the DP's default
* applies) when the slot is absent or NULL.
*
* @public @memberof xrt_display_processor_d3d11
*/
static inline void
xrt_display_processor_d3d11_set_overlay_2d_filter_strength(struct xrt_display_processor_d3d11 *xdp, float strength)
{
if (!XRT_DP_HAS_SLOT(xdp, set_overlay_2d_filter_strength) || xdp->set_overlay_2d_filter_strength == NULL) {
return;
}
xdp->set_overlay_2d_filter_strength(xdp, strength);
}

//! True when @p xdp also carries lift_convert_blob (GAUSSIANS).
static inline bool
xrt_display_processor_d3d11_has_lift_blob(struct xrt_display_processor_d3d11 *xdp)
Expand Down
1 change: 1 addition & 0 deletions src/xrt/ipc/client/ipc_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ comp_ipc_client_compositor_weave_submit(struct xrt_compositor *xc,
const struct xrt_rect *flat_rects,
bool mono_in_2d,
bool overlay_unchanged,
float overlay_filter_strength,
bool *out_have_output,
uint32_t *out_width,
uint32_t *out_height,
Expand Down
13 changes: 10 additions & 3 deletions src/xrt/ipc/client/ipc_client_compositor.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,8 @@ weave_pack_submit_args(struct ipc_arg_weave_submit *args,
uint32_t flat_rect_count,
const struct xrt_rect *flat_rects,
bool mono_in_2d,
bool overlay_unchanged)
bool overlay_unchanged,
float overlay_filter_strength)
{
U_ZERO(args);
args->rect_x = rect_x;
Expand Down Expand Up @@ -650,6 +651,10 @@ weave_pack_submit_args(struct ipc_arg_weave_submit *args,
// reuse its lens prefilter of it. Only meaningful with an overlay; 0 (a
// pre-v14 caller) is "may have changed", the old behaviour.
args->overlay_unchanged = (have_overlay && overlay_unchanged) ? 1u : 0u;

// v15: the caller's lens-filter strength for the overlay; negative = not set
// (the DP's own default). Only meaningful with an overlay.
args->overlay_filter_strength = have_overlay ? overlay_filter_strength : -1.0f;
}

xrt_result_t
Expand All @@ -672,6 +677,7 @@ comp_ipc_client_compositor_weave_submit(struct xrt_compositor *xc,
const struct xrt_rect *flat_rects,
bool mono_in_2d,
bool overlay_unchanged,
float overlay_filter_strength,
bool *out_have_output,
uint32_t *out_width,
uint32_t *out_height,
Expand Down Expand Up @@ -706,7 +712,7 @@ comp_ipc_client_compositor_weave_submit(struct xrt_compositor *xc,
const bool have_overlay = (overlay_handle != XRT_GRAPHICS_BUFFER_HANDLE_INVALID);
weave_pack_submit_args(&args, rect_x, rect_y, rect_w, rect_h, rect_count, rects, have_overlay,
overlay_rect_count, overlay_rects, weave_frame_first, layout, flat_rect_count,
flat_rects, mono_in_2d, overlay_unchanged);
flat_rects, mono_in_2d, overlay_unchanged, overlay_filter_strength);

xrt_graphics_buffer_handle_t handles[2] = {in_handle, overlay_handle};
uint32_t handle_count = have_overlay ? 2u : 1u;
Expand Down Expand Up @@ -886,6 +892,7 @@ comp_ipc_client_compositor_weave_submit_dmabuf(struct xrt_compositor *xc,
const struct xrt_rect *flat_rects,
bool mono_in_2d,
bool overlay_unchanged,
float overlay_filter_strength,
int *out_release_fence_fd,
bool *out_have_output,
uint32_t *out_width,
Expand Down Expand Up @@ -928,7 +935,7 @@ comp_ipc_client_compositor_weave_submit_dmabuf(struct xrt_compositor *xc,
struct ipc_arg_weave_submit args;
weave_pack_submit_args(&args, rect_x, rect_y, rect_w, rect_h, rect_count, rects, overlay != NULL,
overlay_rect_count, NULL, weave_frame_first, layout, flat_rect_count, flat_rects,
mono_in_2d, overlay_unchanged);
mono_in_2d, overlay_unchanged, overlay_filter_strength);

struct ipc_arg_weave_dmabuf dmabuf = {0};
weave_pack_dmabuf(&dmabuf.input, in);
Expand Down
2 changes: 2 additions & 0 deletions src/xrt/ipc/server/ipc_server_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -6571,6 +6571,8 @@ ipc_handle_weave_submit(volatile struct ipc_client_state *ics,
struct xrt_eye_positions eyes = {0};
// v14: per submit — a submit without XrWeaveSubmitOverlayUnchangedDXR clears it.
comp_d3d11_service_weave_set_overlay_unchanged(ics->xc, args->overlay_unchanged != 0);
// v15: per submit — negative = not set by the app, the DP's own default applies.
comp_d3d11_service_weave_set_overlay_filter_strength(ics->xc, args->overlay_filter_strength);
bool ok = comp_d3d11_service_weave_submit( //
ics->xc, in_handle, in_is_dxgi, //
args->rect_x, args->rect_y, args->rect_w, args->rect_h, //
Expand Down
5 changes: 5 additions & 0 deletions src/xrt/ipc/shared/ipc_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,11 @@ struct ipc_arg_weave_submit
//! Amendment). Advisory; 0 = may have changed (pre-v14 behaviour). Appended:
//! 828 + 4 = 832 B; the dma-buf call is 4 + 832 + 136 = 972 of 1024.
uint32_t overlay_unchanged;

//! XR_DXR_weave v15 (XrWeaveSubmitOverlayFilterDXR): the caller's lens-filter
//! strength for the overlay, [0,1]; NEGATIVE = not set (the DP's own default).
//! Appended: 832 + 4 = 836 B; the dma-buf call is 4 + 836 + 136 = 976 of 1024.
float overlay_filter_strength;
};

/*!
Expand Down
Loading
Loading