Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qopenxrgraphics_opengles.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
6
7#include <QtGui/QOpenGLContext>
8#include <QtQuick/private/qquickrendertarget_p.h>
9#include <rhi/qrhi.h>
10
12
13#ifndef GL_DEPTH_COMPONENT32F
14#define GL_DEPTH_COMPONENT32F 0x8CAC
15#endif
16
17QOpenXRGraphicsOpenGLES::QOpenXRGraphicsOpenGLES()
18{
19#ifdef XR_USE_PLATFORM_ANDROID
20 m_graphicsBinding.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR;
21#endif
22 m_graphicsRequirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR;
23}
24
25bool QOpenXRGraphicsOpenGLES::initialize(const QVector<XrExtensionProperties> &extensions)
26{
27 return hasExtension(extensions, XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME);
28}
29
31{
32 return { XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME };
33}
34
35
37{
38 return reinterpret_cast<const XrBaseInStructure*>(&m_graphicsBinding);
39}
40
41
42bool QOpenXRGraphicsOpenGLES::setupGraphics(const XrInstance &instance, XrSystemId &systemId, const QQuickGraphicsConfiguration &)
43{
44 // Extension function must be loaded by name
45 PFN_xrGetOpenGLESGraphicsRequirementsKHR pfnGetOpenGLESGraphicsRequirementsKHR = nullptr;
46 OpenXRHelpers::checkXrResult(xrGetInstanceProcAddr(instance, "xrGetOpenGLESGraphicsRequirementsKHR",
47 reinterpret_cast<PFN_xrVoidFunction*>(&pfnGetOpenGLESGraphicsRequirementsKHR)),
48 instance);
49
50 if (!pfnGetOpenGLESGraphicsRequirementsKHR) {
51 qWarning("Could not resolve xrGetOpenGLESGraphicsRequirementsKHR; perhaps the OpenXR implementation does not support OpenGL ES?");
52 return false;
53 }
54 OpenXRHelpers::checkXrResult(pfnGetOpenGLESGraphicsRequirementsKHR(instance, systemId, &m_graphicsRequirements),
55 instance);
56 return true;
57}
58
59bool QOpenXRGraphicsOpenGLES::finializeGraphics(QRhi *rhi)
60{
61 const QRhiGles2NativeHandles *openglRhi = static_cast<const QRhiGles2NativeHandles *>(rhi->nativeHandles());
62
63 auto context = openglRhi->context;
64 const XrVersion desiredApiVersion = XR_MAKE_VERSION(context->format().majorVersion(), context->format().minorVersion(), 0);
65 if (m_graphicsRequirements.minApiVersionSupported > desiredApiVersion) {
66 qWarning("Qt Quick 3D XR (Open GL ES): Runtime does not support desired graphics API and/or version");
67 return false;
68 }
69
70#ifdef XR_USE_PLATFORM_ANDROID
71 auto nativeContext = context->nativeInterface<QNativeInterface::QEGLContext>();
72 if (nativeContext) {
73 m_graphicsBinding.display = nativeContext->display();
74 m_graphicsBinding.config = nativeContext->config();
75 m_graphicsBinding.context = nativeContext->nativeContext();
76 }
77#endif
78
79 m_rhi = rhi;
80
81 return true;
82}
83
84
85int64_t QOpenXRGraphicsOpenGLES::colorSwapchainFormat(const QVector<int64_t> &swapchainFormats) const
86{
87 // List of supported color swapchain formats.
88 constexpr int64_t supportedColorSwapchainFormats[] = {
89 GL_SRGB8_ALPHA8_EXT,
90 GL_RGBA8_SNORM
91 };
92
93 auto swapchainFormatIt = std::find_first_of(std::begin(supportedColorSwapchainFormats),
94 std::end(supportedColorSwapchainFormats),
95 swapchainFormats.begin(),
96 swapchainFormats.end());
97 return *swapchainFormatIt;
98}
99
100int64_t QOpenXRGraphicsOpenGLES::depthSwapchainFormat(const QVector<int64_t> &swapchainFormats) const
101{
102 // in order of preference
103 constexpr int64_t supportedDepthSwapchainFormats[] = {
104 GL_DEPTH24_STENCIL8_OES,
106 GL_DEPTH_COMPONENT24_OES,
107 GL_DEPTH_COMPONENT16_OES
108 };
109
110 return *std::find_first_of(std::begin(supportedDepthSwapchainFormats),
111 std::end(supportedDepthSwapchainFormats),
112 swapchainFormats.begin(),
113 swapchainFormats.end());
114}
115
116
118{
119 QVector<XrSwapchainImageBaseHeader*> swapchainImages;
120 QVector<XrSwapchainImageOpenGLESKHR> swapchainImageBuffer(count);
121 for (XrSwapchainImageOpenGLESKHR& image : swapchainImageBuffer) {
122 image.type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR;
123 swapchainImages.push_back(reinterpret_cast<XrSwapchainImageBaseHeader*>(&image));
124 }
125 m_swapchainImageBuffer.insert(swapchain, swapchainImageBuffer);
126 return swapchainImages;
127}
128
129
130QQuickRenderTarget QOpenXRGraphicsOpenGLES::renderTarget(const XrSwapchainSubImage &subImage,
131 const XrSwapchainImageBaseHeader *swapchainImage,
132 quint64 swapchainFormat,
133 int samples,
134 int arraySize,
135 const XrSwapchainImageBaseHeader *depthSwapchainImage,
136 quint64 depthSwapchainFormat) const
137{
138 const uint32_t colorTexture = reinterpret_cast<const XrSwapchainImageOpenGLESKHR*>(swapchainImage)->image;
139
140 switch (swapchainFormat) {
141 case GL_SRGB8_ALPHA8_EXT:
142 swapchainFormat = GL_RGBA8_OES;
143 break;
144 default:
145 break;
146 }
147
148 QQuickRenderTarget::Flags flags;
149 if (samples > 1)
150 flags |= QQuickRenderTarget::Flag::MultisampleResolve;
151
152 const QSize pixelSize(subImage.imageRect.extent.width, subImage.imageRect.extent.height);
153 QQuickRenderTarget rt = QQuickRenderTarget::fromOpenGLTexture(colorTexture,
154 swapchainFormat,
155 pixelSize,
156 samples,
157 arraySize,
158 flags);
159 if (depthSwapchainImage) {
160 QRhiTexture::Format format = QRhiTexture::D24S8;
161 switch (depthSwapchainFormat) {
163 format = QRhiTexture::D32F;
164 break;
165 case GL_DEPTH_COMPONENT24_OES:
166 format = QRhiTexture::D24;
167 break;
168 case GL_DEPTH_COMPONENT16_OES:
169 format = QRhiTexture::D16;
170 break;
171 }
172 GLuint depthImage = reinterpret_cast<const XrSwapchainImageOpenGLESKHR*>(depthSwapchainImage)->image;
173 if (m_depthTexture && (m_depthTexture->format() != format || m_depthTexture->pixelSize() != pixelSize || m_depthTexture->arraySize() != arraySize)) {
174 delete m_depthTexture;
175 m_depthTexture = nullptr;
176 }
177 if (!m_depthTexture) {
178 // this is never multisample, QQuickRt takes care of resolving depth-stencil
179 if (arraySize > 1)
180 m_depthTexture = m_rhi->newTextureArray(format, arraySize, pixelSize, 1, QRhiTexture::RenderTarget);
181 else
182 m_depthTexture = m_rhi->newTexture(format, pixelSize, 1, QRhiTexture::RenderTarget);
183 }
184 m_depthTexture->createFrom({ depthImage, 0 });
185 rt.setDepthTexture(m_depthTexture);
186 }
187 return rt;
188}
189
191{
192 delete m_depthTexture;
193 m_depthTexture = nullptr;
194}
195
196QT_END_NAMESPACE
QQuickRenderTarget renderTarget(const XrSwapchainSubImage &subImage, const XrSwapchainImageBaseHeader *swapchainImage, quint64 swapchainFormat, int samples, int arraySize, const XrSwapchainImageBaseHeader *depthSwapchainImage, quint64 depthSwapchainFormat) const override
const XrBaseInStructure * handle() const override
int64_t depthSwapchainFormat(const QVector< int64_t > &swapchainFormats) const override
bool initialize(const QVector< XrExtensionProperties > &extensions) override
QVector< XrSwapchainImageBaseHeader * > allocateSwapchainImages(int count, XrSwapchain swapchain) override
QVector< const char * > getRequiredExtensions() const override
bool setupGraphics(const XrInstance &instance, XrSystemId &systemId, const QQuickGraphicsConfiguration &quickConfig) override
int64_t colorSwapchainFormat(const QVector< int64_t > &swapchainFormats) const override
bool checkXrResult(XrResult result, XrInstance instance)
Combined button and popup list for selecting options.
#define GL_DEPTH_COMPONENT32F
Definition qopenglext.h:994