diff options
Diffstat (limited to 'src/gui/rhi')
-rw-r--r-- | src/gui/rhi/cs_tdr_p.h | 2 | ||||
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 10 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p_p.h | 43 | ||||
-rw-r--r-- | src/gui/rhi/qrhid3d11.cpp | 28 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 61 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 251 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal_p_p.h | 2 | ||||
-rw-r--r-- | src/gui/rhi/qrhinull.cpp | 4 | ||||
-rw-r--r-- | src/gui/rhi/qrhivulkan.cpp | 219 | ||||
-rw-r--r-- | src/gui/rhi/qshader.cpp | 14 | ||||
-rw-r--r-- | src/gui/rhi/qshaderdescription.cpp | 54 | ||||
-rw-r--r-- | src/gui/rhi/vs_test_p.h | 2 |
12 files changed, 426 insertions, 264 deletions
diff --git a/src/gui/rhi/cs_tdr_p.h b/src/gui/rhi/cs_tdr_p.h index 3e442de39c..de444200a0 100644 --- a/src/gui/rhi/cs_tdr_p.h +++ b/src/gui/rhi/cs_tdr_p.h @@ -70,7 +70,7 @@ ret // Approximately 5 instruction slots used #endif -const BYTE g_killDeviceByTimingOut[] = +inline constexpr BYTE g_killDeviceByTimingOut[] = { 68, 88, 66, 67, 217, 62, 220, 38, 136, 51, 86, 245, diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index a1abdffd32..72b9b523d9 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -3262,7 +3262,7 @@ void QRhiImplementation::updateLayoutDesc(QRhiShaderResourceBindings *srb) srb->m_layoutDescHash = 0; srb->m_layoutDesc.clear(); auto layoutDescAppender = std::back_inserter(srb->m_layoutDesc); - for (const QRhiShaderResourceBinding &b : qAsConst(srb->m_bindings)) { + for (const QRhiShaderResourceBinding &b : std::as_const(srb->m_bindings)) { const QRhiShaderResourceBinding::Data *d = b.data(); srb->m_layoutDescHash ^= uint(d->binding) ^ uint(d->stage) ^ uint(d->type) ^ uint(d->arraySize()); @@ -4963,9 +4963,9 @@ QRhiImplementation::~QRhiImplementation() if (!resources.isEmpty()) { if (leakCheck) { qWarning("QRhi %p going down with %d unreleased resources that own native graphics objects. This is not nice.", - q, int(resources.count())); + q, int(resources.size())); } - for (QRhiResource *res : qAsConst(resources)) { + for (QRhiResource *res : std::as_const(resources)) { if (leakCheck) qWarning(" %s resource %p (%s)", resourceTypeStr(res), res, res->m_objectName.constData()); @@ -5583,7 +5583,7 @@ void QRhi::addCleanupCallback(const CleanupCallback &callback) */ void QRhi::runCleanup() { - for (const CleanupCallback &f : qAsConst(d->cleanupCallbacks)) + for (const CleanupCallback &f : std::as_const(d->cleanupCallbacks)) f(this); d->cleanupCallbacks.clear(); @@ -6018,7 +6018,7 @@ QRhiResourceUpdateBatch *QRhi::nextResourceUpdateBatch() QRhiResourceUpdateBatch *u = nextFreeBatch(); if (!u) { - const int oldSize = d->resUpdPool.count(); + const int oldSize = d->resUpdPool.size(); const int newSize = oldSize + qMin(4, qMax(0, 64 - oldSize)); d->resUpdPool.resize(newSize); for (int i = oldSize; i < newSize; ++i) diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h index 2a0cb7d631..a5ab1e5d97 100644 --- a/src/gui/rhi/qrhi_p_p.h +++ b/src/gui/rhi/qrhi_p_p.h @@ -187,7 +187,7 @@ public: void runGpuFrameTimeCallbacks(float t) { - for (const QRhi::GpuFrameTimeCallback &f : qAsConst(gpuFrameTimeCallbacks)) + for (const QRhi::GpuFrameTimeCallback &f : std::as_const(gpuFrameTimeCallbacks)) f(t); } @@ -224,7 +224,13 @@ private: friend class QRhiResourceUpdateBatchPrivate; }; -template<typename T, size_t N> +enum QRhiTargetRectBoundMode +{ + UnBounded, + Bounded +}; + +template<QRhiTargetRectBoundMode boundingMode, typename T, size_t N> bool qrhi_toTopLeftRenderTargetRect(const QSize &outputSize, const std::array<T, N> &r, T *x, T *y, T *w, T *h) { @@ -235,7 +241,7 @@ bool qrhi_toTopLeftRenderTargetRect(const QSize &outputSize, const std::array<T, // 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. + // layers are allergic to out of bounds scissor rects. const T outputWidth = outputSize.width(); const T outputHeight = outputSize.height(); @@ -247,20 +253,23 @@ bool qrhi_toTopLeftRenderTargetRect(const QSize &outputSize, const std::array<T, *x = r[0]; *y = outputHeight - (r[1] + inputHeight); - - const T widthOffset = *x < 0 ? -*x : 0; - const T heightOffset = *y < 0 ? -*y : 0; - *w = *x < outputWidth ? qMax<T>(0, inputWidth - widthOffset) : 0; - *h = *y < outputHeight ? qMax<T>(0, inputHeight - heightOffset) : 0; - - *x = qBound<T>(0, *x, outputWidth - 1); - *y = qBound<T>(0, *y, outputHeight - 1); - - if (*x + *w > outputWidth) - *w = qMax<T>(0, outputWidth - *x); - if (*y + *h > outputHeight) - *h = qMax<T>(0, outputHeight - *y); - + *w = inputWidth; + *h = inputHeight; + + if (boundingMode == Bounded) { + const T widthOffset = *x < 0 ? -*x : 0; + const T heightOffset = *y < 0 ? -*y : 0; + *w = *x < outputWidth ? qMax<T>(0, inputWidth - widthOffset) : 0; + *h = *y < outputHeight ? qMax<T>(0, inputHeight - heightOffset) : 0; + + *x = qBound<T>(0, *x, outputWidth - 1); + *y = qBound<T>(0, *y, outputHeight - 1); + + if (*x + *w > outputWidth) + *w = qMax<T>(0, outputWidth - *x); + if (*y + *h > outputHeight) + *h = qMax<T>(0, outputHeight - *y); + } return true; } diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index 0ac92e2266..81ce0f1fa4 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -1090,7 +1090,7 @@ void QRhiD3D11::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) // d3d expects top-left, QRhiViewport is bottom-left float x, y, w, h; - if (!qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h)) + if (!qrhi_toTopLeftRenderTargetRect<UnBounded>(outputSize, viewport.viewport(), &x, &y, &w, &h)) return; QD3D11CommandBuffer::Command &cmd(cbD->commands.get()); @@ -1112,7 +1112,7 @@ void QRhiD3D11::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) // d3d expects top-left, QRhiScissor is bottom-left int x, y, w, h; - if (!qrhi_toTopLeftRenderTargetRect(outputSize, scissor.scissor(), &x, &y, &w, &h)) + if (!qrhi_toTopLeftRenderTargetRect<Bounded>(outputSize, scissor.scissor(), &x, &y, &w, &h)) return; QD3D11CommandBuffer::Command &cmd(cbD->commands.get()); @@ -1682,7 +1682,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate QD3D11Texture *texD = QRHI_RES(QD3D11Texture, u.dst); for (int layer = 0, maxLayer = u.subresDesc.count(); layer < maxLayer; ++layer) { for (int level = 0; level < QRhi::MAX_MIP_LEVELS; ++level) { - for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level])) + for (const QRhiTextureSubresourceUploadDescription &subresDesc : std::as_const(u.subresDesc[layer][level])) enqueueSubresUpload(texD, cbD, layer, level, subresDesc); } } @@ -2307,7 +2307,7 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD, }); } - for (const Stage::Buffer &buf : qAsConst(res[RBM_VERTEX].buffers)) { + for (const Stage::Buffer &buf : std::as_const(res[RBM_VERTEX].buffers)) { srbD->vsubufs.feed(buf.breg, buf.buffer); srbD->vsubuforigbindings.feed(buf.breg, UINT(buf.binding)); srbD->vsubufoffsets.feed(buf.breg, buf.offsetInConstants); @@ -2318,7 +2318,7 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD, srbD->vsubufoffsets.finish(); srbD->vsubufsizes.finish(); - for (const Stage::Buffer &buf : qAsConst(res[RBM_FRAGMENT].buffers)) { + for (const Stage::Buffer &buf : std::as_const(res[RBM_FRAGMENT].buffers)) { srbD->fsubufs.feed(buf.breg, buf.buffer); srbD->fsubuforigbindings.feed(buf.breg, UINT(buf.binding)); srbD->fsubufoffsets.feed(buf.breg, buf.offsetInConstants); @@ -2329,7 +2329,7 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD, srbD->fsubufoffsets.finish(); srbD->fsubufsizes.finish(); - for (const Stage::Buffer &buf : qAsConst(res[RBM_COMPUTE].buffers)) { + for (const Stage::Buffer &buf : std::as_const(res[RBM_COMPUTE].buffers)) { srbD->csubufs.feed(buf.breg, buf.buffer); srbD->csubuforigbindings.feed(buf.breg, UINT(buf.binding)); srbD->csubufoffsets.feed(buf.breg, buf.offsetInConstants); @@ -2340,28 +2340,28 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD, srbD->csubufoffsets.finish(); srbD->csubufsizes.finish(); - for (const Stage::Texture &t : qAsConst(res[RBM_VERTEX].textures)) + for (const Stage::Texture &t : std::as_const(res[RBM_VERTEX].textures)) srbD->vsshaderresources.feed(t.treg, t.srv); - for (const Stage::Sampler &s : qAsConst(res[RBM_VERTEX].samplers)) + for (const Stage::Sampler &s : std::as_const(res[RBM_VERTEX].samplers)) srbD->vssamplers.feed(s.sreg, s.sampler); srbD->vssamplersPresent = srbD->vssamplers.finish(); srbD->vsshaderresources.finish(); - for (const Stage::Texture &t : qAsConst(res[RBM_FRAGMENT].textures)) + for (const Stage::Texture &t : std::as_const(res[RBM_FRAGMENT].textures)) srbD->fsshaderresources.feed(t.treg, t.srv); - for (const Stage::Sampler &s : qAsConst(res[RBM_FRAGMENT].samplers)) + for (const Stage::Sampler &s : std::as_const(res[RBM_FRAGMENT].samplers)) srbD->fssamplers.feed(s.sreg, s.sampler); srbD->fssamplersPresent = srbD->fssamplers.finish(); srbD->fsshaderresources.finish(); - for (const Stage::Texture &t : qAsConst(res[RBM_COMPUTE].textures)) + for (const Stage::Texture &t : std::as_const(res[RBM_COMPUTE].textures)) srbD->csshaderresources.feed(t.treg, t.srv); - for (const Stage::Sampler &s : qAsConst(res[RBM_COMPUTE].samplers)) + for (const Stage::Sampler &s : std::as_const(res[RBM_COMPUTE].samplers)) srbD->cssamplers.feed(s.sreg, s.sampler); srbD->cssamplersPresent = srbD->cssamplers.finish(); srbD->csshaderresources.finish(); - for (const Stage::Uav &u : qAsConst(res[RBM_COMPUTE].uavs)) + for (const Stage::Uav &u : std::as_const(res[RBM_COMPUTE].uavs)) srbD->csUAVs.feed(u.ureg, u.uav); srbD->csUAVsPresent = srbD->csUAVs.finish(); } @@ -4325,7 +4325,7 @@ bool QD3D11GraphicsPipeline::create() } QByteArray vsByteCode; - for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) { + for (const QRhiShaderStage &shaderStage : std::as_const(m_shaderStages)) { auto cacheIt = rhiD->m_shaderCache.constFind(shaderStage); if (cacheIt != rhiD->m_shaderCache.constEnd()) { switch (shaderStage.type()) { diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 074ed65882..e97a828c76 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -725,8 +725,15 @@ bool QRhiGles2::create(QRhi::Flags flags) else caps.fixedIndexPrimitiveRestart = caps.ctxMajor > 4 || (caps.ctxMajor == 4 && caps.ctxMinor >= 3); // 4.3 - if (caps.fixedIndexPrimitiveRestart) + if (caps.fixedIndexPrimitiveRestart) { +#ifdef Q_OS_WASM + // WebGL 2 behaves as if GL_PRIMITIVE_RESTART_FIXED_INDEX was always + // enabled (i.e. matching D3D/Metal), and the value cannot be passed to + // glEnable, so skip the call. +#else f->glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); +#endif + } caps.bgraExternalFormat = f->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat); caps.bgraInternalFormat = caps.bgraExternalFormat && caps.gles; @@ -913,7 +920,7 @@ void QRhiGles2::destroy() void QRhiGles2::executeDeferredReleases() { - for (int i = releaseQueue.count() - 1; i >= 0; --i) { + for (int i = releaseQueue.size() - 1; i >= 0; --i) { const QRhiGles2::DeferredReleaseEntry &e(releaseQueue[i]); switch (e.type) { case QRhiGles2::DeferredReleaseEntry::Buffer: @@ -1337,8 +1344,8 @@ QByteArray QRhiGles2::pipelineCacheData() memset(&header, 0, sizeof(header)); header.rhiId = pipelineCacheRhiId(); header.arch = quint32(sizeof(void*)); - header.programBinaryCount = m_pipelineCache.count(); - const size_t driverStrLen = qMin(sizeof(header.driver) - 1, size_t(driverInfoStruct.deviceName.length())); + header.programBinaryCount = m_pipelineCache.size(); + const size_t driverStrLen = qMin(sizeof(header.driver) - 1, size_t(driverInfoStruct.deviceName.size())); if (driverStrLen) memcpy(header.driver, driverInfoStruct.deviceName.constData(), driverStrLen); header.driver[driverStrLen] = '\0'; @@ -1410,7 +1417,7 @@ void QRhiGles2::setPipelineCacheData(const QByteArray &data) if (header.programBinaryCount == 0) return; - const size_t driverStrLen = qMin(sizeof(header.driver) - 1, size_t(driverInfoStruct.deviceName.length())); + const size_t driverStrLen = qMin(sizeof(header.driver) - 1, size_t(driverInfoStruct.deviceName.size())); if (strncmp(header.driver, driverInfoStruct.deviceName.constData(), driverStrLen)) { qWarning("setPipelineCacheData: OpenGL vendor/renderer/version does not match"); return; @@ -1445,7 +1452,7 @@ void QRhiGles2::setPipelineCacheData(const QByteArray &data) m_pipelineCache.insert(key, { format, data }); } - qCDebug(QRHI_LOG_INFO, "Seeded pipeline cache with %d program binaries", int(m_pipelineCache.count())); + qCDebug(QRHI_LOG_INFO, "Seeded pipeline cache with %d program binaries", int(m_pipelineCache.size())); } QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, @@ -1527,7 +1534,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind QGles2ShaderResourceBindings *srbD = QRHI_RES(QGles2ShaderResourceBindings, srb); if (cbD->passNeedsResourceTracking) { QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]); - for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) { + for (int i = 0, ie = srbD->m_bindings.size(); i != ie; ++i) { const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data(); switch (b->type) { case QRhiShaderResourceBinding::UniformBuffer: @@ -2247,9 +2254,9 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate const QRhiResourceUpdateBatchPrivate::TextureOp &u(ud->textureOps[opIdx]); if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) { QGles2Texture *texD = QRHI_RES(QGles2Texture, u.dst); - for (int layer = 0, maxLayer = u.subresDesc.count(); layer < maxLayer; ++layer) { + for (int layer = 0, maxLayer = u.subresDesc.size(); layer < maxLayer; ++layer) { for (int level = 0; level < QRhi::MAX_MIP_LEVELS; ++level) { - for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level])) + for (const QRhiTextureSubresourceUploadDescription &subresDesc : std::as_const(u.subresDesc[layer][level])) enqueueSubresUpload(texD, cbD, layer, level, subresDesc); } } @@ -3015,8 +3022,10 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) f->glDepthMask(GL_TRUE); f->glClearDepthf(cmd.args.clear.d); } - if (cmd.args.clear.mask & GL_STENCIL_BUFFER_BIT) + if (cmd.args.clear.mask & GL_STENCIL_BUFFER_BIT) { + f->glStencilMask(0xFF); f->glClearStencil(GLint(cmd.args.clear.s)); + } f->glClear(cmd.args.clear.mask); cbD->graphicsPassState.reset(); // altered depth/color write, invalidate in order to avoid confusing the state tracking break; @@ -3577,7 +3586,7 @@ void QRhiGles2::bindShaderResources(QGles2CommandBuffer *cbD, }; QVarLengthArray<SeparateSampler, 4> separateSamplerBindings; - for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) { + for (int i = 0, ie = srbD->m_bindings.size(); i != ie; ++i) { const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data(); switch (b->type) { @@ -3592,7 +3601,7 @@ void QRhiGles2::bindShaderResources(QGles2CommandBuffer *cbD, } QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.ubuf.buf); const char *bufView = bufD->data.constData() + viewOffset; - for (const QGles2UniformDescription &uniform : qAsConst(uniforms)) { + for (const QGles2UniformDescription &uniform : std::as_const(uniforms)) { if (uniform.binding == b->binding) { // in a uniform buffer everything is at least 4 byte aligned // so this should not cause unaligned reads @@ -3981,7 +3990,7 @@ QGles2RenderTargetData *QRhiGles2::enqueueBindFramebuffer(QRhiRenderTarget *rt, void QRhiGles2::enqueueBarriersForPass(QGles2CommandBuffer *cbD) { cbD->passResTrackers.append(QRhiPassResourceTracker()); - cbD->currentPassResTrackerIndex = cbD->passResTrackers.count() - 1; + cbD->currentPassResTrackerIndex = cbD->passResTrackers.size() - 1; QGles2CommandBuffer::Command &cmd(cbD->commands.get()); cmd.cmd = QGles2CommandBuffer::Command::BarriersForPass; cmd.args.barriersForPass.trackerIndex = cbD->currentPassResTrackerIndex; @@ -4159,7 +4168,7 @@ void QRhiGles2::dispatch(QRhiCommandBuffer *cb, int x, int y, int z) accessAndIsNewFlag = { 0, false }; QGles2ShaderResourceBindings *srbD = QRHI_RES(QGles2ShaderResourceBindings, cbD->currentComputeSrb); - const int bindingCount = srbD->m_bindings.count(); + const int bindingCount = srbD->m_bindings.size(); for (int i = 0; i < bindingCount; ++i) { const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data(); switch (b->type) { @@ -4320,7 +4329,7 @@ bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage } else { shader = f->glCreateShader(toGlShaderType(shaderStage.type())); const char *srcStr = source.constData(); - const GLint srcLength = source.length(); + const GLint srcLength = source.size(); f->glShaderSource(shader, 1, &srcStr, &srcLength); f->glCompileShader(shader); GLint compiled = 0; @@ -4337,7 +4346,7 @@ bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage qWarning("Failed to compile shader: %s\nSource was:\n%s", log.constData(), source.constData()); return false; } - if (m_shaderCache.count() >= MAX_SHADER_CACHE_ENTRIES) { + if (m_shaderCache.size() >= MAX_SHADER_CACHE_ENTRIES) { // Use the simplest strategy: too many cached shaders -> drop them all. for (uint shader : m_shaderCache) f->glDeleteShader(shader); // does not actually get released yet when attached to a not-yet-released program @@ -4394,7 +4403,7 @@ void QRhiGles2::registerUniformIfActive(const QShaderDescription::BlockVariable // unnecessary glUniform* calls then. uniform.glslLocation = f->glGetUniformLocation(program, name.constData()); if (uniform.glslLocation >= 0 && !activeUniformLocations->hasSeen(uniform.glslLocation)) { - if (var.arrayDims.count() > 1) { + if (var.arrayDims.size() > 1) { qWarning("Array '%s' has more than one dimension. This is not supported.", var.name.constData()); return; @@ -4423,7 +4432,7 @@ void QRhiGles2::gatherUniforms(GLuint program, registerUniformIfActive(structMember, structPrefix + ".", ub.binding, baseOffset, program, activeUniformLocations, dst); } else { - if (blockMember.arrayDims.count() > 1) { + if (blockMember.arrayDims.size() > 1) { qWarning("Array of struct '%s' has more than one dimension. Only the first " "dimension is used.", blockMember.name.constData()); @@ -5383,7 +5392,7 @@ bool QGles2ShaderResourceBindings::create() return false; hasDynamicOffset = false; - for (int i = 0, ie = m_bindings.count(); i != ie; ++i) { + for (int i = 0, ie = m_bindings.size(); i != ie; ++i) { const QRhiShaderResourceBinding::Data *b = m_bindings.at(i).data(); if (b->type == QRhiShaderResourceBinding::UniformBuffer) { if (b->u.ubuf.hasDynamicOffset) { @@ -5491,9 +5500,12 @@ bool QGles2GraphicsPipeline::create() }; QShaderDescription desc[LastIdx]; QShader::SeparateToCombinedImageSamplerMappingList samplerMappingList[LastIdx]; - for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) { + bool vertexFragmentOnly = true; + for (const QRhiShaderStage &shaderStage : std::as_const(m_shaderStages)) { if (isGraphicsStage(shaderStage)) { const int idx = descIdxForStage(shaderStage); + if (idx != VtxIdx && idx != FragIdx) + vertexFragmentOnly = false; QShader shader = shaderStage.shader(); QShaderVersion shaderVersion; desc[idx] = shader.description(); @@ -5506,7 +5518,7 @@ bool QGles2GraphicsPipeline::create() QByteArray cacheKey; QRhiGles2::ProgramCacheResult cacheResult = rhiD->tryLoadFromDiskOrPipelineCache(m_shaderStages.constData(), - m_shaderStages.count(), + m_shaderStages.size(), program, desc[VtxIdx].inputVariables(), &cacheKey); @@ -5514,7 +5526,7 @@ bool QGles2GraphicsPipeline::create() return false; if (cacheResult == QRhiGles2::ProgramCacheMiss) { - for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) { + for (const QRhiShaderStage &shaderStage : std::as_const(m_shaderStages)) { if (isGraphicsStage(shaderStage)) { if (!rhiD->compileShader(program, shaderStage, nullptr)) return false; @@ -5525,7 +5537,8 @@ bool QGles2GraphicsPipeline::create() for (const QShaderDescription::InOutVariable &inVar : desc[VtxIdx].inputVariables()) rhiD->f->glBindAttribLocation(program, GLuint(inVar.location), inVar.name); - rhiD->sanityCheckVertexFragmentInterface(desc[VtxIdx], desc[FragIdx]); + if (vertexFragmentOnly) + rhiD->sanityCheckVertexFragmentInterface(desc[VtxIdx], desc[FragIdx]); if (!rhiD->linkProgram(program)) return false; @@ -5553,7 +5566,7 @@ bool QGles2GraphicsPipeline::create() // present in both shaders. QDuplicateTracker<int, 256> activeUniformLocations; - for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) { + for (const QRhiShaderStage &shaderStage : std::as_const(m_shaderStages)) { if (isGraphicsStage(shaderStage)) { const int idx = descIdxForStage(shaderStage); for (const QShaderDescription::UniformBlock &ub : desc[idx].uniformBlocks()) diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 2ae90bdb0e..2c78517f74 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -402,12 +402,16 @@ bool QRhiMetal::create(QRhi::Flags flags) #if defined(Q_OS_MACOS) caps.maxTextureSize = 16384; caps.baseVertexAndInstance = true; + if (@available(macOS 10.15, *)) + caps.isAppleGPU = [d->dev supportsFamily:MTLGPUFamilyApple7]; + caps.maxThreadGroupSize = 1024; #elif defined(Q_OS_TVOS) if ([d->dev supportsFeatureSet: MTLFeatureSet(30003)]) // MTLFeatureSet_tvOS_GPUFamily2_v1 caps.maxTextureSize = 16384; else caps.maxTextureSize = 8192; caps.baseVertexAndInstance = false; + caps.isAppleGPU = true; #elif defined(Q_OS_IOS) // welcome to feature set hell if ([d->dev supportsFeatureSet: MTLFeatureSet(16)] // MTLFeatureSet_iOS_GPUFamily5_v1 @@ -425,6 +429,11 @@ bool QRhiMetal::create(QRhi::Flags flags) caps.maxTextureSize = 4096; caps.baseVertexAndInstance = false; } + caps.isAppleGPU = true; + if (@available(iOS 13, *)) { + if ([d->dev supportsFamily:MTLGPUFamilyApple4]) + caps.maxThreadGroupSize = 1024; + } #endif caps.supportedSampleCounts = { 1 }; @@ -524,16 +533,32 @@ bool QRhiMetal::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture { Q_UNUSED(flags); + bool supportsFamilyMac2 = false; // needed for BC* formats + bool supportsFamilyApple3 = false; + #ifdef Q_OS_MACOS - if (format >= QRhiTexture::ETC2_RGB8 && format <= QRhiTexture::ETC2_RGBA8) - return false; - if (format >= QRhiTexture::ASTC_4x4 && format <= QRhiTexture::ASTC_12x12) - return false; + supportsFamilyMac2 = true; + if (caps.isAppleGPU) + supportsFamilyApple3 = true; #else - if (format >= QRhiTexture::BC1 && format <= QRhiTexture::BC7) - return false; + supportsFamilyApple3 = true; #endif + // BC5 is not available for any Apple hardare + if (format == QRhiTexture::BC5) + return false; + + if (!supportsFamilyApple3) { + if (format >= QRhiTexture::ETC2_RGB8 && format <= QRhiTexture::ETC2_RGBA8) + return false; + if (format >= QRhiTexture::ASTC_4x4 && format <= QRhiTexture::ASTC_12x12) + return false; + } + + if (!supportsFamilyMac2) + if (format >= QRhiTexture::BC1 && format <= QRhiTexture::BC7) + return false; + return true; } @@ -638,11 +663,7 @@ int QRhiMetal::resourceLimit(QRhi::ResourceLimit limit) const case QRhi::MaxThreadGroupY: Q_FALLTHROUGH(); case QRhi::MaxThreadGroupZ: -#if defined(Q_OS_MACOS) - return 1024; -#else - return 512; -#endif + return caps.maxThreadGroupSize; case QRhi::TextureArraySizeMax: return 2048; case QRhi::MaxUniformBufferRange: @@ -799,7 +820,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD } res[SUPPORTED_STAGES]; enum { VERTEX = 0, FRAGMENT = 1, COMPUTE = 2 }; - for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) { + for (const QRhiShaderResourceBinding &binding : std::as_const(srbD->sortedBindings)) { const QRhiShaderResourceBinding::Data *b = binding.data(); switch (b->type) { case QRhiShaderResourceBinding::UniformBuffer: @@ -941,7 +962,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD return a.nativeBinding < b.nativeBinding; }); - for (const Stage::Buffer &buf : qAsConst(res[stage].buffers)) { + for (const Stage::Buffer &buf : std::as_const(res[stage].buffers)) { res[stage].bufferBatches.feed(buf.nativeBinding, buf.mtlbuf); res[stage].bufferOffsetBatches.feed(buf.nativeBinding, buf.offset); } @@ -985,10 +1006,10 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD return a.nativeBinding < b.nativeBinding; }); - for (const Stage::Texture &t : qAsConst(res[stage].textures)) + for (const Stage::Texture &t : std::as_const(res[stage].textures)) res[stage].textureBatches.feed(t.nativeBinding, t.mtltex); - for (const Stage::Sampler &s : qAsConst(res[stage].samplers)) + for (const Stage::Sampler &s : std::as_const(res[stage].samplers)) res[stage].samplerBatches.feed(s.nativeBinding, s.mtlsampler); res[stage].textureBatches.finish(); @@ -1284,7 +1305,7 @@ void QRhiMetal::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) // x,y is top-left in MTLViewportRect but bottom-left in QRhiViewport float x, y, w, h; - if (!qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h)) + if (!qrhi_toTopLeftRenderTargetRect<UnBounded>(outputSize, viewport.viewport(), &x, &y, &w, &h)) return; MTLViewport vp; @@ -1299,6 +1320,7 @@ void QRhiMetal::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) if (!QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) { MTLScissorRect s; + qrhi_toTopLeftRenderTargetRect<Bounded>(outputSize, viewport.viewport(), &x, &y, &w, &h); s.x = NSUInteger(x); s.y = NSUInteger(y); s.width = NSUInteger(w); @@ -1316,7 +1338,7 @@ void QRhiMetal::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) // x,y is top-left in MTLScissorRect but bottom-left in QRhiScissor int x, y, w, h; - if (!qrhi_toTopLeftRenderTargetRect(outputSize, scissor.scissor(), &x, &y, &w, &h)) + if (!qrhi_toTopLeftRenderTargetRect<Bounded>(outputSize, scissor.scissor(), &x, &y, &w, &h)) return; MTLScissorRect s; @@ -1457,7 +1479,7 @@ QRhi::FrameOpResult QRhiMetal::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginF // commands+present to complete, while for others just for the commands // (for this same frame slot) but not sure how to do that in a sane way so // wait for full cb completion for now. - for (QMetalSwapChain *sc : qAsConst(swapchains)) { + for (QMetalSwapChain *sc : std::as_const(swapchains)) { dispatch_semaphore_t sem = sc->d->sem[swapChainD->currentFrameSlot]; dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); if (sc != swapChainD) @@ -1550,15 +1572,13 @@ QRhi::FrameOpResult QRhiMetal::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi: Q_UNUSED(flags); currentFrameSlot = (currentFrameSlot + 1) % QMTL_FRAMES_IN_FLIGHT; - if (swapchains.count() > 1) { - for (QMetalSwapChain *sc : qAsConst(swapchains)) { - // wait+signal is the general pattern to ensure the commands for a - // given frame slot have completed (if sem is 1, we go 0 then 1; if - // sem is 0 we go -1, block, completion increments to 0, then us to 1) - dispatch_semaphore_t sem = sc->d->sem[currentFrameSlot]; - dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); - dispatch_semaphore_signal(sem); - } + for (QMetalSwapChain *sc : std::as_const(swapchains)) { + // wait+signal is the general pattern to ensure the commands for a + // given frame slot have completed (if sem is 1, we go 0 then 1; if + // sem is 0 we go -1, block, completion increments to 0, then us to 1) + dispatch_semaphore_t sem = sc->d->sem[currentFrameSlot]; + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); + dispatch_semaphore_signal(sem); } d->ofr.active = true; @@ -1605,7 +1625,7 @@ QRhi::FrameOpResult QRhiMetal::finish() } } - for (QMetalSwapChain *sc : qAsConst(swapchains)) { + for (QMetalSwapChain *sc : std::as_const(swapchains)) { for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i) { if (currentSwapChain && sc == currentSwapChain && i == currentFrameSlot) { // no wait as this is the thing we're going to be commit below and @@ -1853,7 +1873,7 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate qsizetype stagingSize = 0; for (int layer = 0, maxLayer = u.subresDesc.count(); layer < maxLayer; ++layer) { for (int level = 0; level < QRhi::MAX_MIP_LEVELS; ++level) { - for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level])) + for (const QRhiTextureSubresourceUploadDescription &subresDesc : std::as_const(u.subresDesc[layer][level])) stagingSize += subresUploadByteSize(subresDesc); } } @@ -1867,7 +1887,7 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate qsizetype curOfs = 0; for (int layer = 0, maxLayer = u.subresDesc.count(); layer < maxLayer; ++layer) { for (int level = 0; level < QRhi::MAX_MIP_LEVELS; ++level) { - for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level])) + for (const QRhiTextureSubresourceUploadDescription &subresDesc : std::as_const(u.subresDesc[layer][level])) enqueueSubresUpload(utexD, mp, blitEnc, layer, level, subresDesc, &curOfs); } } @@ -1980,7 +2000,7 @@ void QRhiMetal::executeBufferHostWritesForSlot(QMetalBuffer *bufD, int slot) void *p = [bufD->d->buf[slot] contents]; int changeBegin = -1; int changeEnd = -1; - for (const QMetalBufferData::BufferUpdate &u : qAsConst(bufD->d->pendingUpdates[slot])) { + for (const QMetalBufferData::BufferUpdate &u : std::as_const(bufD->d->pendingUpdates[slot])) { memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), size_t(u.data.size())); if (changeBegin == -1 || u.offset < changeBegin) changeBegin = u.offset; @@ -2319,8 +2339,10 @@ bool QMetalBuffer::create() d->managed = false; MTLResourceOptions opts = MTLResourceStorageModeShared; + + QRHI_RES_RHI(QRhiMetal); #ifdef Q_OS_MACOS - if (m_type != Dynamic) { + if (!rhiD->caps.isAppleGPU && m_type != Dynamic) { opts = MTLResourceStorageModeManaged; d->managed = true; } @@ -2332,7 +2354,6 @@ bool QMetalBuffer::create() // same buffer is still in flight. d->slotted = !m_usage.testFlag(QRhiBuffer::StorageBuffer); // except for SSBOs written in the shader - QRHI_RES_RHI(QRhiMetal); for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i) { if (i == 0 || d->slotted) { d->buf[i] = [rhiD->d->dev newBufferWithLength: roundedSize options: opts]; @@ -2395,11 +2416,12 @@ void QMetalBuffer::endFullDynamicBufferUpdateForCurrentFrame() #endif } -static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QRhiTexture::Flags flags, const QRhiMetalData *d) +static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QRhiTexture::Flags flags, const QRhiMetal *d) { #ifndef Q_OS_MACOS Q_UNUSED(d); #endif + const bool srgb = flags.testFlag(QRhiTexture::sRGB); switch (format) { case QRhiTexture::RGBA8: @@ -2441,9 +2463,9 @@ static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QR case QRhiTexture::D16: return MTLPixelFormatDepth16Unorm; case QRhiTexture::D24: - return [d->dev isDepth24Stencil8PixelFormatSupported] ? MTLPixelFormatDepth24Unorm_Stencil8 : MTLPixelFormatDepth32Float; + return [d->d->dev isDepth24Stencil8PixelFormatSupported] ? MTLPixelFormatDepth24Unorm_Stencil8 : MTLPixelFormatDepth32Float; case QRhiTexture::D24S8: - return [d->dev isDepth24Stencil8PixelFormatSupported] ? MTLPixelFormatDepth24Unorm_Stencil8 : MTLPixelFormatDepth32Float_Stencil8; + return [d->d->dev isDepth24Stencil8PixelFormatSupported] ? MTLPixelFormatDepth24Unorm_Stencil8 : MTLPixelFormatDepth32Float_Stencil8; #else case QRhiTexture::D16: return MTLPixelFormatDepth32Float; @@ -2466,7 +2488,7 @@ static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QR return MTLPixelFormatBC4_RUnorm; case QRhiTexture::BC5: qWarning("QRhiMetal does not support BC5"); - return MTLPixelFormatRGBA8Unorm; + return MTLPixelFormatInvalid; case QRhiTexture::BC6H: return MTLPixelFormatBC6H_RGBUfloat; case QRhiTexture::BC7: @@ -2480,7 +2502,7 @@ static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QR case QRhiTexture::BC6H: case QRhiTexture::BC7: qWarning("QRhiMetal: BCx compression not supported on this platform"); - return MTLPixelFormatRGBA8Unorm; + return MTLPixelFormatInvalid; #endif #ifndef Q_OS_MACOS @@ -2521,32 +2543,129 @@ static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QR return srgb ? MTLPixelFormatASTC_12x12_sRGB : MTLPixelFormatASTC_12x12_LDR; #else case QRhiTexture::ETC2_RGB8: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatETC2_RGB8_sRGB : MTLPixelFormatETC2_RGB8; + } + qWarning("QRhiMetal: ETC2 compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ETC2_RGB8A1: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatETC2_RGB8A1_sRGB : MTLPixelFormatETC2_RGB8A1; + } + qWarning("QRhiMetal: ETC2 compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ETC2_RGBA8: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatEAC_RGBA8_sRGB : MTLPixelFormatEAC_RGBA8; + } qWarning("QRhiMetal: ETC2 compression not supported on this platform"); - return MTLPixelFormatRGBA8Unorm; - + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_4x4: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_4x4_sRGB : MTLPixelFormatASTC_4x4_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_5x4: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_5x4_sRGB : MTLPixelFormatASTC_5x4_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_5x5: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_5x5_sRGB : MTLPixelFormatASTC_5x5_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_6x5: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_6x5_sRGB : MTLPixelFormatASTC_6x5_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_6x6: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_6x6_sRGB : MTLPixelFormatASTC_6x6_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_8x5: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_8x5_sRGB : MTLPixelFormatASTC_8x5_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_8x6: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_8x6_sRGB : MTLPixelFormatASTC_8x6_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_8x8: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_8x8_sRGB : MTLPixelFormatASTC_8x8_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_10x5: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_10x5_sRGB : MTLPixelFormatASTC_10x5_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_10x6: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_10x6_sRGB : MTLPixelFormatASTC_10x6_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_10x8: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_10x8_sRGB : MTLPixelFormatASTC_10x8_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_10x10: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_10x10_sRGB : MTLPixelFormatASTC_10x10_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_12x10: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_12x10_sRGB : MTLPixelFormatASTC_12x10_LDR; + } + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatInvalid; case QRhiTexture::ASTC_12x12: + if (d->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) + return srgb ? MTLPixelFormatASTC_12x12_sRGB : MTLPixelFormatASTC_12x12_LDR; + } qWarning("QRhiMetal: ASTC compression not supported on this platform"); - return MTLPixelFormatRGBA8Unorm; + return MTLPixelFormatInvalid; #endif default: Q_UNREACHABLE(); - return MTLPixelFormatRGBA8Unorm; + return MTLPixelFormatInvalid; } } @@ -2606,9 +2725,18 @@ bool QMetalRenderBuffer::create() switch (m_type) { case DepthStencil: #ifdef Q_OS_MACOS - desc.storageMode = MTLStorageModePrivate; - d->format = rhiD->d->dev.depth24Stencil8PixelFormatSupported - ? MTLPixelFormatDepth24Unorm_Stencil8 : MTLPixelFormatDepth32Float_Stencil8; + if (rhiD->caps.isAppleGPU) { + if (@available(macOS 11.0, *)) { + desc.storageMode = MTLStorageModeMemoryless; + d->format = MTLPixelFormatDepth32Float_Stencil8; + } else { + Q_UNREACHABLE(); + } + } else { + desc.storageMode = MTLStorageModePrivate; + d->format = rhiD->d->dev.depth24Stencil8PixelFormatSupported + ? MTLPixelFormatDepth24Unorm_Stencil8 : MTLPixelFormatDepth32Float_Stencil8; + } #else desc.storageMode = MTLStorageModeMemoryless; d->format = MTLPixelFormatDepth32Float_Stencil8; @@ -2618,7 +2746,7 @@ bool QMetalRenderBuffer::create() case Color: desc.storageMode = MTLStorageModePrivate; if (m_backingFormatHint != QRhiTexture::UnknownFormat) - d->format = toMetalTextureFormat(m_backingFormatHint, {}, rhiD->d); + d->format = toMetalTextureFormat(m_backingFormatHint, {}, rhiD); else d->format = MTLPixelFormatRGBA8Unorm; desc.pixelFormat = d->format; @@ -2707,7 +2835,7 @@ bool QMetalTexture::prepareCreate(QSize *adjustedSize) const bool hasMipMaps = m_flags.testFlag(MipMapped); QRHI_RES_RHI(QRhiMetal); - d->format = toMetalTextureFormat(m_format, m_flags, rhiD->d); + d->format = toMetalTextureFormat(m_format, m_flags, rhiD); mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1; samples = rhiD->effectiveSampleCount(m_sampleCount); if (samples > 1) { @@ -3594,10 +3722,7 @@ id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Var id<MTLFunction> QRhiMetalData::createMSLShaderFunction(id<MTLLibrary> lib, const QByteArray &entryPoint) { - NSString *name = [NSString stringWithUTF8String: entryPoint.constData()]; - id<MTLFunction> f = [lib newFunctionWithName: name]; - [name release]; - return f; + return [lib newFunctionWithName:[NSString stringWithUTF8String:entryPoint.constData()]]; } bool QMetalGraphicsPipeline::create() @@ -3642,7 +3767,7 @@ bool QMetalGraphicsPipeline::create() // descriptor for each buffer combination as this depends on the actual // buffers not just the resource binding layout) so leave it at the default - for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) { + for (const QRhiShaderStage &shaderStage : std::as_const(m_shaderStages)) { auto cacheIt = rhiD->d->shaderCache.constFind(shaderStage); if (cacheIt != rhiD->d->shaderCache.constEnd()) { switch (shaderStage.type()) { @@ -3741,7 +3866,7 @@ bool QMetalGraphicsPipeline::create() // validation blows up otherwise. MTLPixelFormat fmt = MTLPixelFormat(rpD->dsFormat); rpDesc.depthAttachmentPixelFormat = fmt; -#ifdef Q_OS_MACOS +#if defined(Q_OS_MACOS) if (fmt != MTLPixelFormatDepth16Unorm && fmt != MTLPixelFormatDepth32Float) #else if (fmt != MTLPixelFormatDepth32Float) @@ -4040,8 +4165,7 @@ QSize QMetalSwapChain::surfacePixelSize() bool QMetalSwapChain::isFormatSupported(Format f) { #ifdef Q_OS_MACOS - if (@available(macOS 10.12, /*iOS 10.0,*/ *)) - return f == SDR || f == HDRExtendedSrgbLinear; + return f == SDR || f == HDRExtendedSrgbLinear; #endif return f == SDR; } @@ -4075,11 +4199,9 @@ void QMetalSwapChain::chooseFormats() samples = rhiD->effectiveSampleCount(m_sampleCount); // pick a format that is allowed for CAMetalLayer.pixelFormat if (m_format == HDRExtendedSrgbLinear) { - if (@available(macOS 10.12, /*iOS 10.0,*/ *)) { - d->colorFormat = MTLPixelFormatRGBA16Float; - d->rhiColorFormat = QRhiTexture::RGBA16F; - return; - } + d->colorFormat = MTLPixelFormatRGBA16Float; + d->rhiColorFormat = QRhiTexture::RGBA16F; + return; } d->colorFormat = m_flags.testFlag(sRGB) ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm; d->rhiColorFormat = QRhiTexture::BGRA8; @@ -4113,11 +4235,10 @@ bool QMetalSwapChain::createOrResize() if (d->colorFormat != d->layer.pixelFormat) d->layer.pixelFormat = d->colorFormat; #ifdef Q_OS_MACOS - if (@available(macOS 10.12, /*iOS 10.0,*/ *)) { // Can't enable this on iOS until wantsExtendedDynamicRangeContent is available - if (m_format == HDRExtendedSrgbLinear) { - d->layer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceExtendedLinearSRGB); - d->layer.wantsExtendedDynamicRangeContent = YES; - } + // Can't enable this on iOS until wantsExtendedDynamicRangeContent is available + if (m_format == HDRExtendedSrgbLinear) { + d->layer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceExtendedLinearSRGB); + d->layer.wantsExtendedDynamicRangeContent = YES; } #endif diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h index ef9b9c93ca..4e5f9dd21e 100644 --- a/src/gui/rhi/qrhimetal_p_p.h +++ b/src/gui/rhi/qrhimetal_p_p.h @@ -454,6 +454,8 @@ public: int maxTextureSize = 4096; bool baseVertexAndInstance = true; QVector<int> supportedSampleCounts; + bool isAppleGPU = false; + int maxThreadGroupSize = 512; } caps; QRhiMetalData *d = nullptr; diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp index 2a3412a69c..f8571be604 100644 --- a/src/gui/rhi/qrhinull.cpp +++ b/src/gui/rhi/qrhinull.cpp @@ -382,9 +382,9 @@ QRhi::FrameOpResult QRhiNull::finish() void QRhiNull::simulateTextureUpload(const QRhiResourceUpdateBatchPrivate::TextureOp &u) { QNullTexture *texD = QRHI_RES(QNullTexture, u.dst); - for (int layer = 0, maxLayer = u.subresDesc.count(); layer < maxLayer; ++layer) { + for (int layer = 0, maxLayer = u.subresDesc.size(); layer < maxLayer; ++layer) { for (int level = 0; level < QRhi::MAX_MIP_LEVELS; ++level) { - for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level])) { + for (const QRhiTextureSubresourceUploadDescription &subresDesc : std::as_const(u.subresDesc[layer][level])) { if (!subresDesc.image().isNull()) { const QImage src = subresDesc.image(); QPainter painter(&texD->image[layer][level]); diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 4bdd16e021..ff74de6f77 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -486,7 +486,7 @@ bool QRhiVulkan::create(QRhi::Flags flags) gfxQueueFamilyIdx = -1; int computelessGfxQueueCandidateIdx = -1; queryQueueFamilyProps(); - for (int i = 0; i < queueFamilyProps.count(); ++i) { + for (int i = 0; i < queueFamilyProps.size(); ++i) { qCDebug(QRHI_LOG_INFO, "queue family %d: flags=0x%x count=%d", i, queueFamilyProps[i].queueFlags, queueFamilyProps[i].queueCount); if (gfxQueueFamilyIdx == -1 @@ -526,14 +526,26 @@ bool QRhiVulkan::create(QRhi::Flags flags) if (devExtCount) { QList<VkExtensionProperties> extProps(devExtCount); f->vkEnumerateDeviceExtensionProperties(physDev, nullptr, &devExtCount, extProps.data()); - for (const VkExtensionProperties &p : qAsConst(extProps)) + for (const VkExtensionProperties &p : std::as_const(extProps)) devExts.append({ p.extensionName, p.specVersion }); } - qCDebug(QRHI_LOG_INFO, "%d device extensions available", int(devExts.count())); + qCDebug(QRHI_LOG_INFO, "%d device extensions available", int(devExts.size())); QList<const char *> requestedDevExts; requestedDevExts.append("VK_KHR_swapchain"); + const bool hasPhysDevProp2 = inst->extensions().contains(QByteArrayLiteral("VK_KHR_get_physical_device_properties2")); + + if (devExts.contains(QByteArrayLiteral("VK_KHR_portability_subset"))) { + if (hasPhysDevProp2) { + requestedDevExts.append("VK_KHR_portability_subset"); + } else { + qWarning("VK_KHR_portability_subset should be enabled on the device " + "but the instance does not have VK_KHR_get_physical_device_properties2 enabled. " + "Expect problems."); + } + } + caps.debugMarkers = false; if (devExts.contains(VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) { requestedDevExts.append(VK_EXT_DEBUG_MARKER_EXTENSION_NAME); @@ -542,28 +554,32 @@ bool QRhiVulkan::create(QRhi::Flags flags) caps.vertexAttribDivisor = false; if (devExts.contains(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) { - if (inst->extensions().contains(QByteArrayLiteral("VK_KHR_get_physical_device_properties2"))) { + if (hasPhysDevProp2) { requestedDevExts.append(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME); caps.vertexAttribDivisor = true; } } for (const QByteArray &ext : requestedDeviceExtensions) { - if (!ext.isEmpty()) { - if (devExts.contains(ext)) + if (!ext.isEmpty() && !requestedDevExts.contains(ext)) { + if (devExts.contains(ext)) { requestedDevExts.append(ext.constData()); - else - qWarning("Device extension %s is not supported", ext.constData()); + } else { + qWarning("Device extension %s requested in QRhiVulkanInitParams is not supported", + ext.constData()); + } } } QByteArrayList envExtList = qgetenv("QT_VULKAN_DEVICE_EXTENSIONS").split(';'); for (const QByteArray &ext : envExtList) { if (!ext.isEmpty() && !requestedDevExts.contains(ext)) { - if (devExts.contains(ext)) + if (devExts.contains(ext)) { requestedDevExts.append(ext.constData()); - else - qWarning("Device extension %s is not supported", ext.constData()); + } else { + qWarning("Device extension %s requested in QT_VULKAN_DEVICE_EXTENSIONS is not supported", + ext.constData()); + } } } @@ -578,9 +594,9 @@ bool QRhiVulkan::create(QRhi::Flags flags) devInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; devInfo.queueCreateInfoCount = 1; devInfo.pQueueCreateInfos = queueInfo; - devInfo.enabledLayerCount = uint32_t(devLayers.count()); + devInfo.enabledLayerCount = uint32_t(devLayers.size()); devInfo.ppEnabledLayerNames = devLayers.constData(); - devInfo.enabledExtensionCount = uint32_t(requestedDevExts.count()); + devInfo.enabledExtensionCount = uint32_t(requestedDevExts.size()); devInfo.ppEnabledExtensionNames = requestedDevExts.constData(); // Enable all 1.0 core features that are reported as supported, except @@ -830,7 +846,7 @@ bool QRhiVulkan::allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, V return r; }; - int lastPoolIdx = descriptorPools.count() - 1; + int lastPoolIdx = descriptorPools.size() - 1; for (int i = lastPoolIdx; i >= 0; --i) { if (descriptorPools[i].refCount == 0) { df->vkResetDescriptorPool(dev, descriptorPools[i].pool, 0); @@ -850,7 +866,7 @@ bool QRhiVulkan::allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, V VkResult poolErr = createDescriptorPool(&newPool); if (poolErr == VK_SUCCESS) { descriptorPools.append(newPool); - lastPoolIdx = descriptorPools.count() - 1; + lastPoolIdx = descriptorPools.size() - 1; VkResult err = tryAllocate(lastPoolIdx); if (err != VK_SUCCESS) { qWarning("Failed to allocate descriptor set from new pool too, giving up: %d", err); @@ -1171,18 +1187,18 @@ static void fillRenderPassCreateInfo(VkRenderPassCreateInfo *rpInfo, { memset(subpassDesc, 0, sizeof(VkSubpassDescription)); subpassDesc->pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpassDesc->colorAttachmentCount = uint32_t(rpD->colorRefs.count()); + subpassDesc->colorAttachmentCount = uint32_t(rpD->colorRefs.size()); subpassDesc->pColorAttachments = !rpD->colorRefs.isEmpty() ? rpD->colorRefs.constData() : nullptr; subpassDesc->pDepthStencilAttachment = rpD->hasDepthStencil ? &rpD->dsRef : nullptr; subpassDesc->pResolveAttachments = !rpD->resolveRefs.isEmpty() ? rpD->resolveRefs.constData() : nullptr; memset(rpInfo, 0, sizeof(VkRenderPassCreateInfo)); rpInfo->sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - rpInfo->attachmentCount = uint32_t(rpD->attDescs.count()); + rpInfo->attachmentCount = uint32_t(rpD->attDescs.size()); rpInfo->pAttachments = rpD->attDescs.constData(); rpInfo->subpassCount = 1; rpInfo->pSubpasses = subpassDesc; - rpInfo->dependencyCount = uint32_t(rpD->subpassDeps.count()); + rpInfo->dependencyCount = uint32_t(rpD->subpassDeps.size()); rpInfo->pDependencies = !rpD->subpassDeps.isEmpty() ? rpD->subpassDeps.constData() : nullptr; } @@ -1305,7 +1321,7 @@ bool QRhiVulkan::createOffscreenRenderPass(QVkRenderPassDescriptor *rpD, attDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; rpD->attDescs.append(attDesc); - const VkAttachmentReference ref = { uint32_t(rpD->attDescs.count() - 1), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; + const VkAttachmentReference ref = { uint32_t(rpD->attDescs.size() - 1), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; rpD->colorRefs.append(ref); } @@ -1329,7 +1345,7 @@ bool QRhiVulkan::createOffscreenRenderPass(QVkRenderPassDescriptor *rpD, attDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; rpD->attDescs.append(attDesc); } - rpD->dsRef = { uint32_t(rpD->attDescs.count() - 1), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; + rpD->dsRef = { uint32_t(rpD->attDescs.size() - 1), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; for (auto it = firstColorAttachment; it != lastColorAttachment; ++it) { if (it->resolveTexture()) { @@ -1361,14 +1377,14 @@ bool QRhiVulkan::createOffscreenRenderPass(QVkRenderPassDescriptor *rpD, attDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; rpD->attDescs.append(attDesc); - const VkAttachmentReference ref = { uint32_t(rpD->attDescs.count() - 1), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; + const VkAttachmentReference ref = { uint32_t(rpD->attDescs.size() - 1), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; rpD->resolveRefs.append(ref); } else { const VkAttachmentReference ref = { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; rpD->resolveRefs.append(ref); } } - Q_ASSERT(rpD->colorRefs.count() == rpD->resolveRefs.count()); + Q_ASSERT(rpD->colorRefs.size() == rpD->resolveRefs.size()); // rpD->subpassDeps stays empty: don't yet know the correct initial/final // access and stage stuff for the implicit deps at this point, so leave it @@ -1790,7 +1806,7 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin // when profiling is enabled, pick a free query (pair) from the pool int timestampQueryIdx = -1; if (hasGpuFrameTimeCallback() && swapChainD->bufferCount > 1) { // no timestamps if not having at least 2 frames in flight - for (int i = 0; i < timestampQueryPoolMap.count(); ++i) { + for (int i = 0; i < timestampQueryPoolMap.size(); ++i) { if (!timestampQueryPoolMap.testBit(i)) { timestampQueryPoolMap.setBit(i); timestampQueryIdx = i * 2; @@ -2030,7 +2046,7 @@ QRhi::FrameOpResult QRhiVulkan::endAndSubmitPrimaryCommandBuffer(VkCommandBuffer void QRhiVulkan::waitCommandCompletion(int frameSlot) { - for (QVkSwapChain *sc : qAsConst(swapchains)) { + for (QVkSwapChain *sc : std::as_const(swapchains)) { const int frameResIndex = sc->bufferCount > 1 ? frameSlot : 0; QVkSwapChain::FrameResources &frame(sc->frameRes[frameResIndex]); if (frame.cmdFenceWaitable) { @@ -2364,14 +2380,14 @@ void QRhiVulkan::beginPass(QRhiCommandBuffer *cb, float(colorClearValue.alphaF()) } }; cvs.append(cv); } - rpBeginInfo.clearValueCount = uint32_t(cvs.count()); + rpBeginInfo.clearValueCount = uint32_t(cvs.size()); QVkCommandBuffer::Command &cmd(cbD->commands.get()); cmd.cmd = QVkCommandBuffer::Command::BeginRenderPass; cmd.args.beginRenderPass.desc = rpBeginInfo; - cmd.args.beginRenderPass.clearValueIndex = cbD->pools.clearValue.count(); + cmd.args.beginRenderPass.clearValueIndex = cbD->pools.clearValue.size(); cmd.args.beginRenderPass.useSecondaryCb = cbD->passUsesSecondaryCb; - cbD->pools.clearValue.append(cvs.constData(), cvs.count()); + cbD->pools.clearValue.append(cvs.constData(), cvs.size()); if (cbD->passUsesSecondaryCb) cbD->activeSecondaryCbStack.append(startSecondaryCommandBuffer(rtD)); @@ -2502,7 +2518,7 @@ void QRhiVulkan::dispatch(QRhiCommandBuffer *cb, int x, int y, int z) accessAndIsNewFlag = { 0, false }; QVkShaderResourceBindings *srbD = QRHI_RES(QVkShaderResourceBindings, cbD->currentComputeSrb); - const int bindingCount = srbD->m_bindings.count(); + const int bindingCount = srbD->m_bindings.size(); for (int i = 0; i < bindingCount; ++i) { const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data(); switch (b->type) { @@ -2582,12 +2598,12 @@ void QRhiVulkan::dispatch(QRhiCommandBuffer *cb, int x, int y, int z) df->vkCmdPipelineBarrier(secondaryCb, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, - imageBarriers.count(), imageBarriers.constData()); + imageBarriers.size(), imageBarriers.constData()); } if (!bufferBarriers.isEmpty()) { df->vkCmdPipelineBarrier(secondaryCb, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, - bufferBarriers.count(), bufferBarriers.constData(), + bufferBarriers.size(), bufferBarriers.constData(), 0, nullptr); } df->vkCmdDispatch(secondaryCb, uint32_t(x), uint32_t(y), uint32_t(z)); @@ -2597,18 +2613,18 @@ void QRhiVulkan::dispatch(QRhiCommandBuffer *cb, int x, int y, int z) cmd.cmd = QVkCommandBuffer::Command::ImageBarrier; cmd.args.imageBarrier.srcStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; cmd.args.imageBarrier.dstStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - cmd.args.imageBarrier.count = imageBarriers.count(); - cmd.args.imageBarrier.index = cbD->pools.imageBarrier.count(); - cbD->pools.imageBarrier.append(imageBarriers.constData(), imageBarriers.count()); + cmd.args.imageBarrier.count = imageBarriers.size(); + cmd.args.imageBarrier.index = cbD->pools.imageBarrier.size(); + cbD->pools.imageBarrier.append(imageBarriers.constData(), imageBarriers.size()); } if (!bufferBarriers.isEmpty()) { QVkCommandBuffer::Command &cmd(cbD->commands.get()); cmd.cmd = QVkCommandBuffer::Command::BufferBarrier; cmd.args.bufferBarrier.srcStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; cmd.args.bufferBarrier.dstStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - cmd.args.bufferBarrier.count = bufferBarriers.count(); - cmd.args.bufferBarrier.index = cbD->pools.bufferBarrier.count(); - cbD->pools.bufferBarrier.append(bufferBarriers.constData(), bufferBarriers.count()); + cmd.args.bufferBarrier.count = bufferBarriers.size(); + cmd.args.bufferBarrier.index = cbD->pools.bufferBarrier.size(); + cbD->pools.bufferBarrier.append(bufferBarriers.constData(), bufferBarriers.size()); } QVkCommandBuffer::Command &cmd(cbD->commands.get()); cmd.cmd = QVkCommandBuffer::Command::Dispatch; @@ -2665,7 +2681,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i const bool updateAll = descSetIdx < 0; int frameSlot = updateAll ? 0 : descSetIdx; while (frameSlot < (updateAll ? QVK_FRAMES_IN_FLIGHT : descSetIdx + 1)) { - for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) { + for (int i = 0, ie = srbD->sortedBindings.size(); i != ie; ++i) { const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data(); QVkShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[frameSlot][i]); @@ -2694,7 +2710,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i bufInfo.range = VkDeviceSize(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size); // be nice and assert when we know the vulkan device would die a horrible death due to non-aligned reads Q_ASSERT(aligned(bufInfo.offset, ubufAlign) == bufInfo.offset); - bufferInfoIndex = bufferInfos.count(); + bufferInfoIndex = bufferInfos.size(); bufferInfos.append(bufInfo); } break; @@ -2716,7 +2732,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i imageInfo[elem].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } bd.stex.count = data->count; - imageInfoIndex = imageInfos.count(); + imageInfoIndex = imageInfos.size(); imageInfos.append(imageInfo); } break; @@ -2737,7 +2753,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i imageInfo[elem].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } bd.stex.count = data->count; - imageInfoIndex = imageInfos.count(); + imageInfoIndex = imageInfos.size(); imageInfos.append(imageInfo); } break; @@ -2753,7 +2769,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i imageInfo[0].sampler = samplerD->sampler; imageInfo[0].imageView = VK_NULL_HANDLE; imageInfo[0].imageLayout = VK_IMAGE_LAYOUT_GENERAL; - imageInfoIndex = imageInfos.count(); + imageInfoIndex = imageInfos.size(); imageInfos.append(imageInfo); } break; @@ -2771,7 +2787,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i imageInfo[0].sampler = VK_NULL_HANDLE; imageInfo[0].imageView = view; imageInfo[0].imageLayout = VK_IMAGE_LAYOUT_GENERAL; - imageInfoIndex = imageInfos.count(); + imageInfoIndex = imageInfos.size(); imageInfos.append(imageInfo); } } @@ -2788,7 +2804,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i bufInfo.buffer = bufD->m_type == QRhiBuffer::Dynamic ? bufD->buffers[frameSlot] : bufD->buffers[0]; bufInfo.offset = VkDeviceSize(b->u.ubuf.offset); bufInfo.range = VkDeviceSize(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size); - bufferInfoIndex = bufferInfos.count(); + bufferInfoIndex = bufferInfos.size(); bufferInfos.append(bufInfo); } break; @@ -2802,7 +2818,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i ++frameSlot; } - for (int i = 0, writeInfoCount = writeInfos.count(); i < writeInfoCount; ++i) { + for (int i = 0, writeInfoCount = writeInfos.size(); i < writeInfoCount; ++i) { const int bufferInfoIndex = infoIndices[i].first; const int imageInfoIndex = infoIndices[i].second; if (bufferInfoIndex >= 0) @@ -2811,7 +2827,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i writeInfos[i].pImageInfo = imageInfos[imageInfoIndex].constData(); } - df->vkUpdateDescriptorSets(dev, uint32_t(writeInfos.count()), writeInfos.constData(), 0, nullptr); + df->vkUpdateDescriptorSets(dev, uint32_t(writeInfos.size()), writeInfos.constData(), 0, nullptr); } static inline bool accessIsWrite(VkAccessFlags access) @@ -2858,7 +2874,7 @@ void QRhiVulkan::trackedBufferBarrier(QVkCommandBuffer *cbD, QVkBuffer *bufD, in cmd.args.bufferBarrier.srcStageMask = s.stage; cmd.args.bufferBarrier.dstStageMask = stage; cmd.args.bufferBarrier.count = 1; - cmd.args.bufferBarrier.index = cbD->pools.bufferBarrier.count(); + cmd.args.bufferBarrier.index = cbD->pools.bufferBarrier.size(); cbD->pools.bufferBarrier.append(bufMemBarrier); s.access = access; @@ -2900,7 +2916,7 @@ void QRhiVulkan::trackedImageBarrier(QVkCommandBuffer *cbD, QVkTexture *texD, cmd.args.imageBarrier.srcStageMask = srcStage; cmd.args.imageBarrier.dstStageMask = stage; cmd.args.imageBarrier.count = 1; - cmd.args.imageBarrier.index = cbD->pools.imageBarrier.count(); + cmd.args.imageBarrier.index = cbD->pools.imageBarrier.size(); cbD->pools.imageBarrier.append(barrier); s.layout = layout; @@ -2935,7 +2951,7 @@ void QRhiVulkan::depthStencilExplicitBarrier(QVkCommandBuffer *cbD, QVkRenderBuf cmd.args.imageBarrier.srcStageMask = stages; cmd.args.imageBarrier.dstStageMask = stages; cmd.args.imageBarrier.count = 1; - cmd.args.imageBarrier.index = cbD->pools.imageBarrier.count(); + cmd.args.imageBarrier.index = cbD->pools.imageBarrier.size(); cbD->pools.imageBarrier.append(barrier); } @@ -2966,7 +2982,7 @@ void QRhiVulkan::subresourceBarrier(QVkCommandBuffer *cbD, VkImage image, cmd.args.imageBarrier.srcStageMask = srcStage; cmd.args.imageBarrier.dstStageMask = dstStage; cmd.args.imageBarrier.count = 1; - cmd.args.imageBarrier.index = cbD->pools.imageBarrier.count(); + cmd.args.imageBarrier.index = cbD->pools.imageBarrier.size(); cbD->pools.imageBarrier.append(barrier); } @@ -3245,9 +3261,9 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat QVkTexture *utexD = QRHI_RES(QVkTexture, u.dst); // batch into a single staging buffer and a single CopyBufferToImage with multiple copyInfos VkDeviceSize stagingSize = 0; - for (int layer = 0, maxLayer = u.subresDesc.count(); layer < maxLayer; ++layer) { + for (int layer = 0, maxLayer = u.subresDesc.size(); layer < maxLayer; ++layer) { for (int level = 0; level < QRhi::MAX_MIP_LEVELS; ++level) { - for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level])) + for (const QRhiTextureSubresourceUploadDescription &subresDesc : std::as_const(u.subresDesc[layer][level])) stagingSize += subresUploadByteSize(subresDesc); } } @@ -3282,12 +3298,12 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat continue; } - for (int layer = 0, maxLayer = u.subresDesc.count(); layer < maxLayer; ++layer) { + for (int layer = 0, maxLayer = u.subresDesc.size(); layer < maxLayer; ++layer) { for (int level = 0; level < QRhi::MAX_MIP_LEVELS; ++level) { const QList<QRhiTextureSubresourceUploadDescription> &srd(u.subresDesc[layer][level]); if (srd.isEmpty()) continue; - for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(srd)) { + for (const QRhiTextureSubresourceUploadDescription &subresDesc : std::as_const(srd)) { prepareUploadSubres(utexD, layer, level, subresDesc, &curOfs, mp, ©Infos); } @@ -3304,9 +3320,9 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat cmd.args.copyBufferToImage.src = utexD->stagingBuffers[currentFrameSlot]; cmd.args.copyBufferToImage.dst = utexD->image; cmd.args.copyBufferToImage.dstLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - cmd.args.copyBufferToImage.count = copyInfos.count(); - cmd.args.copyBufferToImage.bufferImageCopyIndex = cbD->pools.bufferImageCopy.count(); - cbD->pools.bufferImageCopy.append(copyInfos.constData(), copyInfos.count()); + cmd.args.copyBufferToImage.count = copyInfos.size(); + cmd.args.copyBufferToImage.bufferImageCopyIndex = cbD->pools.bufferImageCopy.size(); + cbD->pools.bufferImageCopy.append(copyInfos.constData(), copyInfos.size()); // no reuse of staging, this is intentional QRhiVulkan::DeferredReleaseEntry e; @@ -3597,7 +3613,7 @@ void QRhiVulkan::executeBufferHostWritesForSlot(QVkBuffer *bufD, int slot) } int changeBegin = -1; int changeEnd = -1; - for (const QVkBuffer::DynamicUpdate &u : qAsConst(bufD->pendingDynamicUpdates[slot])) { + for (const QVkBuffer::DynamicUpdate &u : std::as_const(bufD->pendingDynamicUpdates[slot])) { memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), size_t(u.data.size())); if (changeBegin == -1 || u.offset < changeBegin) changeBegin = u.offset; @@ -3645,7 +3661,7 @@ static void qrhivk_releaseSampler(const QRhiVulkan::DeferredReleaseEntry &e, VkD void QRhiVulkan::executeDeferredReleases(bool forced) { - for (int i = releaseQueue.count() - 1; i >= 0; --i) { + for (int i = releaseQueue.size() - 1; i >= 0; --i) { const QRhiVulkan::DeferredReleaseEntry &e(releaseQueue[i]); if (forced || currentFrameSlot == e.lastActiveFrameSlot || e.lastActiveFrameSlot < 0) { switch (e.type) { @@ -3701,7 +3717,7 @@ void QRhiVulkan::finishActiveReadbacks(bool forced) { QVarLengthArray<std::function<void()>, 4> completedCallbacks; - for (int i = activeTextureReadbacks.count() - 1; i >= 0; --i) { + for (int i = activeTextureReadbacks.size() - 1; i >= 0; --i) { const QRhiVulkan::TextureReadback &readback(activeTextureReadbacks[i]); if (forced || currentFrameSlot == readback.activeFrameSlot || readback.activeFrameSlot < 0) { readback.result->format = readback.format; @@ -3726,7 +3742,7 @@ void QRhiVulkan::finishActiveReadbacks(bool forced) } } - for (int i = activeBufferReadbacks.count() - 1; i >= 0; --i) { + for (int i = activeBufferReadbacks.size() - 1; i >= 0; --i) { const QRhiVulkan::BufferReadback &readback(activeBufferReadbacks[i]); if (forced || currentFrameSlot == readback.activeFrameSlot || readback.activeFrameSlot < 0) { VmaAllocation a = toVmaAllocation(readback.stagingAlloc); @@ -3809,11 +3825,11 @@ VkSampleCountFlagBits QRhiVulkan::effectiveSampleCount(int sampleCount) void QRhiVulkan::enqueueTransitionPassResources(QVkCommandBuffer *cbD) { cbD->passResTrackers.append(QRhiPassResourceTracker()); - cbD->currentPassResTrackerIndex = cbD->passResTrackers.count() - 1; + cbD->currentPassResTrackerIndex = cbD->passResTrackers.size() - 1; QVkCommandBuffer::Command &cmd(cbD->commands.get()); cmd.cmd = QVkCommandBuffer::Command::TransitionPassResources; - cmd.args.transitionResources.trackerIndex = cbD->passResTrackers.count() - 1; + cmd.args.transitionResources.trackerIndex = cbD->passResTrackers.size() - 1; } void QRhiVulkan::recordPrimaryCommandBuffer(QVkCommandBuffer *cbD) @@ -4617,7 +4633,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin // Do host writes and mark referenced shader resources as in-use. // Also prepare to ensure the descriptor set we are going to bind refers to up-to-date Vk objects. - for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) { + for (int i = 0, ie = srbD->sortedBindings.size(); i != ie; ++i) { const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings[i].data(); QVkShaderResourceBindings::BoundResourceData &bd(descSetBd[i]); switch (b->type) { @@ -4764,7 +4780,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin // because dynOfs has to be ordered based on the binding numbers, // and neither srb nor dynamicOffsets has any such ordering // requirement. - for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) { + for (const QRhiShaderResourceBinding &binding : std::as_const(srbD->sortedBindings)) { const QRhiShaderResourceBinding::Data *b = binding.data(); if (b->type == QRhiShaderResourceBinding::UniformBuffer && b->u.ubuf.hasDynamicOffset) { uint32_t offset = 0; @@ -4785,8 +4801,8 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin gfxPsD ? VK_PIPELINE_BIND_POINT_GRAPHICS : VK_PIPELINE_BIND_POINT_COMPUTE, gfxPsD ? gfxPsD->layout : compPsD->layout, 0, 1, &srbD->descSets[descSetIdx], - uint32_t(dynOfs.count()), - dynOfs.count() ? dynOfs.constData() : nullptr); + uint32_t(dynOfs.size()), + dynOfs.size() ? dynOfs.constData() : nullptr); } else { QVkCommandBuffer::Command &cmd(cbD->commands.get()); cmd.cmd = QVkCommandBuffer::Command::BindDescriptorSet; @@ -4794,9 +4810,9 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin : VK_PIPELINE_BIND_POINT_COMPUTE; cmd.args.bindDescriptorSet.pipelineLayout = gfxPsD ? gfxPsD->layout : compPsD->layout; cmd.args.bindDescriptorSet.descSet = srbD->descSets[descSetIdx]; - cmd.args.bindDescriptorSet.dynamicOffsetCount = dynOfs.count(); - cmd.args.bindDescriptorSet.dynamicOffsetIndex = cbD->pools.dynamicOffset.count(); - cbD->pools.dynamicOffset.append(dynOfs.constData(), dynOfs.count()); + cmd.args.bindDescriptorSet.dynamicOffsetCount = dynOfs.size(); + cmd.args.bindDescriptorSet.dynamicOffsetIndex = cbD->pools.dynamicOffset.size(); + cbD->pools.dynamicOffset.append(dynOfs.constData(), dynOfs.size()); } if (gfxPsD) { @@ -4855,16 +4871,16 @@ void QRhiVulkan::setVertexInput(QRhiCommandBuffer *cb, if (cbD->passUsesSecondaryCb) { df->vkCmdBindVertexBuffers(cbD->activeSecondaryCbStack.last(), uint32_t(startBinding), - uint32_t(bufs.count()), bufs.constData(), ofs.constData()); + uint32_t(bufs.size()), bufs.constData(), ofs.constData()); } else { QVkCommandBuffer::Command &cmd(cbD->commands.get()); cmd.cmd = QVkCommandBuffer::Command::BindVertexBuffer; cmd.args.bindVertexBuffer.startBinding = startBinding; - cmd.args.bindVertexBuffer.count = bufs.count(); - cmd.args.bindVertexBuffer.vertexBufferIndex = cbD->pools.vertexBuffer.count(); - cbD->pools.vertexBuffer.append(bufs.constData(), bufs.count()); - cmd.args.bindVertexBuffer.vertexBufferOffsetIndex = cbD->pools.vertexBufferOffset.count(); - cbD->pools.vertexBufferOffset.append(ofs.constData(), ofs.count()); + cmd.args.bindVertexBuffer.count = bufs.size(); + cmd.args.bindVertexBuffer.vertexBufferIndex = cbD->pools.vertexBuffer.size(); + cbD->pools.vertexBuffer.append(bufs.constData(), bufs.size()); + cmd.args.bindVertexBuffer.vertexBufferOffsetIndex = cbD->pools.vertexBufferOffset.size(); + cbD->pools.vertexBufferOffset.append(ofs.constData(), ofs.size()); } } @@ -4913,7 +4929,7 @@ void QRhiVulkan::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport // x,y is top-left in VkViewport but bottom-left in QRhiViewport float x, y, w, h; - if (!qrhi_toTopLeftRenderTargetRect(outputSize, viewport.viewport(), &x, &y, &w, &h)) + if (!qrhi_toTopLeftRenderTargetRect<UnBounded>(outputSize, viewport.viewport(), &x, &y, &w, &h)) return; QVkCommandBuffer::Command &cmd(cbD->commands.get()); @@ -4935,6 +4951,7 @@ void QRhiVulkan::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport if (!QRHI_RES(QVkGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) { QVkCommandBuffer::Command &cmd(cbD->commands.get()); VkRect2D *s = &cmd.args.setScissor.scissor; + qrhi_toTopLeftRenderTargetRect<Bounded>(outputSize, viewport.viewport(), &x, &y, &w, &h); s->offset.x = int32_t(x); s->offset.y = int32_t(y); s->extent.width = uint32_t(w); @@ -4957,7 +4974,7 @@ void QRhiVulkan::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) // x,y is top-left in VkRect2D but bottom-left in QRhiScissor int x, y, w, h; - if (!qrhi_toTopLeftRenderTargetRect(outputSize, scissor.scissor(), &x, &y, &w, &h)) + if (!qrhi_toTopLeftRenderTargetRect<Bounded>(outputSize, scissor.scissor(), &x, &y, &w, &h)) return; QVkCommandBuffer::Command &cmd(cbD->commands.get()); @@ -5062,7 +5079,7 @@ void QRhiVulkan::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) QVkCommandBuffer::Command &cmd(cbD->commands.get()); cmd.cmd = QVkCommandBuffer::Command::DebugMarkerBegin; cmd.args.debugMarkerBegin.marker = marker; - cmd.args.debugMarkerBegin.markerNameIndex = cbD->pools.debugMarkerData.count(); + cmd.args.debugMarkerBegin.markerNameIndex = cbD->pools.debugMarkerData.size(); cbD->pools.debugMarkerData.append(name); } } @@ -5098,7 +5115,7 @@ void QRhiVulkan::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) QVkCommandBuffer::Command &cmd(cbD->commands.get()); cmd.cmd = QVkCommandBuffer::Command::DebugMarkerInsert; cmd.args.debugMarkerInsert.marker = marker; - cmd.args.debugMarkerInsert.markerNameIndex = cbD->pools.debugMarkerData.count(); + cmd.args.debugMarkerInsert.markerNameIndex = cbD->pools.debugMarkerData.size(); cbD->pools.debugMarkerData.append(msg); } } @@ -6304,16 +6321,16 @@ bool QVkRenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other const QVkRenderPassDescriptor *o = QRHI_RES(const QVkRenderPassDescriptor, other); - if (attDescs.count() != o->attDescs.count()) + if (attDescs.size() != o->attDescs.size()) return false; - if (colorRefs.count() != o->colorRefs.count()) + if (colorRefs.size() != o->colorRefs.size()) return false; - if (resolveRefs.count() != o->resolveRefs.count()) + if (resolveRefs.size() != o->resolveRefs.size()) return false; if (hasDepthStencil != o->hasDepthStencil) return false; - for (int i = 0, ie = colorRefs.count(); i != ie; ++i) { + for (int i = 0, ie = colorRefs.size(); i != ie; ++i) { const uint32_t attIdx = colorRefs[i].attachment; if (attIdx != o->colorRefs[i].attachment) return false; @@ -6329,7 +6346,7 @@ bool QVkRenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other return false; } - for (int i = 0, ie = resolveRefs.count(); i != ie; ++i) { + for (int i = 0, ie = resolveRefs.size(); i != ie; ++i) { const uint32_t attIdx = resolveRefs[i].attachment; if (attIdx != o->resolveRefs[i].attachment) return false; @@ -6347,9 +6364,9 @@ void QVkRenderPassDescriptor::updateSerializedFormat() serializedFormatData.clear(); auto p = std::back_inserter(serializedFormatData); - *p++ = attDescs.count(); - *p++ = colorRefs.count(); - *p++ = resolveRefs.count(); + *p++ = attDescs.size(); + *p++ = colorRefs.size(); + *p++ = resolveRefs.size(); *p++ = hasDepthStencil; auto serializeAttachmentData = [this, &p](uint32_t attIdx) { @@ -6365,7 +6382,7 @@ void QVkRenderPassDescriptor::updateSerializedFormat() *p++ = used ? a->finalLayout : 0; }; - for (int i = 0, ie = colorRefs.count(); i != ie; ++i) { + for (int i = 0, ie = colorRefs.size(); i != ie; ++i) { const uint32_t attIdx = colorRefs[i].attachment; *p++ = attIdx; serializeAttachmentData(attIdx); @@ -6377,7 +6394,7 @@ void QVkRenderPassDescriptor::updateSerializedFormat() serializeAttachmentData(attIdx); } - for (int i = 0, ie = resolveRefs.count(); i != ie; ++i) { + for (int i = 0, ie = resolveRefs.size(); i != ie; ++i) { const uint32_t attIdx = resolveRefs[i].attachment; *p++ = attIdx; serializeAttachmentData(attIdx); @@ -6738,7 +6755,7 @@ bool QVkShaderResourceBindings::create() hasSlottedResource = false; hasDynamicOffset = false; - for (const QRhiShaderResourceBinding &binding : qAsConst(sortedBindings)) { + for (const QRhiShaderResourceBinding &binding : std::as_const(sortedBindings)) { const QRhiShaderResourceBinding::Data *b = binding.data(); if (b->type == QRhiShaderResourceBinding::UniformBuffer && b->u.ubuf.buf) { if (QRHI_RES(QVkBuffer, b->u.ubuf.buf)->type() == QRhiBuffer::Dynamic) @@ -6749,7 +6766,7 @@ bool QVkShaderResourceBindings::create() } QVarLengthArray<VkDescriptorSetLayoutBinding, 4> vkbindings; - for (const QRhiShaderResourceBinding &binding : qAsConst(sortedBindings)) { + for (const QRhiShaderResourceBinding &binding : std::as_const(sortedBindings)) { const QRhiShaderResourceBinding::Data *b = binding.data(); VkDescriptorSetLayoutBinding vkbinding; memset(&vkbinding, 0, sizeof(vkbinding)); @@ -6766,7 +6783,7 @@ bool QVkShaderResourceBindings::create() VkDescriptorSetLayoutCreateInfo layoutInfo; memset(&layoutInfo, 0, sizeof(layoutInfo)); layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layoutInfo.bindingCount = uint32_t(vkbindings.count()); + layoutInfo.bindingCount = uint32_t(vkbindings.size()); layoutInfo.pBindings = vkbindings.constData(); VkResult err = rhiD->df->vkCreateDescriptorSetLayout(rhiD->dev, &layoutInfo, nullptr, &layout); @@ -6787,7 +6804,7 @@ bool QVkShaderResourceBindings::create() return false; for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i) { - boundResourceData[i].resize(sortedBindings.count()); + boundResourceData[i].resize(sortedBindings.size()); for (BoundResourceData &bd : boundResourceData[i]) memset(&bd, 0, sizeof(BoundResourceData)); } @@ -6820,7 +6837,7 @@ void QVkShaderResourceBindings::updateResources(UpdateFlags flags) // complicating the checks in setShaderResources(), reset the table here // just like we do in create(). for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i) { - Q_ASSERT(boundResourceData[i].count() == sortedBindings.count()); + Q_ASSERT(boundResourceData[i].size() == sortedBindings.size()); for (BoundResourceData &bd : boundResourceData[i]) memset(&bd, 0, sizeof(BoundResourceData)); } @@ -6910,7 +6927,7 @@ bool QVkGraphicsPipeline::create() shaderStageCreateInfos.append(shaderInfo); } } - pipelineInfo.stageCount = uint32_t(shaderStageCreateInfos.count()); + pipelineInfo.stageCount = uint32_t(shaderStageCreateInfos.size()); pipelineInfo.pStages = shaderStageCreateInfos.constData(); QVarLengthArray<VkVertexInputBindingDescription, 4> vertexBindings; @@ -6951,15 +6968,15 @@ bool QVkGraphicsPipeline::create() VkPipelineVertexInputStateCreateInfo vertexInputInfo; memset(&vertexInputInfo, 0, sizeof(vertexInputInfo)); vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertexInputInfo.vertexBindingDescriptionCount = uint32_t(vertexBindings.count()); + vertexInputInfo.vertexBindingDescriptionCount = uint32_t(vertexBindings.size()); vertexInputInfo.pVertexBindingDescriptions = vertexBindings.constData(); - vertexInputInfo.vertexAttributeDescriptionCount = uint32_t(vertexAttributes.count()); + vertexInputInfo.vertexAttributeDescriptionCount = uint32_t(vertexAttributes.size()); vertexInputInfo.pVertexAttributeDescriptions = vertexAttributes.constData(); VkPipelineVertexInputDivisorStateCreateInfoEXT divisorInfo; if (!nonOneStepRates.isEmpty()) { memset(&divisorInfo, 0, sizeof(divisorInfo)); divisorInfo.sType = VkStructureType(1000190001); // VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT - divisorInfo.vertexBindingDivisorCount = uint32_t(nonOneStepRates.count()); + divisorInfo.vertexBindingDivisorCount = uint32_t(nonOneStepRates.size()); divisorInfo.pVertexBindingDivisors = nonOneStepRates.constData(); vertexInputInfo.pNext = &divisorInfo; } @@ -6976,7 +6993,7 @@ bool QVkGraphicsPipeline::create() VkPipelineDynamicStateCreateInfo dynamicInfo; memset(&dynamicInfo, 0, sizeof(dynamicInfo)); dynamicInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamicInfo.dynamicStateCount = uint32_t(dynEnable.count()); + dynamicInfo.dynamicStateCount = uint32_t(dynEnable.size()); dynamicInfo.pDynamicStates = dynEnable.constData(); pipelineInfo.pDynamicState = &dynamicInfo; @@ -7064,7 +7081,7 @@ bool QVkGraphicsPipeline::create() memset(&blendInfo, 0, sizeof(blendInfo)); blendInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; QVarLengthArray<VkPipelineColorBlendAttachmentState, 4> vktargetBlends; - for (const QRhiGraphicsPipeline::TargetBlend &b : qAsConst(m_targetBlends)) { + for (const QRhiGraphicsPipeline::TargetBlend &b : std::as_const(m_targetBlends)) { VkPipelineColorBlendAttachmentState blend; memset(&blend, 0, sizeof(blend)); blend.blendEnable = b.enable; @@ -7084,7 +7101,7 @@ bool QVkGraphicsPipeline::create() | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; vktargetBlends.append(blend); } - blendInfo.attachmentCount = uint32_t(vktargetBlends.count()); + blendInfo.attachmentCount = uint32_t(vktargetBlends.size()); blendInfo.pAttachments = vktargetBlends.constData(); pipelineInfo.pColorBlendState = &blendInfo; diff --git a/src/gui/rhi/qshader.cpp b/src/gui/rhi/qshader.cpp index 1992708ba4..7fc327c5c3 100644 --- a/src/gui/rhi/qshader.cpp +++ b/src/gui/rhi/qshader.cpp @@ -335,7 +335,7 @@ QByteArray QShader::serialized() const ds << QShaderPrivate::QSB_VERSION; ds << int(d->stage); d->desc.serialize(&ds); - ds << int(d->shaders.count()); + ds << int(d->shaders.size()); for (auto it = d->shaders.cbegin(), itEnd = d->shaders.cend(); it != itEnd; ++it) { const QShaderKey &k(it.key()); writeShaderKey(&ds, k); @@ -343,24 +343,24 @@ QByteArray QShader::serialized() const ds << shader.shader(); ds << shader.entryPoint(); } - ds << int(d->bindings.count()); + ds << int(d->bindings.size()); for (auto it = d->bindings.cbegin(), itEnd = d->bindings.cend(); it != itEnd; ++it) { const QShaderKey &k(it.key()); writeShaderKey(&ds, k); const NativeResourceBindingMap &map(it.value()); - ds << int(map.count()); + ds << int(map.size()); for (auto mapIt = map.cbegin(), mapItEnd = map.cend(); mapIt != mapItEnd; ++mapIt) { ds << mapIt.key(); ds << mapIt.value().first; ds << mapIt.value().second; } } - ds << int(d->combinedImageMap.count()); + ds << int(d->combinedImageMap.size()); for (auto it = d->combinedImageMap.cbegin(), itEnd = d->combinedImageMap.cend(); it != itEnd; ++it) { const QShaderKey &k(it.key()); writeShaderKey(&ds, k); const SeparateToCombinedImageSamplerMappingList &list(it.value()); - ds << int(list.count()); + ds << int(list.size()); for (auto listIt = list.cbegin(), listItEnd = list.cend(); listIt != listItEnd; ++listIt) { ds << listIt->combinedSamplerName; ds << listIt->textureBinding; @@ -516,8 +516,8 @@ QShaderKey::QShaderKey(QShader::Source s, bool operator==(const QShader &lhs, const QShader &rhs) noexcept { return lhs.d->stage == rhs.d->stage - && lhs.d->shaders == rhs.d->shaders; - // do not bother with desc and bindings, if the shader code is the same, the description must match too + && lhs.d->shaders == rhs.d->shaders + && lhs.d->bindings == rhs.d->bindings; } /*! diff --git a/src/gui/rhi/qshaderdescription.cpp b/src/gui/rhi/qshaderdescription.cpp index d55caed210..90cfc2e298 100644 --- a/src/gui/rhi/qshaderdescription.cpp +++ b/src/gui/rhi/qshaderdescription.cpp @@ -829,7 +829,7 @@ static void serializeDecorations(QDataStream *stream, const QShaderDescription:: (*stream) << v.descriptorSet; (*stream) << int(v.imageFormat); (*stream) << int(v.imageFlags); - (*stream) << int(v.arrayDims.count()); + (*stream) << int(v.arrayDims.size()); for (int dim : v.arrayDims) (*stream) << dim; } @@ -884,13 +884,13 @@ static void serializeBlockMemberVar(QDataStream *stream, const QShaderDescriptio (*stream) << int(v.type); (*stream) << v.offset; (*stream) << v.size; - (*stream) << int(v.arrayDims.count()); + (*stream) << int(v.arrayDims.size()); for (int dim : v.arrayDims) (*stream) << dim; (*stream) << v.arrayStride; (*stream) << v.matrixStride; (*stream) << v.matrixIsRowMajor; - (*stream) << int(v.structMembers.count()); + (*stream) << int(v.structMembers.size()); for (const QShaderDescription::BlockVariable &sv : v.structMembers) serializeBlockMemberVar(stream, sv); } @@ -900,13 +900,13 @@ QJsonDocument QShaderDescriptionPrivate::makeDoc() QJsonObject root; QJsonArray jinputs; - for (const QShaderDescription::InOutVariable &v : qAsConst(inVars)) + for (const QShaderDescription::InOutVariable &v : std::as_const(inVars)) jinputs.append(inOutObject(v)); if (!jinputs.isEmpty()) root[inputsKey()] = jinputs; QJsonArray joutputs; - for (const QShaderDescription::InOutVariable &v : qAsConst(outVars)) + for (const QShaderDescription::InOutVariable &v : std::as_const(outVars)) joutputs.append(inOutObject(v)); if (!joutputs.isEmpty()) root[outputsKey()] = joutputs; @@ -964,7 +964,7 @@ QJsonDocument QShaderDescriptionPrivate::makeDoc() root[storageBlocksKey()] = jstorageBlocks; QJsonArray jcombinedSamplers; - for (const QShaderDescription::InOutVariable &v : qAsConst(combinedImageSamplers)) { + for (const QShaderDescription::InOutVariable &v : std::as_const(combinedImageSamplers)) { QJsonObject sampler; sampler[nameKey()] = QString::fromUtf8(v.name); sampler[typeKey()] = typeStr(v.type); @@ -975,7 +975,7 @@ QJsonDocument QShaderDescriptionPrivate::makeDoc() root[combinedImageSamplersKey()] = jcombinedSamplers; QJsonArray jstorageImages; - for (const QShaderDescription::InOutVariable &v : qAsConst(storageImages)) { + for (const QShaderDescription::InOutVariable &v : std::as_const(storageImages)) { QJsonObject image; image[nameKey()] = QString::fromUtf8(v.name); image[typeKey()] = typeStr(v.type); @@ -991,7 +991,7 @@ QJsonDocument QShaderDescriptionPrivate::makeDoc() root[localSizeKey()] = jlocalSize; QJsonArray jseparateImages; - for (const QShaderDescription::InOutVariable &v : qAsConst(separateImages)) { + for (const QShaderDescription::InOutVariable &v : std::as_const(separateImages)) { QJsonObject image; image[nameKey()] = QString::fromUtf8(v.name); image[typeKey()] = typeStr(v.type); @@ -1002,7 +1002,7 @@ QJsonDocument QShaderDescriptionPrivate::makeDoc() root[separateImagesKey()] = jseparateImages; QJsonArray jseparateSamplers; - for (const QShaderDescription::InOutVariable &v : qAsConst(separateSamplers)) { + for (const QShaderDescription::InOutVariable &v : std::as_const(separateSamplers)) { QJsonObject sampler; sampler[nameKey()] = QString::fromUtf8(v.name); sampler[typeKey()] = typeStr(v.type); @@ -1017,56 +1017,56 @@ QJsonDocument QShaderDescriptionPrivate::makeDoc() void QShaderDescriptionPrivate::writeToStream(QDataStream *stream) { - (*stream) << int(inVars.count()); - for (const QShaderDescription::InOutVariable &v : qAsConst(inVars)) + (*stream) << int(inVars.size()); + for (const QShaderDescription::InOutVariable &v : std::as_const(inVars)) serializeInOutVar(stream, v); - (*stream) << int(outVars.count()); - for (const QShaderDescription::InOutVariable &v : qAsConst(outVars)) + (*stream) << int(outVars.size()); + for (const QShaderDescription::InOutVariable &v : std::as_const(outVars)) serializeInOutVar(stream, v); - (*stream) << int(uniformBlocks.count()); + (*stream) << int(uniformBlocks.size()); for (const QShaderDescription::UniformBlock &b : uniformBlocks) { (*stream) << QString::fromUtf8(b.blockName); (*stream) << QString::fromUtf8(b.structName); (*stream) << b.size; (*stream) << b.binding; (*stream) << b.descriptorSet; - (*stream) << int(b.members.count()); + (*stream) << int(b.members.size()); for (const QShaderDescription::BlockVariable &v : b.members) serializeBlockMemberVar(stream, v); } - (*stream) << int(pushConstantBlocks.count()); + (*stream) << int(pushConstantBlocks.size()); for (const QShaderDescription::PushConstantBlock &b : pushConstantBlocks) { (*stream) << QString::fromUtf8(b.name); (*stream) << b.size; - (*stream) << int(b.members.count()); + (*stream) << int(b.members.size()); for (const QShaderDescription::BlockVariable &v : b.members) serializeBlockMemberVar(stream, v); } - (*stream) << int(storageBlocks.count()); + (*stream) << int(storageBlocks.size()); for (const QShaderDescription::StorageBlock &b : storageBlocks) { (*stream) << QString::fromUtf8(b.blockName); (*stream) << QString::fromUtf8(b.instanceName); (*stream) << b.knownSize; (*stream) << b.binding; (*stream) << b.descriptorSet; - (*stream) << int(b.members.count()); + (*stream) << int(b.members.size()); for (const QShaderDescription::BlockVariable &v : b.members) serializeBlockMemberVar(stream, v); } - (*stream) << int(combinedImageSamplers.count()); - for (const QShaderDescription::InOutVariable &v : qAsConst(combinedImageSamplers)) { + (*stream) << int(combinedImageSamplers.size()); + for (const QShaderDescription::InOutVariable &v : std::as_const(combinedImageSamplers)) { (*stream) << QString::fromUtf8(v.name); (*stream) << int(v.type); serializeDecorations(stream, v); } - (*stream) << int(storageImages.count()); - for (const QShaderDescription::InOutVariable &v : qAsConst(storageImages)) { + (*stream) << int(storageImages.size()); + for (const QShaderDescription::InOutVariable &v : std::as_const(storageImages)) { (*stream) << QString::fromUtf8(v.name); (*stream) << int(v.type); serializeDecorations(stream, v); @@ -1075,15 +1075,15 @@ void QShaderDescriptionPrivate::writeToStream(QDataStream *stream) for (size_t i = 0; i < 3; ++i) (*stream) << localSize[i]; - (*stream) << int(separateImages.count()); - for (const QShaderDescription::InOutVariable &v : qAsConst(separateImages)) { + (*stream) << int(separateImages.size()); + for (const QShaderDescription::InOutVariable &v : std::as_const(separateImages)) { (*stream) << QString::fromUtf8(v.name); (*stream) << int(v.type); serializeDecorations(stream, v); } - (*stream) << int(separateSamplers.count()); - for (const QShaderDescription::InOutVariable &v : qAsConst(separateSamplers)) { + (*stream) << int(separateSamplers.size()); + for (const QShaderDescription::InOutVariable &v : std::as_const(separateSamplers)) { (*stream) << QString::fromUtf8(v.name); (*stream) << int(v.type); serializeDecorations(stream, v); diff --git a/src/gui/rhi/vs_test_p.h b/src/gui/rhi/vs_test_p.h index e24472cd95..5feaef7d38 100644 --- a/src/gui/rhi/vs_test_p.h +++ b/src/gui/rhi/vs_test_p.h @@ -76,7 +76,7 @@ ret // Approximately 6 instruction slots used #endif -const BYTE g_testVertexShader[] = +inline constexpr BYTE g_testVertexShader[] = { 68, 88, 66, 67, 75, 198, 18, 149, 172, 244, 247, 123, |