summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorQt Forward Merge Bot <[email protected]>2019-09-28 01:00:51 +0200
committerQt Forward Merge Bot <[email protected]>2019-09-28 01:01:03 +0200
commitfbda189e081e6c7abf82334c0ac71b16ec2c37dd (patch)
tree92bdcfeb6c32de9c90ea126714907afa18ef44f1 /src/gui
parentd12bf4eb8353f33499cbec4e105431668dbe8c88 (diff)
parente8d7df4cb2586ba5098fb4f476807ba7992d9cea (diff)
Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/opengl/qopenglprogrambinarycache.cpp10
-rw-r--r--src/gui/opengl/qopenglprogrambinarycache_p.h1
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp7
-rw-r--r--src/gui/rhi/qrhi.cpp22
-rw-r--r--src/gui/rhi/qrhi_p_p.h32
-rw-r--r--src/gui/rhi/qrhigles2.cpp17
-rw-r--r--src/gui/rhi/qrhimetal.mm15
-rw-r--r--src/gui/rhi/qrhimetal_p_p.h5
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();