summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi/qrhigles2_p_p.h
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2020-03-13 18:19:19 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2020-03-20 09:43:04 +0100
commit6c5b42b678b8e54cbb58f75d5d8abb50eff46dd9 (patch)
tree34afb5831229d26bf9f5da1a8bcdf1b900fd08f9 /src/gui/rhi/qrhigles2_p_p.h
parente7cff5bca7aefaea63e80598babf6bd7917aa1c3 (diff)
rhi: gl: Reduce state changes
...between setGraphicsPipeline() calls with different QRhiGraphicsPipeline instances within the same pass. Also adds similar logic for the GL_ARRAY_BUFFER (vertex buffers) as that is a hotspot as well. This is not intended to be a 100% avoiding any redundant call solution, but rather to take care of the most common hotspots, so that bad OpenGL implementations with a larger API call overhead will not cause us to regress compared to the direct OpenGL rendering path in Quick and Quick3D. What we have here reduces the number of GL calls in the view3d example by ~200 within one frame, which is a pretty good start. Task-number: QTBUG-78603 Change-Id: I6aeab9c1c43b148ea6ef05d0284990a996c7ba28 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/gui/rhi/qrhigles2_p_p.h')
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h87
1 files changed, 86 insertions, 1 deletions
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index 8b7d01532a..ac7b384cb6 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -522,6 +522,45 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
QRhiShaderResourceBindings *currentComputeSrb;
uint currentSrbGeneration;
+ struct GraphicsPassState {
+ bool valid = false;
+ bool scissor;
+ bool cullFace;
+ GLenum cullMode;
+ GLenum frontFace;
+ bool blendEnabled;
+ struct ColorMask { bool r, g, b, a; } colorMask;
+ struct Blend {
+ GLenum srcColor;
+ GLenum dstColor;
+ GLenum srcAlpha;
+ GLenum dstAlpha;
+ GLenum opColor;
+ GLenum opAlpha;
+ } blend;
+ bool depthTest;
+ bool depthWrite;
+ GLenum depthFunc;
+ bool stencilTest;
+ GLuint stencilReadMask;
+ GLuint stencilWriteMask;
+ struct StencilFace {
+ GLenum func;
+ GLenum failOp;
+ GLenum zfailOp;
+ GLenum zpassOp;
+ } stencil[2]; // front, back
+ bool polyOffsetFill;
+ float polyOffsetFactor;
+ float polyOffsetUnits;
+ float lineWidth;
+ void reset() { valid = false; }
+ struct {
+ // not part of QRhiGraphicsPipeline but used by setGraphicsPipeline()
+ GLint stencilRef = 0;
+ } dynamic;
+ } graphicsPassState;
+
struct ComputePassState {
enum Access {
Read = 0x01,
@@ -566,11 +605,57 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
currentGraphicsSrb = nullptr;
currentComputeSrb = nullptr;
currentSrbGeneration = 0;
+ graphicsPassState.reset();
+ computePassState.reset();
}
};
Q_DECLARE_TYPEINFO(QGles2CommandBuffer::Command, Q_MOVABLE_TYPE);
+inline bool operator==(const QGles2CommandBuffer::GraphicsPassState::StencilFace &a,
+ const QGles2CommandBuffer::GraphicsPassState::StencilFace &b)
+{
+ return a.func == b.func
+ && a.failOp == b.failOp
+ && a.zfailOp == b.zfailOp
+ && a.zpassOp == b.zpassOp;
+}
+
+inline bool operator!=(const QGles2CommandBuffer::GraphicsPassState::StencilFace &a,
+ const QGles2CommandBuffer::GraphicsPassState::StencilFace &b)
+{
+ return !(a == b);
+}
+
+inline bool operator==(const QGles2CommandBuffer::GraphicsPassState::ColorMask &a,
+ const QGles2CommandBuffer::GraphicsPassState::ColorMask &b)
+{
+ return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
+}
+
+inline bool operator!=(const QGles2CommandBuffer::GraphicsPassState::ColorMask &a,
+ const QGles2CommandBuffer::GraphicsPassState::ColorMask &b)
+{
+ return !(a == b);
+}
+
+inline bool operator==(const QGles2CommandBuffer::GraphicsPassState::Blend &a,
+ const QGles2CommandBuffer::GraphicsPassState::Blend &b)
+{
+ return a.srcColor == b.srcColor
+ && a.dstColor == b.dstColor
+ && a.srcAlpha == b.srcAlpha
+ && a.dstAlpha == b.dstAlpha
+ && a.opColor == b.opColor
+ && a.opAlpha == b.opAlpha;
+}
+
+inline bool operator!=(const QGles2CommandBuffer::GraphicsPassState::Blend &a,
+ const QGles2CommandBuffer::GraphicsPassState::Blend &b)
+{
+ return !(a == b);
+}
+
struct QGles2SwapChain : public QRhiSwapChain
{
QGles2SwapChain(QRhiImplementation *rhi);
@@ -709,7 +794,7 @@ public:
QRhiPassResourceTracker::TextureAccess access,
QRhiPassResourceTracker::TextureStage stage);
void executeCommandBuffer(QRhiCommandBuffer *cb);
- void executeBindGraphicsPipeline(QRhiGraphicsPipeline *ps);
+ void executeBindGraphicsPipeline(QGles2CommandBuffer *cbD, QGles2GraphicsPipeline *psD);
void bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiComputePipeline *maybeComputePs,
QRhiShaderResourceBindings *srb,
const uint *dynOfsPairs, int dynOfsCount);