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