Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenXR - Major review #17636

Merged
merged 4 commits into from
Jun 27, 2023
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
402 changes: 203 additions & 199 deletions Common/VR/PPSSPPVR.cpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Common/VR/PPSSPPVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ bool Is2DVRObject(float* projMatrix, bool ortho);
void UpdateVRParams(float* projMatrix, float* viewMatrix);
void UpdateVRProjection(float* projMatrix, float* leftEye, float* rightEye);
void UpdateVRView(float* leftEye, float* rightEye);
void UpdateVRViewMatrices();
3 changes: 2 additions & 1 deletion Common/VR/VRBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,9 @@ typedef struct {
uint32_t TextureSwapChainLength;
uint32_t TextureSwapChainIndex;
ovrSwapChain ColorSwapChain;
ovrSwapChain DepthSwapChain;
void* ColorSwapChainImage;
unsigned int* GLDepthBuffers;
void* DepthSwapChainImage;
unsigned int* GLFrameBuffers;
VkFramebuffer* VKFrameBuffers;
VkImageView* VKColorImages;
Expand Down
99 changes: 54 additions & 45 deletions Common/VR/VRFramebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ void ovrFramebuffer_Clear(ovrFramebuffer* frameBuffer) {
frameBuffer->ColorSwapChain.Width = 0;
frameBuffer->ColorSwapChain.Height = 0;
frameBuffer->ColorSwapChainImage = NULL;
frameBuffer->DepthSwapChain.Handle = XR_NULL_HANDLE;
frameBuffer->DepthSwapChain.Width = 0;
frameBuffer->DepthSwapChain.Height = 0;
frameBuffer->DepthSwapChainImage = NULL;

frameBuffer->GLDepthBuffers = NULL;
frameBuffer->GLFrameBuffers = NULL;
frameBuffer->Acquired = false;
}
Expand Down Expand Up @@ -116,6 +119,8 @@ static bool ovrFramebuffer_CreateGLES(XrSession session, ovrFramebuffer* frameBu

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_SRGB8_ALPHA8;
Expand All @@ -124,55 +129,45 @@ static bool ovrFramebuffer_CreateGLES(XrSession session, ovrFramebuffer* frameBu
OXR(xrEnumerateSwapchainImages(frameBuffer->ColorSwapChain.Handle, 0, &frameBuffer->TextureSwapChainLength, NULL));
frameBuffer->ColorSwapChainImage = 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 = malloc(frameBuffer->TextureSwapChainLength * sizeof(XrSwapchainImageOpenGLESKHR));

// Populate the swapchain image array.
for (uint32_t i = 0; i < frameBuffer->TextureSwapChainLength; i++) {
((XrSwapchainImageOpenGLESKHR*)frameBuffer->ColorSwapChainImage)[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR;
((XrSwapchainImageOpenGLESKHR*)frameBuffer->ColorSwapChainImage)[i].next = NULL;
((XrSwapchainImageOpenGLESKHR*)frameBuffer->DepthSwapChainImage)[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR;
((XrSwapchainImageOpenGLESKHR*)frameBuffer->DepthSwapChainImage)[i].next = NULL;
}
OXR(xrEnumerateSwapchainImages(
frameBuffer->ColorSwapChain.Handle,
frameBuffer->TextureSwapChainLength,
&frameBuffer->TextureSwapChainLength,
(XrSwapchainImageBaseHeader*)frameBuffer->ColorSwapChainImage));
OXR(xrEnumerateSwapchainImages(
frameBuffer->DepthSwapChain.Handle,
frameBuffer->TextureSwapChainLength,
&frameBuffer->TextureSwapChainLength,
(XrSwapchainImageBaseHeader*)frameBuffer->DepthSwapChainImage));

frameBuffer->GLDepthBuffers = (GLuint*)malloc(frameBuffer->TextureSwapChainLength * sizeof(GLuint));
frameBuffer->GLFrameBuffers = (GLuint*)malloc(frameBuffer->TextureSwapChainLength * sizeof(GLuint));
for (uint32_t i = 0; i < frameBuffer->TextureSwapChainLength; i++) {

// Create color texture.
const GLuint colorTexture = ((XrSwapchainImageOpenGLESKHR*)frameBuffer->ColorSwapChainImage)[i].image;
GLenum colorTextureTarget = multiview ? GL_TEXTURE_2D_ARRAY : 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.
if (multiview) {
GL(glGenTextures(1, &frameBuffer->GLDepthBuffers[i]));
GL(glBindTexture(GL_TEXTURE_2D_ARRAY, frameBuffer->GLDepthBuffers[i]));
GL(glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH24_STENCIL8, width, height, 2));
GL(glBindTexture(GL_TEXTURE_2D_ARRAY, 0));
} else {
GL(glGenRenderbuffers(1, &frameBuffer->GLDepthBuffers[i]));
GL(glBindRenderbuffer(GL_RENDERBUFFER, frameBuffer->GLDepthBuffers[i]));
GL(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height));
GL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
}

const GLuint depthTexture = ((XrSwapchainImageOpenGLESKHR*)frameBuffer->DepthSwapChainImage)[i].image;

// Create the frame buffer.
GL(glGenFramebuffers(1, &frameBuffer->GLFrameBuffers[i]));
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer->GLFrameBuffers[i]));
if (multiview) {
GL(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, frameBuffer->GLDepthBuffers[i], 0, 0, 2));
GL(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, frameBuffer->GLDepthBuffers[i], 0, 0, 2));
GL(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthTexture, 0, 0, 2));
GL(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0, 0, 2));
GL(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorTexture, 0, 0, 2));
} else {
GL(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, frameBuffer->GLDepthBuffers[i]));
GL(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, frameBuffer->GLDepthBuffers[i]));
GL(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0));
GL(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0));
GL(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0));
}
GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
Expand Down Expand Up @@ -218,6 +213,8 @@ static bool ovrFramebuffer_CreateVK(XrSession session, ovrFramebuffer* frameBuff

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 = VK_FORMAT_R8G8B8A8_UNORM;
Expand All @@ -226,16 +223,29 @@ static bool ovrFramebuffer_CreateVK(XrSession session, ovrFramebuffer* frameBuff
OXR(xrEnumerateSwapchainImages(frameBuffer->ColorSwapChain.Handle, 0, &frameBuffer->TextureSwapChainLength, NULL));
frameBuffer->ColorSwapChainImage = malloc(frameBuffer->TextureSwapChainLength * sizeof(XrSwapchainImageVulkanKHR));

// Create the depth swapchain.
swapChainCreateInfo.format = VK_FORMAT_D24_UNORM_S8_UINT;
swapChainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
OXR(xrCreateSwapchain(session, &swapChainCreateInfo, &frameBuffer->DepthSwapChain.Handle));
frameBuffer->DepthSwapChainImage = malloc(frameBuffer->TextureSwapChainLength * sizeof(XrSwapchainImageVulkanKHR));

// Populate the swapchain image array.
for (uint32_t i = 0; i < frameBuffer->TextureSwapChainLength; i++) {
((XrSwapchainImageVulkanKHR*)frameBuffer->ColorSwapChainImage)[i].type = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR;
((XrSwapchainImageVulkanKHR*)frameBuffer->ColorSwapChainImage)[i].next = NULL;
((XrSwapchainImageVulkanKHR*)frameBuffer->DepthSwapChainImage)[i].type = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR;
((XrSwapchainImageVulkanKHR*)frameBuffer->DepthSwapChainImage)[i].next = NULL;
}
OXR(xrEnumerateSwapchainImages(
frameBuffer->ColorSwapChain.Handle,
frameBuffer->TextureSwapChainLength,
&frameBuffer->TextureSwapChainLength,
(XrSwapchainImageBaseHeader*)frameBuffer->ColorSwapChainImage));
OXR(xrEnumerateSwapchainImages(
frameBuffer->DepthSwapChain.Handle,
frameBuffer->TextureSwapChainLength,
&frameBuffer->TextureSwapChainLength,
(XrSwapchainImageBaseHeader*)frameBuffer->DepthSwapChainImage));

frameBuffer->VKColorImages = new VkImageView[frameBuffer->TextureSwapChainLength];
frameBuffer->VKDepthImages = new VkImageView[frameBuffer->TextureSwapChainLength];
Expand All @@ -260,6 +270,14 @@ static bool ovrFramebuffer_CreateVK(XrSession session, ovrFramebuffer* frameBuff
return false;
}

createInfo.image = ((XrSwapchainImageVulkanKHR*)frameBuffer->DepthSwapChainImage)[i].image;
createInfo.format = VK_FORMAT_D24_UNORM_S8_UINT;
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
if (vkCreateImageView(frameBuffer->VKContext->device, &createInfo, nullptr, &frameBuffer->VKDepthImages[i]) != VK_SUCCESS) {
ALOGE("failed to create depth image view!");
return false;
}

// Create the frame buffer.
VkImageView attachments[] = { frameBuffer->VKColorImages[i], frameBuffer->VKDepthImages[i] };
VkFramebufferCreateInfo framebufferInfo{};
Expand Down Expand Up @@ -293,14 +311,14 @@ void ovrFramebuffer_Destroy(ovrFramebuffer* frameBuffer) {
delete[] frameBuffer->VKFrameBuffers;
} else {
#if XR_USE_GRAPHICS_API_OPENGL_ES || XR_USE_GRAPHICS_API_OPENGL
GL(glDeleteRenderbuffers(frameBuffer->TextureSwapChainLength, frameBuffer->GLDepthBuffers));
GL(glDeleteFramebuffers(frameBuffer->TextureSwapChainLength, frameBuffer->GLFrameBuffers));
free(frameBuffer->GLDepthBuffers);
free(frameBuffer->GLFrameBuffers);
#endif
}
OXR(xrDestroySwapchain(frameBuffer->ColorSwapChain.Handle));
OXR(xrDestroySwapchain(frameBuffer->DepthSwapChain.Handle));
free(frameBuffer->ColorSwapChainImage);
free(frameBuffer->DepthSwapChainImage);

ovrFramebuffer_Clear(frameBuffer);
}
Expand All @@ -323,17 +341,8 @@ void ovrFramebuffer_Acquire(ovrFramebuffer* frameBuffer) {
XrSwapchainImageWaitInfo waitInfo;
waitInfo.type = XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO;
waitInfo.next = NULL;
waitInfo.timeout = 1000000; /* timeout in nanoseconds */
waitInfo.timeout = XR_INFINITE_DURATION;
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;

ovrFramebuffer_SetCurrent(frameBuffer);
Expand All @@ -355,6 +364,10 @@ void ovrFramebuffer_Acquire(ovrFramebuffer* frameBuffer) {

void ovrFramebuffer_Release(ovrFramebuffer* frameBuffer) {
if (frameBuffer->Acquired) {
XrSwapchainImageReleaseInfo releaseInfo = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, NULL};
OXR(xrReleaseSwapchainImage(frameBuffer->ColorSwapChain.Handle, &releaseInfo));
frameBuffer->Acquired = false;

// Clear the alpha channel, other way OpenXR would not transfer the framebuffer fully
if (VR_GetPlatformFlag(VR_PLATFORM_RENDERER_VULKAN)) {
//TODO:implement
Expand All @@ -366,10 +379,6 @@ void ovrFramebuffer_Release(ovrFramebuffer* frameBuffer) {
GL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
#endif
}

XrSwapchainImageReleaseInfo releaseInfo = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, NULL};
OXR(xrReleaseSwapchainImage(frameBuffer->ColorSwapChain.Handle, &releaseInfo));
frameBuffer->Acquired = false;
}
}

Expand Down
13 changes: 5 additions & 8 deletions Common/VR/VRRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,11 @@ bool VR_InitFrame( engine_t* engine ) {
projectionCapacityInput,
&projectionCountOutput,
projections));
//
if ((viewState.viewStateFlags & XR_VIEW_STATE_POSITION_VALID_BIT) == 0 ||
(viewState.viewStateFlags & XR_VIEW_STATE_ORIENTATION_VALID_BIT) == 0) {
return false; // There is no valid tracking poses for the views.
}


fov = {};
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
Expand Down Expand Up @@ -486,14 +490,7 @@ void VR_FinishFrame( engine_t* engine ) {
endFrameInfo.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
endFrameInfo.layerCount = engine->appState.LayerCount;
endFrameInfo.layers = layers;

OXR(xrEndFrame(engine->appState.Session, &endFrameInfo));
int instances = engine->appState.Renderer.Multiview ? 1 : ovrMaxNumEyes;
for (int i = 0; i < instances; i++) {
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[instances];
frameBuffer->TextureSwapChainIndex++;
frameBuffer->TextureSwapChainIndex %= frameBuffer->TextureSwapChainLength;
}
}

int VR_GetConfig( VRConfig config ) {
Expand Down
4 changes: 1 addition & 3 deletions GPU/GLES/ShaderManagerGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,6 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, bool useBufferedRenderin
} else {
UpdateVRProjection(gstate.projMatrix, leftEyeMatrix.m, rightEyeMatrix.m);
}
float m4x4[16];
ConvertMatrix4x3To4x4Transposed(m4x4, gstate.viewMatrix);
UpdateVRParams(gstate.projMatrix, m4x4);

FlipProjMatrix(leftEyeMatrix, useBufferedRendering);
FlipProjMatrix(rightEyeMatrix, useBufferedRendering);
Expand Down Expand Up @@ -574,6 +571,7 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, bool useBufferedRenderin
ConvertMatrix4x3To4x4Transposed(leftEyeView, gstate.viewMatrix);
ConvertMatrix4x3To4x4Transposed(rightEyeView, gstate.viewMatrix);
if (!is2D) {
UpdateVRParams(gstate.projMatrix, leftEyeView);
UpdateVRView(leftEyeView, rightEyeView);
}
render_->SetUniformM4x4Stereo("u_view", &u_view, leftEyeView, rightEyeView);
Expand Down
Binary file modified ext/openxr/android/arm64-v8a/libopenxr_meta.so
Binary file not shown.
Binary file modified ext/openxr/android/arm64-v8a/libopenxr_pico.so
Binary file not shown.