OpenXR - Multiview refactor to make it optional

This commit is contained in:
Lubos 2022-08-29 22:06:59 +02:00
parent 94968c3075
commit 462174f548
6 changed files with 90 additions and 100 deletions

View file

@ -90,7 +90,7 @@ void EnterVR(bool firstStart) {
VR_EnterVR(VR_GetEngine());
IN_VRInit(VR_GetEngine());
}
VR_InitRenderer(VR_GetEngine());
VR_InitRenderer(VR_GetEngine(), IsMultiviewSupported());
}
void GetVRResolutionPerEye(int* width, int* height) {

View file

@ -92,14 +92,14 @@ typedef struct {
typedef struct {
int Width;
int Height;
bool Multiview;
uint32_t TextureSwapChainLength;
uint32_t TextureSwapChainIndex;
ovrSwapChain ColorSwapChain;
ovrSwapChain DepthSwapChain;
XrSwapchainImageOpenGLESKHR* ColorSwapChainImage;
XrSwapchainImageOpenGLESKHR* DepthSwapChainImage;
unsigned int* DepthBuffers;
unsigned int* FrameBuffers;
bool Acquired[2];
bool Acquired;
} ovrFramebuffer;
typedef struct {

View file

@ -33,23 +33,17 @@ void ovrFramebuffer_Clear(ovrFramebuffer* frameBuffer) {
frameBuffer->ColorSwapChain.Handle = XR_NULL_HANDLE;
frameBuffer->ColorSwapChain.Width = 0;
frameBuffer->ColorSwapChain.Height = 0;
frameBuffer->DepthSwapChain.Handle = XR_NULL_HANDLE;
frameBuffer->DepthSwapChain.Width = 0;
frameBuffer->DepthSwapChain.Height = 0;
frameBuffer->DepthBuffers = NULL;
frameBuffer->FrameBuffers = NULL;
frameBuffer->Acquired[0] = false;
frameBuffer->Acquired[1] = false;
frameBuffer->Acquired = false;
}
bool ovrFramebuffer_Create(
XrSession session,
ovrFramebuffer* frameBuffer,
const int width,
const int height) {
bool ovrFramebuffer_Create(XrSession session, ovrFramebuffer* frameBuffer, int width, int height, bool multiview) {
frameBuffer->Width = width;
frameBuffer->Height = height;
frameBuffer->Multiview = multiview;
if (strstr((const char*)glGetString(GL_EXTENSIONS), "GL_OVR_multiview2") == nullptr)
{
@ -68,37 +62,27 @@ bool ovrFramebuffer_Create(
XrSwapchainCreateInfo swapChainCreateInfo;
memset(&swapChainCreateInfo, 0, sizeof(swapChainCreateInfo));
swapChainCreateInfo.type = XR_TYPE_SWAPCHAIN_CREATE_INFO;
swapChainCreateInfo.format = GL_RGBA8;
swapChainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
swapChainCreateInfo.sampleCount = 1;
swapChainCreateInfo.width = width;
swapChainCreateInfo.height = height;
swapChainCreateInfo.faceCount = 1;
swapChainCreateInfo.mipCount = 1;
swapChainCreateInfo.arraySize = 1; //TODO:set to 2 to enable multiview
swapChainCreateInfo.arraySize = multiview ? 2 : 1;
frameBuffer->ColorSwapChain.Width = swapChainCreateInfo.width;
frameBuffer->ColorSwapChain.Height = swapChainCreateInfo.height;
frameBuffer->DepthSwapChain.Width = swapChainCreateInfo.width;
frameBuffer->DepthSwapChain.Height = swapChainCreateInfo.height;
// Create the color swapchain.
swapChainCreateInfo.format = GL_RGBA8;
swapChainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
OXR(xrCreateSwapchain(session, &swapChainCreateInfo, &frameBuffer->ColorSwapChain.Handle));
OXR(xrEnumerateSwapchainImages(frameBuffer->ColorSwapChain.Handle, 0, &frameBuffer->TextureSwapChainLength, NULL));
frameBuffer->ColorSwapChainImage = (XrSwapchainImageOpenGLESKHR*)malloc(frameBuffer->TextureSwapChainLength * sizeof(XrSwapchainImageOpenGLESKHR));
// Create the depth swapchain.
swapChainCreateInfo.format = GL_DEPTH24_STENCIL8;
swapChainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
OXR(xrCreateSwapchain(session, &swapChainCreateInfo, &frameBuffer->DepthSwapChain.Handle));
frameBuffer->DepthSwapChainImage = (XrSwapchainImageOpenGLESKHR*)malloc(frameBuffer->TextureSwapChainLength * sizeof(XrSwapchainImageOpenGLESKHR));
// Populate the swapchain image array.
for (uint32_t i = 0; i < frameBuffer->TextureSwapChainLength; i++) {
frameBuffer->ColorSwapChainImage[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR;
frameBuffer->ColorSwapChainImage[i].next = NULL;
frameBuffer->DepthSwapChainImage[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR;
frameBuffer->DepthSwapChainImage[i].next = NULL;
}
OXR(xrEnumerateSwapchainImages(
frameBuffer->ColorSwapChain.Handle,
@ -106,25 +90,52 @@ bool ovrFramebuffer_Create(
&frameBuffer->TextureSwapChainLength,
(XrSwapchainImageBaseHeader*)frameBuffer->ColorSwapChainImage));
OXR(xrEnumerateSwapchainImages(
frameBuffer->DepthSwapChain.Handle,
frameBuffer->TextureSwapChainLength,
&frameBuffer->TextureSwapChainLength,
(XrSwapchainImageBaseHeader*)frameBuffer->DepthSwapChainImage));
frameBuffer->DepthBuffers = (GLuint*)malloc(frameBuffer->TextureSwapChainLength * sizeof(GLuint));
frameBuffer->FrameBuffers = (GLuint*)malloc(frameBuffer->TextureSwapChainLength * sizeof(GLuint));
for (uint32_t i = 0; i < frameBuffer->TextureSwapChainLength; i++) {
const GLuint colorTexture = frameBuffer->ColorSwapChainImage[i].image;
const GLuint depthTexture = frameBuffer->DepthSwapChainImage[i].image;
if (multiview) {
// Create the color buffer texture.
GLenum textureTarget = GL_TEXTURE_2D_ARRAY;
GL(glBindTexture(textureTarget, colorTexture));
GL(glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GL(glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
GL(glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GL(glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GL(glBindTexture(textureTarget, 0));
// Create the frame buffer.
GL(glGenFramebuffers(1, &frameBuffer->FrameBuffers[i]));
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer->FrameBuffers[i]));
if (swapChainCreateInfo.arraySize > 1) {
GL(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0, 0, 2));
// Create depth buffer.
GL(glGenTextures(1, &frameBuffer->DepthBuffers[i]));
GL(glBindTexture(textureTarget, frameBuffer->DepthBuffers[i]));
GL(glTexStorage3D(textureTarget, 1, GL_DEPTH_COMPONENT24, width, height, 2));
GL(glBindTexture(textureTarget, 0));
// Create the frame buffer.
GL(glGenFramebuffers(1, &frameBuffer->FrameBuffers[i]));
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer->FrameBuffers[i]));
GL(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, frameBuffer->DepthBuffers[i], 0, 0, 2));
GL(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorTexture, 0, 0, 2));
} else {
GL(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0));
// Create the color buffer texture.
GLenum colorTextureTarget = GL_TEXTURE_2D;
GL(glBindTexture(colorTextureTarget, colorTexture));
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GL(glBindTexture(colorTextureTarget, 0));
// Create depth buffer.
GL(glGenRenderbuffers(1, &frameBuffer->DepthBuffers[i]));
GL(glBindRenderbuffer(GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
GL(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height));
GL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
// Create the frame buffer.
GL(glGenFramebuffers(1, &frameBuffer->FrameBuffers[i]));
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer->FrameBuffers[i]));
GL(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
GL(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
GL(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0));
}
GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
@ -140,10 +151,14 @@ bool ovrFramebuffer_Create(
void ovrFramebuffer_Destroy(ovrFramebuffer* frameBuffer) {
GL(glDeleteFramebuffers(frameBuffer->TextureSwapChainLength, frameBuffer->FrameBuffers));
OXR(xrDestroySwapchain(frameBuffer->DepthSwapChain.Handle));
if (frameBuffer->Multiview) {
GL(glDeleteFramebuffers(frameBuffer->TextureSwapChainLength, frameBuffer->DepthBuffers));
} else {
GL(glDeleteRenderbuffers(frameBuffer->TextureSwapChainLength, frameBuffer->DepthBuffers));
}
OXR(xrDestroySwapchain(frameBuffer->ColorSwapChain.Handle));
free(frameBuffer->DepthSwapChainImage);
free(frameBuffer->ColorSwapChainImage);
free(frameBuffer->DepthBuffers);
free(frameBuffer->FrameBuffers);
ovrFramebuffer_Clear(frameBuffer);
@ -164,38 +179,31 @@ void ovrFramebuffer_Resolve(ovrFramebuffer* frameBuffer) {
}
void ovrFramebuffer_Acquire(ovrFramebuffer* frameBuffer) {
ovrSwapChain swapChains[2] = {frameBuffer->ColorSwapChain, frameBuffer->DepthSwapChain};
XrSwapchainImageAcquireInfo acquireInfo = {XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO, NULL};
OXR(xrAcquireSwapchainImage(frameBuffer->ColorSwapChain.Handle, &acquireInfo, &frameBuffer->TextureSwapChainIndex));
for (int index = 0; index < 2; index++) {
XrSwapchainImageAcquireInfo acquireInfo = {XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO, NULL};
OXR(xrAcquireSwapchainImage(swapChains[index].Handle, &acquireInfo, &frameBuffer->TextureSwapChainIndex));
XrSwapchainImageWaitInfo waitInfo;
waitInfo.type = XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO;
waitInfo.next = NULL;
waitInfo.timeout = 1000; /* timeout in nanoseconds */
XrResult res = xrWaitSwapchainImage(swapChains[index].Handle, &waitInfo);
int i = 0;
while ((res != XR_SUCCESS) && (i < 10)) {
res = xrWaitSwapchainImage(swapChains[index].Handle, &waitInfo);
i++;
ALOGV(
" Retry xrWaitSwapchainImage %d times due to XR_TIMEOUT_EXPIRED (duration %f micro seconds)",
i,
waitInfo.timeout * (1E-9));
}
frameBuffer->Acquired[index] = res == XR_SUCCESS;
XrSwapchainImageWaitInfo waitInfo;
waitInfo.type = XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO;
waitInfo.next = NULL;
waitInfo.timeout = 1000; /* timeout in nanoseconds */
XrResult res = xrWaitSwapchainImage(frameBuffer->ColorSwapChain.Handle, &waitInfo);
int i = 0;
while ((res != XR_SUCCESS) && (i < 10)) {
res = xrWaitSwapchainImage(frameBuffer->ColorSwapChain.Handle, &waitInfo);
i++;
ALOGV(
" Retry xrWaitSwapchainImage %d times due to XR_TIMEOUT_EXPIRED (duration %f micro seconds)",
i,
waitInfo.timeout * (1E-9));
}
frameBuffer->Acquired = res == XR_SUCCESS;
}
void ovrFramebuffer_Release(ovrFramebuffer* frameBuffer) {
ovrSwapChain swapChains[2] = {frameBuffer->ColorSwapChain, frameBuffer->DepthSwapChain};
for (int index = 0; index < 2; index++) {
if (frameBuffer->Acquired[index]) {
XrSwapchainImageReleaseInfo releaseInfo = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, NULL};
OXR(xrReleaseSwapchainImage(swapChains[index].Handle, &releaseInfo));
frameBuffer->Acquired[index] = false;
}
if (frameBuffer->Acquired) {
XrSwapchainImageReleaseInfo releaseInfo = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, NULL};
OXR(xrReleaseSwapchainImage(frameBuffer->ColorSwapChain.Handle, &releaseInfo));
frameBuffer->Acquired = false;
}
}
@ -211,17 +219,8 @@ void ovrRenderer_Clear(ovrRenderer* renderer) {
ovrFramebuffer_Clear(&renderer->FrameBuffer);
}
void ovrRenderer_Create(
XrSession session,
ovrRenderer* renderer,
int suggestedEyeTextureWidth,
int suggestedEyeTextureHeight) {
// Create the frame buffers.
ovrFramebuffer_Create(
session,
&renderer->FrameBuffer,
suggestedEyeTextureWidth,
suggestedEyeTextureHeight);
void ovrRenderer_Create(XrSession session, ovrRenderer* renderer, int width, int height, bool multiview) {
ovrFramebuffer_Create(session, &renderer->FrameBuffer, width, height, multiview);
}
void ovrRenderer_Destroy(ovrRenderer* renderer) {

View file

@ -12,9 +12,5 @@ void ovrFramebuffer_Release(ovrFramebuffer* frameBuffer);
void ovrFramebuffer_SetCurrent(ovrFramebuffer* frameBuffer);
void ovrFramebuffer_SetNone();
void ovrRenderer_Create(
XrSession session,
ovrRenderer* renderer,
int suggestedEyeTextureWidth,
int suggestedEyeTextureHeight);
void ovrRenderer_Create(XrSession session, ovrRenderer* renderer, int width, int height, bool multiview);
void ovrRenderer_Destroy(ovrRenderer* renderer);

View file

@ -175,7 +175,7 @@ void VR_Recenter(engine_t* engine) {
menuYaw = 0;
}
void VR_InitRenderer( engine_t* engine ) {
void VR_InitRenderer( engine_t* engine, bool multiview ) {
if (initialized) {
VR_DestroyRenderer(engine);
}
@ -185,18 +185,12 @@ void VR_InitRenderer( engine_t* engine ) {
// Get the viewport configuration info for the chosen viewport configuration type.
engine->appState.ViewportConfig.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES;
OXR(xrGetViewConfigurationProperties(
engine->appState.Instance, engine->appState.SystemId, XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, &engine->appState.ViewportConfig));
OXR(xrGetViewConfigurationProperties(engine->appState.Instance, engine->appState.SystemId, XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, &engine->appState.ViewportConfig));
uint32_t numOutputSpaces = 0;
OXR(xrEnumerateReferenceSpaces(engine->appState.Session, 0, &numOutputSpaces, NULL));
XrReferenceSpaceType* referenceSpaces =
(XrReferenceSpaceType*)malloc(numOutputSpaces * sizeof(XrReferenceSpaceType));
OXR(xrEnumerateReferenceSpaces(
engine->appState.Session, numOutputSpaces, &numOutputSpaces, referenceSpaces));
XrReferenceSpaceType* referenceSpaces = (XrReferenceSpaceType*)malloc(numOutputSpaces * sizeof(XrReferenceSpaceType));
OXR(xrEnumerateReferenceSpaces(engine->appState.Session, numOutputSpaces, &numOutputSpaces, referenceSpaces));
for (uint32_t i = 0; i < numOutputSpaces; i++) {
if (referenceSpaces[i] == XR_REFERENCE_SPACE_TYPE_STAGE) {
@ -217,7 +211,8 @@ void VR_InitRenderer( engine_t* engine ) {
engine->appState.Session,
&engine->appState.Renderer,
engine->appState.ViewConfigurationView[0].recommendedImageRectWidth,
engine->appState.ViewConfigurationView[0].recommendedImageRectHeight);
engine->appState.ViewConfigurationView[0].recommendedImageRectHeight,
multiview);
initialized = GL_TRUE;
}
@ -432,9 +427,9 @@ void VR_SetConfig( VRConfig config, int value) {
void VR_BindFramebuffer(engine_t *engine) {
if (!initialized) return;
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer;
int swapchainIndex = frameBuffer->TextureSwapChainIndex;
int glFramebuffer = frameBuffer->FrameBuffers[swapchainIndex];
GL(glBindFramebuffer(GL_FRAMEBUFFER, glFramebuffer));
unsigned int swapchainIndex = frameBuffer->TextureSwapChainIndex;
unsigned int glFramebuffer = frameBuffer->FrameBuffers[swapchainIndex];
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, glFramebuffer));
}
ovrMatrix4f VR_GetMatrix( VRMatrix matrix ) {

View file

@ -35,7 +35,7 @@ enum VRMode {
};
void VR_GetResolution( engine_t* engine, int *pWidth, int *pHeight );
void VR_InitRenderer( engine_t* engine );
void VR_InitRenderer( engine_t* engine, bool multiview );
void VR_DestroyRenderer( engine_t* engine );
bool VR_BeginFrame( engine_t* engine );