diff options
Diffstat (limited to 'src')
11 files changed, 118 insertions, 90 deletions
diff --git a/src/3rdparty/embree/common/sys/platform.h b/src/3rdparty/embree/common/sys/platform.h index 78d8afce..cd08a26c 100644 --- a/src/3rdparty/embree/common/sys/platform.h +++ b/src/3rdparty/embree/common/sys/platform.h @@ -3,6 +3,10 @@ #pragma once +#if defined (__AVX__) +#pragma GCC target("no-sse3") +#endif + #define _CRT_SECURE_NO_WARNINGS #include <cstddef> @@ -384,3 +388,4 @@ namespace embree #undef __AVXI__ #undef __AVX__ #undef __SSE4_2__ +#undef __SSE4_1__ diff --git a/src/3rdparty/embree/patches/0001-Allow-Embree-to-build-with-custom-compiler-flags.patch b/src/3rdparty/embree/patches/0001-Allow-Embree-to-build-with-custom-compiler-flags.patch index 33d1b79f..c463f486 100644 --- a/src/3rdparty/embree/patches/0001-Allow-Embree-to-build-with-custom-compiler-flags.patch +++ b/src/3rdparty/embree/patches/0001-Allow-Embree-to-build-with-custom-compiler-flags.patch @@ -1,4 +1,4 @@ -From bcdf980cd1293e10e3f661e847f41b4e7ec3a4e4 Mon Sep 17 00:00:00 2001 +From e88ce86ad1bcac88804c80c3aeea60a80515703f Mon Sep 17 00:00:00 2001 From: Laszlo Agocs <laszlo.agocs@qt.io> Date: Fri, 3 Jun 2022 10:35:15 +0200 Subject: [PATCH] Allow Embree to build with custom compiler flags @@ -8,14 +8,14 @@ that result in linker errors. Change-Id: I60d8a77c449607762bd5449ead21180744c17dff --- - src/3rdparty/embree/common/sys/platform.h | 8 ++++++++ - 1 file changed, 8 insertions(+) + src/3rdparty/embree/common/sys/platform.h | 9 +++++++++ + 1 file changed, 9 insertions(+) diff --git a/src/3rdparty/embree/common/sys/platform.h b/src/3rdparty/embree/common/sys/platform.h -index 7ba5a19f..78d8afce 100644 +index abc784cee..8965c0626 100644 --- a/src/3rdparty/embree/common/sys/platform.h +++ b/src/3rdparty/embree/common/sys/platform.h -@@ -376,3 +376,11 @@ namespace embree +@@ -380,3 +380,12 @@ namespace embree } } @@ -26,7 +26,8 @@ index 7ba5a19f..78d8afce 100644 +#undef __AVX2__ +#undef __AVXI__ +#undef __AVX__ ++#undef __SSE4_1__ +#undef __SSE4_2__ -- -2.36.1.windows.1 +2.43.0 diff --git a/src/3rdparty/embree/patches/0004-embree-properly-disable-avx-for-GCC14.patch b/src/3rdparty/embree/patches/0004-embree-properly-disable-avx-for-GCC14.patch new file mode 100644 index 00000000..69fd7813 --- /dev/null +++ b/src/3rdparty/embree/patches/0004-embree-properly-disable-avx-for-GCC14.patch @@ -0,0 +1,30 @@ +From ae28850ddb92450e30e1fa6bbace00af0775e907 Mon Sep 17 00:00:00 2001 +From: Samuli Piippo <samuli.piippo@qt.io> +Date: Tue, 22 Oct 2024 10:24:11 +0000 +Subject: [PATCH] embree: properly disable avx for GCC14 + +GCC 14 does not keep avx disabled just by undef'ing __AVX__ . +Add pragma option to do this properly. + +Fixes: QTBUG-130381 +Change-Id: Ia2ae6edc50bfb24b83753fff184469c86daa88dc +--- + src/3rdparty/embree/common/sys/platform.h | 4 +++ + 2 files changed, 30 insertions(+) + create mode 100644 src/3rdparty/embree/patches/0004-embree-properly-disable-avx-for-GCC14.patch + +diff --git a/src/3rdparty/embree/common/sys/platform.h b/src/3rdparty/embree/common/sys/platform.h +index 78d8afce5..5e218fa37 100644 +--- a/src/3rdparty/embree/common/sys/platform.h ++++ b/src/3rdparty/embree/common/sys/platform.h +@@ -3,6 +3,10 @@ + + #pragma once + ++#if defined (__AVX__) ++#pragma GCC target("no-sse3") ++#endif ++ + #define _CRT_SECURE_NO_WARNINGS + + #include <cstddef> diff --git a/src/quick3d/qquick3dscenerenderer.cpp b/src/quick3d/qquick3dscenerenderer.cpp index f414f3be..072bde05 100644 --- a/src/quick3d/qquick3dscenerenderer.cpp +++ b/src/quick3d/qquick3dscenerenderer.cpp @@ -980,7 +980,12 @@ void QQuick3DSceneRenderer::releaseCachedResources() std::optional<QSSGRenderRay> QQuick3DSceneRenderer::getRayFromViewportPos(const QPointF &pos) { - if (!m_layer || !m_layer->renderedCamera) + if (!m_layer) + return std::nullopt; + + QMutexLocker locker(&m_layer->renderedCameraMutex); + + if (!m_layer->renderedCamera) return std::nullopt; const QVector2D viewportSize(m_surfaceSize.width(), m_surfaceSize.height()); diff --git a/src/quick3d/qquick3dtexturedata.cpp b/src/quick3d/qquick3dtexturedata.cpp index 6471909d..cc0a192d 100644 --- a/src/quick3d/qquick3dtexturedata.cpp +++ b/src/quick3d/qquick3dtexturedata.cpp @@ -437,7 +437,7 @@ QSSGRenderGraphObject *QQuick3DTextureData::updateSpatialNode(QSSGRenderGraphObj changed = true; } - if (d->hasTransparency != textureData->hasTransparancy()) { + if (d->hasTransparency != textureData->hasTransparency()) { textureData->setHasTransparency(d->hasTransparency); changed = true; } diff --git a/src/runtimerender/graphobjects/qssgrenderlayer_p.h b/src/runtimerender/graphobjects/qssgrenderlayer_p.h index a3157dda..3c53f2cf 100644 --- a/src/runtimerender/graphobjects/qssgrenderlayer_p.h +++ b/src/runtimerender/graphobjects/qssgrenderlayer_p.h @@ -20,6 +20,7 @@ #include <QtQuick3DRuntimeRender/private/qssglightmapper_p.h> #include <QtCore/qvarlengtharray.h> #include <QtCore/qlist.h> +#include <QMutex> QT_BEGIN_NAMESPACE class QSSGRenderContextInterface; @@ -161,6 +162,7 @@ struct Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderLayer : public QSSGRenderNode QSSGRenderCamera *explicitCamera; // The camera used for rendering (explicitCamera, nullptr or first usable camera). QSSGRenderCamera *renderedCamera; + QMutex renderedCameraMutex; // Tonemapping TonemapMode tonemapMode; diff --git a/src/runtimerender/graphobjects/qssgrendertexturedata.cpp b/src/runtimerender/graphobjects/qssgrendertexturedata.cpp index 227d2101..0fb367cf 100644 --- a/src/runtimerender/graphobjects/qssgrendertexturedata.cpp +++ b/src/runtimerender/graphobjects/qssgrendertexturedata.cpp @@ -30,12 +30,8 @@ const QByteArray &QSSGRenderTextureData::textureData() const void QSSGRenderTextureData::setTextureData(const QByteArray &data) { m_textureData = data; - markDirty(); -} - -QSize QSSGRenderTextureData::size() const -{ - return m_size; + // Bump the version number + ++m_textureDataVersion; } void QSSGRenderTextureData::setSize(const QSize &size) @@ -43,12 +39,6 @@ void QSSGRenderTextureData::setSize(const QSize &size) if (m_size == size) return; m_size = size; - markDirty(); -} - -QSSGRenderTextureFormat QSSGRenderTextureData::format() const -{ - return m_format; } void QSSGRenderTextureData::setFormat(QSSGRenderTextureFormat format) @@ -57,12 +47,6 @@ void QSSGRenderTextureData::setFormat(QSSGRenderTextureFormat format) return; m_format = format; - markDirty(); -} - -bool QSSGRenderTextureData::hasTransparancy() const -{ - return m_hasTransparency; } void QSSGRenderTextureData::setHasTransparency(bool hasTransparency) @@ -71,20 +55,6 @@ void QSSGRenderTextureData::setHasTransparency(bool hasTransparency) return; m_hasTransparency = hasTransparency; - markDirty(); -} - -uint32_t QSSGRenderTextureData::generationId() const -{ - return m_generationId; -} - -void QSSGRenderTextureData::markDirty() -{ - // The generation ID changes every time a property of this texture - // changes so that the buffer manager can compare the generation it - // holds vs the current generation. - m_generationId++; } QT_END_NAMESPACE diff --git a/src/runtimerender/graphobjects/qssgrendertexturedata_p.h b/src/runtimerender/graphobjects/qssgrendertexturedata_p.h index ef6a489e..65d8a07d 100644 --- a/src/runtimerender/graphobjects/qssgrendertexturedata_p.h +++ b/src/runtimerender/graphobjects/qssgrendertexturedata_p.h @@ -35,31 +35,41 @@ public: const QByteArray &textureData() const; void setTextureData(const QByteArray &data); - QSize size() const; + QSize size() const { return m_size; } void setSize(const QSize &size); - QSSGRenderTextureFormat format() const; + QSSGRenderTextureFormat format() const { return m_format; } void setFormat(QSSGRenderTextureFormat format); - bool hasTransparancy() const; + bool hasTransparency() const { return m_hasTransparency; } void setHasTransparency(bool hasTransparency); - uint32_t generationId() const; + // We use a version number to track changes in the texture data. + [[nodiscard]] quint32 version() const { return m_textureDataVersion; } QString debugObjectName; protected: Q_DISABLE_COPY(QSSGRenderTextureData) - void markDirty(); - QByteArray m_textureData; QSize m_size; + quint32 m_textureDataVersion = 0; QSSGRenderTextureFormat m_format = QSSGRenderTextureFormat::Unknown; bool m_hasTransparency = false; - uint32_t m_generationId = 1; }; +// NOTE: We only hash the size, depth, format and hasTransparency here, not the actual data. +// This is because we want to be able to quickly check if a texture has changed, without needing +// to inspect the data content. If only the version changes we'll try to recycle the existing +// texture resource, if the size, depth, format or hasTransparency changes we'll need to create a +// new texture resource (See: QSSGBufferManager::loadTextureData). +inline size_t qHash(const QSSGRenderTextureData &data, size_t seed) noexcept +{ + const auto format = data.format(); + return qHashMulti(seed, data.size(), format.format, data.hasTransparency()); +} + QT_END_NAMESPACE #endif // QSSGRENDERTEXTUREDATA_H diff --git a/src/runtimerender/rendererimpl/qssglayerrenderdata.cpp b/src/runtimerender/rendererimpl/qssglayerrenderdata.cpp index 3f307eca..0894ec0c 100644 --- a/src/runtimerender/rendererimpl/qssglayerrenderdata.cpp +++ b/src/runtimerender/rendererimpl/qssglayerrenderdata.cpp @@ -1795,7 +1795,9 @@ void QSSGLayerRenderData::prepareForRender() } } + layer.renderedCameraMutex.lock(); layer.renderedCamera = camera; + layer.renderedCameraMutex.unlock(); // ResourceLoaders prepareResourceLoaders(); diff --git a/src/runtimerender/resourcemanager/qssgrenderbuffermanager.cpp b/src/runtimerender/resourcemanager/qssgrenderbuffermanager.cpp index 8d2fe95b..ec956e86 100644 --- a/src/runtimerender/resourcemanager/qssgrenderbuffermanager.cpp +++ b/src/runtimerender/resourcemanager/qssgrenderbuffermanager.cpp @@ -232,24 +232,20 @@ QSSGRenderImageTexture QSSGBufferManager::loadRenderImage(const QSSGRenderImage QSSGRenderImageTexture QSSGBufferManager::loadTextureData(QSSGRenderTextureData *data, MipMode inMipMode) { - const CustomImageCacheKey imageKey = { data, inMipMode }; + QSSG_ASSERT(data != nullptr, return {}); + + const CustomImageCacheKey imageKey = { data, data->size(), inMipMode }; auto theImageData = customTextureMap.find(imageKey); if (theImageData == customTextureMap.end()) { - theImageData = customTextureMap.insert(imageKey, ImageData()); - } else if (data->generationId() != theImageData->generationId) { - auto &renderImageTexture = theImageData.value().renderImageTexture; - if (toRhiFormat(data->format()) != renderImageTexture.m_texture->format() - || data->size() != renderImageTexture.m_texture->pixelSize()) { - // release first - releaseTextureData(imageKey); - // reinsert the placeholder since releaseTextureData removed from map - theImageData = customTextureMap.insert(imageKey, ImageData()); - } - theImageData->generationId = data->generationId(); - } else { + theImageData = customTextureMap.insert(imageKey, ImageData{{}, {}, data->version()}); + } else if (data->version() == theImageData->version) { // Return the currently loaded texture theImageData.value().usageCounts[currentLayer]++; return theImageData.value().renderImageTexture; + } else { + // Optimization: If only the version number has changed, we can attempt to reuse the texture. + // Just update the version number and let setRhiTexture handle the rest. + theImageData->version = data->version(); } // Load the texture @@ -261,10 +257,8 @@ QSSGRenderImageTexture QSSGBufferManager::loadTextureData(QSSGRenderTextureData bool wasTextureCreated = false; if (setRhiTexture(theImageData.value().renderImageTexture, theLoadedTexture.data(), inMipMode, {}, data->debugObjectName, &wasTextureCreated)) { - if (wasTextureCreated) { - theImageData.value().generationId = data->generationId(); + if (wasTextureCreated) increaseMemoryStat(theImageData.value().renderImageTexture.m_texture); - } } else { theImageData.value() = ImageData(); } @@ -917,6 +911,15 @@ bool QSSGBufferManager::setRhiTexture(QSSGRenderImageTexture &texture, int mipmapCount = texFileData.isValid() ? texFileData.numLevels() : 1; bool generateMipmaps = false; + if (size.isEmpty()) { + qWarning() << "Could not use 0 sized texture"; + return false; + } else if (!rhi->isTextureFormatSupported(rhiFormat)) { + qWarning() << "Unsupported texture format"; + return false; + } + + if (wasTextureCreated) *wasTextureCreated = false; @@ -1036,14 +1039,6 @@ bool QSSGBufferManager::setRhiTexture(QSSGRenderImageTexture &texture, const auto validTexSize = size.width() <= maxTextureSize && size.height() <= maxTextureSize; QSSG_ASSERT_X(validTexSize, qPrintable(textureSizeWarning(size, maxTextureSize)), return false); - if (textureUploads.isEmpty() || size.isEmpty() || rhiFormat == QRhiTexture::UnknownFormat) { - qWarning() << "Could not load texture"; - return false; - } else if (!rhi->isTextureFormatSupported(rhiFormat)) { - qWarning() << "Unsupported texture format"; - return false; - } - QSSG_ASSERT(texture.m_texture != nullptr, return false); if (checkTransp) @@ -1993,4 +1988,12 @@ void QSSGBufferManager::decreaseMemoryStat(QSSGRenderMesh *mesh) m_contextInterface->rhiContext()->stats().meshDataSizeChanges(stats.meshDataSize); } +size_t qHash(const QSSGBufferManager::CustomImageCacheKey &k, size_t seed) noexcept +{ + // NOTE: The data pointer should never be null, as null data pointers shouldn't be inserted into + // the cached (make sure to check that before inserting!!!) + using MipMap_t = std::underlying_type_t<QSSGBufferManager::MipMode>; + return qHash(*k.data, seed) ^ MipMap_t(k.mipMode); +} + QT_END_NAMESPACE diff --git a/src/runtimerender/resourcemanager/qssgrenderbuffermanager_p.h b/src/runtimerender/resourcemanager/qssgrenderbuffermanager_p.h index aee89b9e..cda950f4 100644 --- a/src/runtimerender/resourcemanager/qssgrenderbuffermanager_p.h +++ b/src/runtimerender/resourcemanager/qssgrenderbuffermanager_p.h @@ -26,6 +26,8 @@ #include <QtQuick3DUtils/private/qquick3dprofiler_p.h> #include <QtCore/QMutex> +#include <QtCore/qhash.h> +#include <QtCore/qsize.h> QT_BEGIN_NAMESPACE @@ -77,6 +79,18 @@ class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGBufferManager { Q_DISABLE_COPY(QSSGBufferManager) public: + enum MipMode : quint8 { + MipModeFollowRenderImage, + MipModeEnable, + MipModeDisable, + MipModeBsdf + }; + + enum LoadRenderImageFlag { + LoadWithFlippedY = 0x01 + }; + Q_DECLARE_FLAGS(LoadRenderImageFlags, LoadRenderImageFlag) + struct ImageCacheKey { QSSGRenderPath path; int mipMode; @@ -85,13 +99,14 @@ public: struct CustomImageCacheKey { QSSGRenderTextureData *data; - int mipMode; + QSize pixelSize; + MipMode mipMode; }; struct ImageData { QSSGRenderImageTexture renderImageTexture; QHash<QSSGRenderLayer*, uint32_t> usageCounts; - uint32_t generationId = 0; + uint32_t version = 0; }; struct MeshData { @@ -106,18 +121,6 @@ public: quint64 imageDataSize = 0; }; - enum MipMode { - MipModeFollowRenderImage, - MipModeEnable, - MipModeDisable, - MipModeBsdf - }; - - enum LoadRenderImageFlag { - LoadWithFlippedY = 0x01 - }; - Q_DECLARE_FLAGS(LoadRenderImageFlags, LoadRenderImageFlag) - QSSGBufferManager(); ~QSSGBufferManager(); @@ -234,14 +237,11 @@ inline bool operator==(const QSSGBufferManager::ImageCacheKey &a, const QSSGBuff return a.path == b.path && a.mipMode == b.mipMode && a.type == b.type; } -inline size_t qHash(const QSSGBufferManager::CustomImageCacheKey &k, size_t seed) Q_DECL_NOTHROW -{ - return qHash(k.data, seed) ^ k.mipMode; -} +size_t qHash(const QSSGBufferManager::CustomImageCacheKey &k, size_t seed) noexcept; inline bool operator==(const QSSGBufferManager::CustomImageCacheKey &a, const QSSGBufferManager::CustomImageCacheKey &b) Q_DECL_NOTHROW { - return a.data == b.data && a.mipMode == b.mipMode; + return a.data == b.data && a.pixelSize == b.pixelSize && a.mipMode == b.mipMode; } QT_END_NAMESPACE |
