diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-09-30 15:23:32 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-09-30 20:07:53 +0200 |
commit | 9e59024bf80124dbf301e8b3dca3dc4548fee428 (patch) | |
tree | fb3507ea76a57d1e72143821e565a6f6ae2e496e | |
parent | 7000b66f7e85e58d267b71322fbb3d5a0fc356b8 (diff) |
rhi: Speed up buffer and texture tracking
Task-number: QTBUG-78862
Change-Id: If278bd55530081cbbdbab8dd6e14d86e28da558e
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 10 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p_p.h | 16 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 10 | ||||
-rw-r--r-- | src/gui/rhi/qrhivulkan.cpp | 26 |
4 files changed, 30 insertions, 32 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index fa0c5fadc0..08bafebdec 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -5513,7 +5513,7 @@ static inline QRhiPassResourceTracker::BufferStage earlierStage(QRhiPassResource void QRhiPassResourceTracker::registerBuffer(QRhiBuffer *buf, int slot, BufferAccess *access, BufferStage *stage, const UsageState &state) { - auto it = std::find_if(m_buffers.begin(), m_buffers.end(), [buf](const Buffer &b) { return b.buf == buf; }); + auto it = m_buffers.find(buf); if (it != m_buffers.end()) { if (it->access != *access) { const QByteArray name = buf->name(); @@ -5529,12 +5529,11 @@ void QRhiPassResourceTracker::registerBuffer(QRhiBuffer *buf, int slot, BufferAc } Buffer b; - b.buf = buf; b.slot = slot; b.access = *access; b.stage = *stage; b.stateAtPassBegin = state; // first use -> initial state - m_buffers.append(b); + m_buffers.insert(buf, b); } static inline QRhiPassResourceTracker::TextureStage earlierStage(QRhiPassResourceTracker::TextureStage a, @@ -5553,7 +5552,7 @@ static inline bool isImageLoadStore(QRhiPassResourceTracker::TextureAccess acces void QRhiPassResourceTracker::registerTexture(QRhiTexture *tex, TextureAccess *access, TextureStage *stage, const UsageState &state) { - auto it = std::find_if(m_textures.begin(), m_textures.end(), [tex](const Texture &t) { return t.tex == tex; }); + auto it = m_textures.find(tex); if (it != m_textures.end()) { if (it->access != *access) { // Different subresources of a texture may be used for both load @@ -5577,11 +5576,10 @@ void QRhiPassResourceTracker::registerTexture(QRhiTexture *tex, TextureAccess *a } Texture t; - t.tex = tex; t.access = *access; t.stage = *stage; t.stateAtPassBegin = state; // first use -> initial state - m_textures.append(t); + m_textures.insert(tex, t); } QRhiPassResourceTracker::BufferStage QRhiPassResourceTracker::toPassTrackerBufferStage(QRhiShaderResourceBinding::StageFlags stages) diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h index 2cb96ebaf5..822da528f1 100644 --- a/src/gui/rhi/qrhi_p_p.h +++ b/src/gui/rhi/qrhi_p_p.h @@ -503,28 +503,32 @@ public: const UsageState &state); struct Buffer { - QRhiBuffer *buf; int slot; BufferAccess access; BufferStage stage; UsageState stateAtPassBegin; }; - const QVector<Buffer> *buffers() const { return &m_buffers; } + + using BufferIterator = QHash<QRhiBuffer *, Buffer>::const_iterator; + BufferIterator cbeginBuffers() const { return m_buffers.cbegin(); } + BufferIterator cendBuffers() const { return m_buffers.cend(); } struct Texture { - QRhiTexture *tex; TextureAccess access; TextureStage stage; UsageState stateAtPassBegin; }; - const QVector<Texture> *textures() const { return &m_textures; } + + using TextureIterator = QHash<QRhiTexture *, Texture>::const_iterator; + TextureIterator cbeginTextures() const { return m_textures.cbegin(); } + TextureIterator cendTextures() const { return m_textures.cend(); } static BufferStage toPassTrackerBufferStage(QRhiShaderResourceBinding::StageFlags stages); static TextureStage toPassTrackerTextureStage(QRhiShaderResourceBinding::StageFlags stages); private: - QVector<Buffer> m_buffers; - QVector<Texture> m_textures; + QHash<QRhiBuffer *, Buffer> m_buffers; + QHash<QRhiTexture *, Texture> m_textures; }; Q_DECLARE_TYPEINFO(QRhiPassResourceTracker::Buffer, Q_MOVABLE_TYPE); diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 5afba774a9..190385d5de 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -2186,7 +2186,6 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) { GLbitfield barriers = 0; QRhiPassResourceTracker &tracker(cbD->passResTrackers[cmd.args.barriersForPass.trackerIndex]); - const QVector<QRhiPassResourceTracker::Buffer> *buffers = tracker.buffers(); // we only care about after-write, not any other accesses, and // cannot tell if something was written in a shader several passes // ago: now the previously written resource may be used with an @@ -2194,17 +2193,16 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) // barrier in theory. Hence setting all barrier bits whenever // something previously written is used for the first time in a // subsequent pass. - for (const QRhiPassResourceTracker::Buffer &b : *buffers) { - QGles2Buffer::Access accessBeforePass = QGles2Buffer::Access(b.stateAtPassBegin.access); + for (auto it = tracker.cbeginBuffers(), itEnd = tracker.cendBuffers(); it != itEnd; ++it) { + QGles2Buffer::Access accessBeforePass = QGles2Buffer::Access(it->stateAtPassBegin.access); if (accessBeforePass == QGles2Buffer::AccessStorageWrite || accessBeforePass == QGles2Buffer::AccessStorageReadWrite) { barriers |= GL_ALL_BARRIER_BITS; } } - const QVector<QRhiPassResourceTracker::Texture> *textures = tracker.textures(); - for (const QRhiPassResourceTracker::Texture &t : *textures) { - QGles2Texture::Access accessBeforePass = QGles2Texture::Access(t.stateAtPassBegin.access); + for (auto it = tracker.cbeginTextures(), itEnd = tracker.cendTextures(); it != itEnd; ++it) { + QGles2Texture::Access accessBeforePass = QGles2Texture::Access(it->stateAtPassBegin.access); if (accessBeforePass == QGles2Texture::AccessStorageWrite || accessBeforePass == QGles2Texture::AccessStorageReadWrite) { diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index b7fc50d259..7e2e914af3 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -3556,12 +3556,11 @@ void QRhiVulkan::recordTransitionPassResources(QVkCommandBuffer *cbD, const QRhi if (tracker.isEmpty()) return; - const QVector<QRhiPassResourceTracker::Buffer> *buffers = tracker.buffers(); - for (const QRhiPassResourceTracker::Buffer &b : *buffers) { - QVkBuffer *bufD = QRHI_RES(QVkBuffer, b.buf); - VkAccessFlags access = toVkAccess(b.access); - VkPipelineStageFlags stage = toVkPipelineStage(b.stage); - QVkBuffer::UsageState s = toVkBufferUsageState(b.stateAtPassBegin); + for (auto it = tracker.cbeginBuffers(), itEnd = tracker.cendBuffers(); it != itEnd; ++it) { + QVkBuffer *bufD = QRHI_RES(QVkBuffer, it.key()); + VkAccessFlags access = toVkAccess(it->access); + VkPipelineStageFlags stage = toVkPipelineStage(it->stage); + QVkBuffer::UsageState s = toVkBufferUsageState(it->stateAtPassBegin); if (!s.stage) continue; if (s.access == access && s.stage == stage) { @@ -3575,7 +3574,7 @@ void QRhiVulkan::recordTransitionPassResources(QVkCommandBuffer *cbD, const QRhi bufMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; bufMemBarrier.srcAccessMask = s.access; bufMemBarrier.dstAccessMask = access; - bufMemBarrier.buffer = bufD->buffers[b.slot]; + bufMemBarrier.buffer = bufD->buffers[it->slot]; bufMemBarrier.size = VK_WHOLE_SIZE; df->vkCmdPipelineBarrier(cbD->cb, s.stage, stage, 0, 0, nullptr, @@ -3583,13 +3582,12 @@ void QRhiVulkan::recordTransitionPassResources(QVkCommandBuffer *cbD, const QRhi 0, nullptr); } - const QVector<QRhiPassResourceTracker::Texture> *textures = tracker.textures(); - for (const QRhiPassResourceTracker::Texture &t : *textures) { - QVkTexture *texD = QRHI_RES(QVkTexture, t.tex); - VkImageLayout layout = toVkLayout(t.access); - VkAccessFlags access = toVkAccess(t.access); - VkPipelineStageFlags stage = toVkPipelineStage(t.stage); - QVkTexture::UsageState s = toVkTextureUsageState(t.stateAtPassBegin); + for (auto it = tracker.cbeginTextures(), itEnd = tracker.cendTextures(); it != itEnd; ++it) { + QVkTexture *texD = QRHI_RES(QVkTexture, it.key()); + VkImageLayout layout = toVkLayout(it->access); + VkAccessFlags access = toVkAccess(it->access); + VkPipelineStageFlags stage = toVkPipelineStage(it->stage); + QVkTexture::UsageState s = toVkTextureUsageState(it->stateAtPassBegin); if (s.access == access && s.stage == stage && s.layout == layout) { if (!accessIsWrite(access)) continue; |