mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 01:29:41 +01:00
OpenXR - Multiview refactor to make it optional
This commit is contained in:
1 parent
94968c3075
commit
462174f548
6 files changed
+90
-100
No files matched your search
+75
-76
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user