diff options
author | Qt Forward Merge Bot <[email protected]> | 2019-09-28 01:00:51 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <[email protected]> | 2019-09-28 01:01:03 +0200 |
commit | fbda189e081e6c7abf82334c0ac71b16ec2c37dd (patch) | |
tree | 92bdcfeb6c32de9c90ea126714907afa18ef44f1 /src/gui | |
parent | d12bf4eb8353f33499cbec4e105431668dbe8c88 (diff) | |
parent | e8d7df4cb2586ba5098fb4f476807ba7992d9cea (diff) |
Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/opengl/qopenglprogrambinarycache.cpp | 10 | ||||
-rw-r--r-- | src/gui/opengl/qopenglprogrambinarycache_p.h | 1 | ||||
-rw-r--r-- | src/gui/opengl/qopenglshaderprogram.cpp | 7 | ||||
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 22 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p_p.h | 32 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 17 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 15 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal_p_p.h | 5 |
8 files changed, 80 insertions, 29 deletions
diff --git a/src/gui/opengl/qopenglprogrambinarycache.cpp b/src/gui/opengl/qopenglprogrambinarycache.cpp index 54160e1240e..14954714572 100644 --- a/src/gui/opengl/qopenglprogrambinarycache.cpp +++ b/src/gui/opengl/qopenglprogrambinarycache.cpp @@ -45,6 +45,7 @@ #include <QDir> #include <QSaveFile> #include <QLoggingCategory> +#include <QCryptographicHash> #ifdef Q_OS_UNIX #include <sys/mman.h> @@ -94,6 +95,15 @@ GLEnvInfo::GLEnvInfo() glversion = QByteArray(version); } +QByteArray QOpenGLProgramBinaryCache::ProgramDesc::cacheKey() const +{ + QCryptographicHash keyBuilder(QCryptographicHash::Sha1); + for (const QOpenGLProgramBinaryCache::ShaderDesc &shader : shaders) + keyBuilder.addData(shader.source); + + return keyBuilder.result().toHex(); +} + static inline bool qt_ensureWritableDir(const QString &name) { QDir::root().mkpath(name); diff --git a/src/gui/opengl/qopenglprogrambinarycache_p.h b/src/gui/opengl/qopenglprogrambinarycache_p.h index e181a6ab814..fb01e61872b 100644 --- a/src/gui/opengl/qopenglprogrambinarycache_p.h +++ b/src/gui/opengl/qopenglprogrambinarycache_p.h @@ -71,6 +71,7 @@ public: }; struct ProgramDesc { QVector<ShaderDesc> shaders; + QByteArray cacheKey() const; }; QOpenGLProgramBinaryCache(); diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index 3c7bd4f90d3..153a5dd9ee5 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -47,7 +47,6 @@ #include <QtCore/qvarlengtharray.h> #include <QtCore/qvector.h> #include <QtCore/qloggingcategory.h> -#include <QtCore/qcryptographichash.h> #include <QtCore/qcoreapplication.h> #include <QtGui/qtransform.h> #include <QtGui/QColor> @@ -3819,11 +3818,7 @@ bool QOpenGLShaderProgramPrivate::linkBinary() Q_Q(QOpenGLShaderProgram); - QCryptographicHash keyBuilder(QCryptographicHash::Sha1); - for (const QOpenGLProgramBinaryCache::ShaderDesc &shader : qAsConst(binaryProgram.shaders)) - keyBuilder.addData(shader.source); - - const QByteArray cacheKey = keyBuilder.result().toHex(); + const QByteArray cacheKey = binaryProgram.cacheKey(); if (DBG_SHADER_CACHE().isEnabled(QtDebugMsg)) qCDebug(DBG_SHADER_CACHE, "program with %d shaders, cache key %s", binaryProgram.shaders.count(), cacheKey.constData()); diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 858be0159b3..ee4caa47a04 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -707,8 +707,8 @@ QDebug operator<<(QDebug dbg, const QRhiDepthStencilClearValue &v) Used with QRhiCommandBuffer::setViewport(). - \note QRhi assumes OpenGL-style viewport coordinates, meaning x and y are - bottom-left. + QRhi assumes OpenGL-style viewport coordinates, meaning x and y are + bottom-left. Negative width or height are not allowed. Typical usage is like the following: @@ -737,7 +737,9 @@ QDebug operator<<(QDebug dbg, const QRhiDepthStencilClearValue &v) Constructs a viewport description with the rectangle specified by \a x, \a y, \a w, \a h and the depth range \a minDepth and \a maxDepth. - \note x and y are assumed to be the bottom-left position. + \note \a x and \a y are assumed to be the bottom-left position. \a w and \a + h should not be negative, the viewport will be ignored by + QRhiCommandBuffer::setViewport() otherwise. \sa QRhi::clipSpaceCorrMatrix() */ @@ -810,8 +812,12 @@ QDebug operator<<(QDebug dbg, const QRhiViewport &v) only possible with a QRhiGraphicsPipeline that has QRhiGraphicsPipeline::UsesScissor set. - \note QRhi assumes OpenGL-style scissor coordinates, meaning x and y are - bottom-left. + QRhi assumes OpenGL-style scissor coordinates, meaning x and y are + bottom-left. Negative width or height are not allowed. However, apart from + that, the flexible OpenGL semantics apply: negative x and y, partially out + of bounds rectangles, etc. will be handled gracefully, clamping as + appropriate. Therefore, any rendering logic targeting OpenGL can feed + scissor rectangles into QRhiScissor as-is, without any adaptation. \sa QRhiCommandBuffer::setScissor(), QRhiViewport */ @@ -826,7 +832,11 @@ QDebug operator<<(QDebug dbg, const QRhiViewport &v) Constructs a scissor with the rectangle specified by \a x, \a y, \a w, and \a h. - \note x and y are assumed to be the bottom-left position. + \note \a x and \a y are assumed to be the bottom-left position. Negative \a w + or \a h are not allowed, such scissor rectangles will be ignored by + QRhiCommandBuffer. Other than that, the flexible OpenGL semantics apply: + negative x and y, partially out of bounds rectangles, etc. will be handled + gracefully, clamping as appropriate. */ QRhiScissor::QRhiScissor(int x, int y, int w, int h) : m_rect { { x, y, w, h } } diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h index 63f27b6de42..be2808549c9 100644 --- a/src/gui/rhi/qrhi_p_p.h +++ b/src/gui/rhi/qrhi_p_p.h @@ -233,27 +233,37 @@ bool qrhi_toTopLeftRenderTargetRect(const QSize &outputSize, const std::array<T, T *x, T *y, T *w, T *h) { // x,y are bottom-left in QRhiScissor and QRhiViewport but top-left in - // Vulkan/Metal/D3D. We also need proper clamping since some - // validation/debug layers are allergic to out of bounds scissor or - // viewport rects. + // Vulkan/Metal/D3D. Our input is an OpenGL-style scissor rect where both + // negative x or y, and partly or completely out of bounds rects are + // allowed. The only thing the input here cannot have is a negative width + // or height. We must handle all other input gracefully, clamping to a zero + // width or height rect in the worst case, and ensuring the resulting rect + // is inside the rendertarget's bounds because some APIs' validation/debug + // layers are allergic to out of bounds scissor or viewport rects. const T outputWidth = outputSize.width(); const T outputHeight = outputSize.height(); const T inputWidth = r[2]; const T inputHeight = r[3]; - *x = qMax<T>(0, r[0]); - *y = qMax<T>(0, outputHeight - (r[1] + inputHeight)); - *w = inputWidth; - *h = inputHeight; - - if (*x >= outputWidth || *y >= outputHeight) + if (inputWidth < 0 || inputHeight < 0) return false; + *x = r[0]; + *y = outputHeight - (r[1] + inputHeight); + + const T widthOffset = *x < 0 ? -*x : 0; + const T heightOffset = *y < 0 ? -*y : 0; + + *x = qBound<T>(0, *x, outputWidth - 1); + *y = qBound<T>(0, *y, outputHeight - 1); + *w = qMax<T>(0, inputWidth - widthOffset); + *h = qMax<T>(0, inputHeight - heightOffset); + if (*x + *w > outputWidth) - *w = outputWidth - *x; + *w = qMax<T>(0, outputWidth - *x - 1); if (*y + *h > outputHeight) - *h = outputHeight - *y; + *h = qMax<T>(0, outputHeight - *y - 1); return true; } diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 2d51d892e32..cc5d41ea46b 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -1004,8 +1004,12 @@ void QRhiGles2::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) QGles2CommandBuffer::Command cmd; cmd.cmd = QGles2CommandBuffer::Command::Viewport; const std::array<float, 4> r = viewport.viewport(); - cmd.args.viewport.x = qMax(0.0f, r[0]); - cmd.args.viewport.y = qMax(0.0f, r[1]); + // A negative width or height is an error. A negative x or y is not. + if (r[2] < 0.0f || r[3] < 0.0f) + return; + + cmd.args.viewport.x = r[0]; + cmd.args.viewport.y = r[1]; cmd.args.viewport.w = r[2]; cmd.args.viewport.h = r[3]; cmd.args.viewport.d0 = viewport.minDepth(); @@ -1021,8 +1025,12 @@ void QRhiGles2::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) QGles2CommandBuffer::Command cmd; cmd.cmd = QGles2CommandBuffer::Command::Scissor; const std::array<int, 4> r = scissor.scissor(); - cmd.args.scissor.x = qMax(0, r[0]); - cmd.args.scissor.y = qMax(0, r[1]); + // A negative width or height is an error. A negative x or y is not. + if (r[2] < 0 || r[3] < 0) + return; + + cmd.args.scissor.x = r[0]; + cmd.args.scissor.y = r[1]; cmd.args.scissor.w = r[2]; cmd.args.scissor.h = r[3]; cbD->commands.append(cmd); @@ -2250,6 +2258,7 @@ void QRhiGles2::executeBindGraphicsPipeline(QRhiGraphicsPipeline *ps) } } else { f->glDisable(GL_BLEND); + f->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } if (psD->m_depthTest) f->glEnable(GL_DEPTH_TEST); diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index bfd6944cdb6..d4043f00a5f 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -838,8 +838,15 @@ void QRhiMetal::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline [cbD->d->currentRenderPassEncoder setRenderPipelineState: psD->d->ps]; [cbD->d->currentRenderPassEncoder setDepthStencilState: psD->d->ds]; - [cbD->d->currentRenderPassEncoder setCullMode: psD->d->cullMode]; - [cbD->d->currentRenderPassEncoder setFrontFacingWinding: psD->d->winding]; + + if (cbD->currentCullMode == -1 || psD->d->cullMode != uint(cbD->currentCullMode)) { + [cbD->d->currentRenderPassEncoder setCullMode: psD->d->cullMode]; + cbD->currentCullMode = int(psD->d->cullMode); + } + if (cbD->currentFrontFaceWinding == -1 || psD->d->winding != uint(cbD->currentFrontFaceWinding)) { + [cbD->d->currentRenderPassEncoder setFrontFacingWinding: psD->d->winding]; + cbD->currentFrontFaceWinding = int(psD->d->winding); + } } psD->lastActiveFrameSlot = currentFrameSlot; @@ -3450,6 +3457,10 @@ void QMetalCommandBuffer::resetPerPassCachedState() currentSrbGeneration = 0; currentResSlot = -1; currentIndexBuffer = nullptr; + currentIndexOffset = 0; + currentIndexFormat = QRhiCommandBuffer::IndexUInt16; + currentCullMode = -1; + currentFrontFaceWinding = -1; d->currentFirstVertexBinding = -1; d->currentVertexInputsBuffers.clear(); diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h index a08f56072a0..7fd7aba923e 100644 --- a/src/gui/rhi/qrhimetal_p_p.h +++ b/src/gui/rhi/qrhimetal_p_p.h @@ -271,8 +271,11 @@ struct QMetalCommandBuffer : public QRhiCommandBuffer ComputePass }; + // per-pass (render or compute command encoder) persistent state PassType recordingPass; QRhiRenderTarget *currentTarget; + + // per-pass (render or compute command encoder) volatile (cached) state QRhiGraphicsPipeline *currentGraphicsPipeline; QRhiComputePipeline *currentComputePipeline; uint currentPipelineGeneration; @@ -283,6 +286,8 @@ struct QMetalCommandBuffer : public QRhiCommandBuffer QRhiBuffer *currentIndexBuffer; quint32 currentIndexOffset; QRhiCommandBuffer::IndexFormat currentIndexFormat; + int currentCullMode; + int currentFrontFaceWinding; const QRhiNativeHandles *nativeHandles(); void resetState(); |