mirror of
https://github.com/InstanceBrick/nightcap.git
synced 2026-10-29 04:01:45 +01:00
1 parent
a014751cd4
commit
5e24bee4ab
4 files changed
+72
-7
No files matched your search
@@ -161,6 +161,7 @@ class OpenXrBackend final {
|
||||
// hands[0]=left, hands[1]=right carry this frame's tracked controller grip
|
||||
// poses (metres, LOCAL space) when a controller layer is active.
|
||||
ScriptedPoseSample PublishedHeadPose() const;
|
||||
bool RecommendedEyeExtent(std::uint32_t* width, std::uint32_t* height) const;
|
||||
void NotePoseApplied(void* owner, std::uint64_t frame);
|
||||
|
||||
// Controller input delivery, consumed by the window-thread input runtime
|
||||
@@ -289,6 +290,8 @@ class OpenXrBackend final {
|
||||
void* xr_session_ = nullptr;
|
||||
void* xr_local_space_ = nullptr;
|
||||
void* xr_view_space_ = nullptr;
|
||||
std::uint32_t xr_eye_width_[2] = {};
|
||||
std::uint32_t xr_eye_height_[2] = {};
|
||||
EyeSwapchain eye_swapchains_[2];
|
||||
int xr_blend_mode_ = 0;
|
||||
// Runtime name captured at xrCreateInstance so the bind-time diagnostics line
|
||||
|
||||
@@ -309,9 +309,8 @@ void GlesTransport::Bind(unsigned target, unsigned framebuffer,
|
||||
if (it == storage.end())
|
||||
return;
|
||||
const auto &size = it->second;
|
||||
// DebugDeviceVR currently creates single-sample 500x500 RGBA eyes.
|
||||
// Reject unsupported formats/extents instead of copying unrelated pixels.
|
||||
if (size.width != 500 || size.height != 500 || size.samples != 0 ||
|
||||
if (size.samples != 0 ||
|
||||
(size.format != GL_RGBA8 && size.format != GL_RGBA &&
|
||||
size.format != GL_SRGB8_ALPHA8))
|
||||
return;
|
||||
|
||||
@@ -878,6 +878,42 @@ bool OpenXrBackend::InitializeSessionResourcesLocked(std::string *error) {
|
||||
xr_blend_mode_ = static_cast<int>(blends[index]);
|
||||
}
|
||||
|
||||
std::uint32_t view_count = 0;
|
||||
const XrInstance instance = static_cast<XrInstance>(xr_instance_);
|
||||
CheckXr(instance,
|
||||
xrEnumerateViewConfigurationViews(
|
||||
instance, static_cast<XrSystemId>(xr_system_),
|
||||
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, 0, &view_count,
|
||||
nullptr),
|
||||
"xrEnumerateViewConfigurationViews count");
|
||||
Require(view_count >= 2,
|
||||
"OpenXR primary stereo configuration exposes fewer than two views");
|
||||
|
||||
std::vector<XrViewConfigurationView> config_views(view_count);
|
||||
for (auto& view : config_views) {
|
||||
view = XrInfo<XrViewConfigurationView>(XR_TYPE_VIEW_CONFIGURATION_VIEW);
|
||||
}
|
||||
|
||||
CheckXr(instance,
|
||||
xrEnumerateViewConfigurationViews(
|
||||
instance, static_cast<XrSystemId>(xr_system_),
|
||||
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, view_count,
|
||||
&view_count, config_views.data()),
|
||||
"xrEnumerateViewConfigurationViews");
|
||||
|
||||
xr_eye_width_[0] = config_views[0].recommendedImageRectWidth;
|
||||
xr_eye_height_[0] = config_views[0].recommendedImageRectHeight;
|
||||
xr_eye_width_[1] = config_views[1].recommendedImageRectWidth;
|
||||
xr_eye_height_[1] = config_views[1].recommendedImageRectHeight;
|
||||
|
||||
Require(xr_eye_width_[0] != 0 && xr_eye_height_[0] != 0 &&
|
||||
xr_eye_width_[1] != 0 && xr_eye_height_[1] != 0,
|
||||
"OpenXR returned zero recommended stereo eye extent");
|
||||
|
||||
Log(" [vr-backend] OpenXR recommended eye extents L=%ux%u R=%ux%u\n",
|
||||
xr_eye_width_[0], xr_eye_height_[0], xr_eye_width_[1],
|
||||
xr_eye_height_[1]);
|
||||
|
||||
if (!CreateSwapchains(error)) {
|
||||
TeardownSessionLocked("swapchain failure", session_recovery_pending_);
|
||||
return false;
|
||||
@@ -936,11 +972,10 @@ bool OpenXrBackend::CreateSwapchains(std::string* error) {
|
||||
Require(chosen != VK_FORMAT_UNDEFINED,
|
||||
"the runtime exposes no 8-bit RGBA swapchain format");
|
||||
|
||||
// Default eye extent until the guest eye images are bound; the simulator
|
||||
// runtime advertises 500x500-capable limits, and DebugDeviceVR renders
|
||||
// 500x500. Re-created lazily if the recorded eye extent differs.
|
||||
const std::uint32_t width = 500;
|
||||
const std::uint32_t height = 500;
|
||||
const std::uint32_t width =
|
||||
std::max(xr_eye_width_[0], xr_eye_width_[1]);
|
||||
const std::uint32_t height =
|
||||
std::max(xr_eye_height_[0], xr_eye_height_[1]);
|
||||
for (int eye = 0; eye < 2; ++eye) {
|
||||
auto create_info =
|
||||
XrInfo<XrSwapchainCreateInfo>(XR_TYPE_SWAPCHAIN_CREATE_INFO);
|
||||
@@ -1354,6 +1389,22 @@ ScriptedPoseSample OpenXrBackend::PublishedHeadPose() const {
|
||||
return published_pose_;
|
||||
}
|
||||
|
||||
bool OpenXrBackend::RecommendedEyeExtent(std::uint32_t* width,
|
||||
std::uint32_t* height) const {
|
||||
if (width == nullptr || height == nullptr) {
|
||||
return false;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (xr_instance_ == nullptr || xr_system_ == 0 ||
|
||||
xr_eye_width_[0] == 0 || xr_eye_height_[0] == 0 ||
|
||||
xr_eye_width_[1] == 0 || xr_eye_height_[1] == 0) {
|
||||
return false;
|
||||
}
|
||||
*width = std::max(xr_eye_width_[0], xr_eye_width_[1]);
|
||||
*height = std::max(xr_eye_height_[0], xr_eye_height_[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenXrBackend::TakeControllerDelivery(ControllerDelivery* out) {
|
||||
if (out == nullptr) {
|
||||
return false;
|
||||
|
||||
@@ -1067,6 +1067,18 @@ void RobloxVrDeviceBridge::TryInitializeEyes(void *self) {
|
||||
const auto initializer = reinterpret_cast<EyeInitializerFn>(
|
||||
image_base_.load(std::memory_order_acquire) +
|
||||
profile_.eye_initializer_rva);
|
||||
|
||||
if (auto* backend = ActiveVrBackend()) {
|
||||
std::uint32_t width = 0;
|
||||
std::uint32_t height = 0;
|
||||
if (backend->RecommendedEyeExtent(&width, &height)) {
|
||||
*reinterpret_cast<std::uint32_t*>(bytes + kWidthOffset) = width;
|
||||
*reinterpret_cast<std::uint32_t*>(bytes + kHeightOffset) = height;
|
||||
Log(" [vr-device][evidence] using OpenXR recommended eye extent %ux%u\n",
|
||||
width, height);
|
||||
}
|
||||
}
|
||||
|
||||
Log(" [vr-device][evidence] eye-init-begin self=%p device=%p tid=%" PRIu64
|
||||
" presents=%" PRIu64 "\n",
|
||||
self, device, CurrentThreadId(),
|
||||
|
||||
Reference in new issue
Block a user