Skip to content

Commit

Permalink
Creation of OXR projection and depth layers
Browse files Browse the repository at this point in the history
  • Loading branch information
shg8 committed Apr 3, 2024
1 parent 620c2d4 commit 15211be
Show file tree
Hide file tree
Showing 16 changed files with 304 additions and 59 deletions.
File renamed without changes.
8 changes: 5 additions & 3 deletions apps/vr_viewer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ add_executable(3dgs_vr_viewer
src/main.cpp
src/VRViewer.cpp
src/VRViewer.h
src/OXRUtils.h
src/OXRContext.cpp
src/OXRContext.h
src/oxr/Utils.h
src/oxr/OXRContext.cpp
src/oxr/OXRContext.h
src/oxr/Layer.cpp
src/oxr/Layer.h
)

target_compile_definitions(3dgs_cpp PUBLIC VKGS_ENABLE_OPENXR)
Expand Down
42 changes: 0 additions & 42 deletions apps/vr_viewer/src/OXRContext.h

This file was deleted.

13 changes: 13 additions & 0 deletions apps/vr_viewer/src/VRViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,31 @@
#include "3dgs.h"
#include "spdlog/spdlog.h"

using namespace OXR;

void VRViewer::run() {
context = std::make_shared<OXRContext>();
context->setup();

VulkanSplatting::OpenXRConfiguration configuration;
configuration.instanceExtensions = context->getRequiredVulkanInstanceExtensions();
configuration.deviceExtensions = context->getRequiredVulkanDeviceExtensions();
configuration.getPhysicalDevice = std::bind(&OXRContext::getPhysicalDevice, context.get(), std::placeholders::_1);
configuration.postVulkanInit = std::bind(&VRViewer::finishSetup, this, std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, std::placeholders::_4, std::placeholders::_5);

auto renderingTarget = VulkanSplatting::createOpenXRRenderingTarget(configuration);
}

void VRViewer::finishSetup(void *vkInstance, void *vkPhysicalDevice, void *vkDevice, uint32_t vkQueueFamilyIndex,
uint32_t vkQueueIndex) {
context->createSession(vkInstance, vkPhysicalDevice, vkDevice, vkQueueFamilyIndex, vkQueueIndex);
context->createReferenceSpace();
context->beginSession();
createProjectionLayer();
}

void VRViewer::createProjectionLayer() {

}

14 changes: 4 additions & 10 deletions apps/vr_viewer/src/VRViewer.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <memory>
#include <utility>

#include "OXRContext.h"
#include "oxr/OXRContext.h"

class VRViewer {
public:
Expand All @@ -17,21 +17,15 @@ class VRViewer {

explicit VRViewer(const VRViewer::Configuration & config) : config(config) {};

VRViewer(const VRViewer &other) = delete;

VRViewer(VRViewer &&other) = delete;

VRViewer & operator=(const VRViewer &other) = delete;

VRViewer & operator=(VRViewer &&other) = delete;

void run();

void finishSetup(void *vkInstance, void *vkPhysicalDevice, void *vkDevice, uint32_t vkQueueFamilyIndex, uint32_t vkQueueIndex);

private:
Configuration config;
std::shared_ptr<OXRContext> context = nullptr;
std::shared_ptr<OXR::OXRContext> context = nullptr;

void createProjectionLayer();
};


Expand Down
154 changes: 154 additions & 0 deletions apps/vr_viewer/src/oxr/Layer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#include "Layer.h"

#include "Utils.h"
#include "spdlog/spdlog.h"
#include "vk_enum_string_helper.h"

namespace OXR {
Layer::Layer(std::shared_ptr<OXRContext> context, XrCompositionLayerFlags flags, bool depth_enabled) : depthEnabled(
depth_enabled) {
createSwapchains(context);
createProjectionViews(context, flags);
}

void Layer::createSwapchains(std::shared_ptr<OXRContext> context) {
// Print the swapchain formats
spdlog::info("Swapchain formats:");
auto swapchainFormats = getVulkanFormatsForSwapchain(context);
for (vk::Format format: swapchainFormats) {
spdlog::info("{}", string_VkFormat(static_cast<VkFormat>(format)));
}

std::vector<XrSwapchainImageVulkanKHR> swapchainImageVectors[2];
for (int i = 0; i < 2; i++) {
XrSwapchainCreateInfo swapchainCreateInfo = {XR_TYPE_SWAPCHAIN_CREATE_INFO};
swapchainCreateInfo.arraySize = 1;
swapchainCreateInfo.format = static_cast<int64_t>(swapchainFormats[0]);
swapchainCreateInfo.width = context->views[i].recommendedImageRectWidth;
swapchainCreateInfo.height = context->views[i].recommendedImageRectHeight;
swapchainCreateInfo.mipCount = 1;
swapchainCreateInfo.faceCount = 1;
swapchainCreateInfo.sampleCount = 1;
swapchainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_SAMPLED_BIT |
XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT |
XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
swapchainCreateInfo.createFlags = 0;

spdlog::debug("Creating swapchain with format and size: {} {}x{}", string_VkFormat(
static_cast<VkFormat>(swapchainCreateInfo.format)), swapchainCreateInfo.width,
swapchainCreateInfo.height);

XR_CHECK(xrCreateSwapchain(context->oxrSession, &swapchainCreateInfo, &swapchains[i]),
"Failed to create swapchain");

uint32_t swapchainLength;
XR_CHECK(xrEnumerateSwapchainImages(swapchains[i], 0, &swapchainLength, nullptr),
"Failed to enumerate swapchain images");

std::vector<XrSwapchainImageVulkanKHR> swapchainImages(swapchainLength);
for (uint32_t j = 0; j < swapchainLength; j++) {
swapchainImages[j] = {XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR};
}

XR_CHECK(xrEnumerateSwapchainImages(swapchains[i], swapchainLength, &swapchainLength,
reinterpret_cast<XrSwapchainImageBaseHeader *>(swapchainImages.data())),
"Failed to enumerate swapchain images");

swapchainImageVectors[i] = swapchainImages;
swapchainSize[i] = swapchainLength;
}

assert(swapchainSize[0] == swapchainSize[1]);

images.resize(swapchainSize[0]);
for (uint32_t i = 0; i < swapchainSize[0]; i++) {
images[i][0] = swapchainImageVectors[0][i];
images[i][1] = swapchainImageVectors[1][i];
}

if (!depthEnabled) {
return;
}

vk::Format selectedDepthFormat = vk::Format::eUndefined;
for (vk::Format format: swapchainFormats) {
if (format == vk::Format::eD32Sfloat) {
selectedDepthFormat = format;
break;
} else if (format == vk::Format::eD16Unorm) {
selectedDepthFormat = format;
}
}

if (selectedDepthFormat == vk::Format::eUndefined) {
spdlog::error("No depth format found");
return;
}

spdlog::info("Depth format: {}", string_VkFormat(static_cast<VkFormat>(selectedDepthFormat)));

for (int i = 0; i < 2; i++) {
XrSwapchainCreateInfo swapchainCreateInfo = {XR_TYPE_SWAPCHAIN_CREATE_INFO};
swapchainCreateInfo.arraySize = 1;
swapchainCreateInfo.format = static_cast<int64_t>(selectedDepthFormat);
swapchainCreateInfo.width = context->views[i].recommendedImageRectWidth;
swapchainCreateInfo.height = context->views[i].recommendedImageRectHeight;
swapchainCreateInfo.mipCount = 1;
swapchainCreateInfo.faceCount = 1;
swapchainCreateInfo.sampleCount = 1;
swapchainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT |
XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
swapchainCreateInfo.createFlags = 0;

spdlog::debug("Creating depth swapchain with format and size: {} {}x{}", string_VkFormat(
static_cast<VkFormat>(swapchainCreateInfo.format)), swapchainCreateInfo.width,
swapchainCreateInfo.height);

XR_CHECK(xrCreateSwapchain(context->oxrSession, &swapchainCreateInfo, &depthSwapchains[i]),
"Failed to create depth swapchain");

uint32_t swapchainLength;
XR_CHECK(xrEnumerateSwapchainImages(depthSwapchains[i], 0, &swapchainLength, nullptr),
"Failed to enumerate depth swapchain images");

std::vector<XrSwapchainImageVulkanKHR> swapchainImages(swapchainLength);
for (uint32_t j = 0; j < swapchainLength; j++) {
swapchainImages[j] = {XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR};
}

XR_CHECK(xrEnumerateSwapchainImages(depthSwapchains[i], swapchainLength, &swapchainLength,
reinterpret_cast<XrSwapchainImageBaseHeader *>(swapchainImages.data())),
"Failed to enumerate depth swapchain images");

depthImages.resize(swapchainLength);
for (uint32_t j = 0; j < swapchainLength; j++) {
depthImages[j][0] = swapchainImages[j];
depthImages[j][1] = swapchainImages[j];
}

depthSwapchainSize[i] = swapchainLength;
}
}

void Layer::createProjectionViews(std::shared_ptr<OXRContext> context, uint64_t flags) {
for (int i = 0; i < 2; i++) {
views[i].pose = {.position = { 0.0f, 0.0f, 0.0f }, .orientation = { 0.0f, 0.0f, 0.0f, 1.0f }};
views[i].subImage.swapchain = swapchains[i];
views[i].subImage.imageRect.offset = {0, 0};
views[i].subImage.imageRect.extent = {static_cast<int32_t>(context->views[i].recommendedImageRectWidth),
static_cast<int32_t>(context->views[i].recommendedImageRectHeight)};
if (depthEnabled) {
views[i].next = &depthLayer;
depthLayer.subImage.swapchain = depthSwapchains[i];
depthLayer.subImage.imageRect.offset = {0, 0};
depthLayer.subImage.imageRect.extent = {static_cast<int32_t>(context->views[i].recommendedImageRectWidth),
static_cast<int32_t>(context->views[i].recommendedImageRectHeight)};
}
}

layer.layerFlags = flags;
layer.space = context->localSpace;
layer.viewCount = 2;
layer.views = views;
}
} // OXR
40 changes: 40 additions & 0 deletions apps/vr_viewer/src/oxr/Layer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef LAYER_H
#define LAYER_H
#include <cstdint>
#include <memory>
#include <vector>
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>

#include "OXRContext.h"

namespace OXR {

class Layer {
public:
explicit Layer(std::shared_ptr<OXRContext> context, XrCompositionLayerFlags flags, bool depth_enabled);


private:
XrCompositionLayerProjection layer = {XR_TYPE_COMPOSITION_LAYER_PROJECTION};
XrCompositionLayerDepthInfoKHR depthLayer = {XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR};
XrCompositionLayerProjectionView views[2] = {{XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW}, {XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW}};
XrSwapchain swapchains[2] = {XR_NULL_HANDLE, XR_NULL_HANDLE};
uint32_t swapchainSize[2] = {0, 0};
uint32_t lastImageAcquired[2] = {0, 0};

bool depthEnabled = false;
XrSwapchain depthSwapchains[2] = {XR_NULL_HANDLE, XR_NULL_HANDLE};
uint32_t depthSwapchainSize[2] = {0, 0};
uint32_t lastDepthImageAcquired[2] = {0, 0};

std::vector<std::array<XrSwapchainImageVulkanKHR, 2>> images;
std::vector<std::array<XrSwapchainImageVulkanKHR, 2>> depthImages;

void createSwapchains(std::shared_ptr<OXRContext> context);
void createProjectionViews(std::shared_ptr<OXRContext> context, uint64_t flags);
};

} // OXR

#endif //LAYER_H
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>

#include "Utils.h"
#include "spdlog/spdlog.h"

using namespace OXR;

void OXRContext::setup() {
bool vulkanSupported = OXR::isExtensionSupported(XR_KHR_VULKAN_ENABLE_EXTENSION_NAME);
if (!vulkanSupported) {
Expand Down
40 changes: 40 additions & 0 deletions apps/vr_viewer/src/oxr/OXRContext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

#ifndef OXRCONTEXT_H
#define OXRCONTEXT_H
#include <openxr/openxr.h>
#include <vulkan/vulkan.hpp>

namespace OXR {
class OXRContext {
public:
void setup();
void* getPhysicalDevice(void *instance) const;

void createSession(void *vkInstance, void *vkPhysicalDevice, void *vkDevice, uint32_t vkQueueFamilyIndex,
uint32_t vkQueueIndex);

void createReferenceSpace();

void beginSession();

[[nodiscard]] std::vector<std::string> getRequiredVulkanInstanceExtensions() const;

[[nodiscard]] std::vector<std::string> getRequiredVulkanDeviceExtensions() const;

XrInstance oxrInstance = XR_NULL_HANDLE;
XrSystemId systemId = XR_NULL_SYSTEM_ID;
XrViewConfigurationView views[2] = {{XR_TYPE_VIEW_CONFIGURATION_VIEW}, {XR_TYPE_VIEW_CONFIGURATION_VIEW}};
XrSession oxrSession = XR_NULL_HANDLE;
XrSpace localSpace = XR_NULL_HANDLE;

private:
void createInstance();

void createSystem();

void setupViews();

};
}

#endif //OXRCONTEXT_H
Loading

0 comments on commit 15211be

Please sign in to comment.