QtBase  v6.3.1
qrhi.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2019 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Gui module
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qrhi_p_p.h"
41 #include <qmath.h>
42 #include <QLoggingCategory>
43 
44 #include "qrhinull_p_p.h"
45 #ifndef QT_NO_OPENGL
46 #include "qrhigles2_p_p.h"
47 #endif
48 #if QT_CONFIG(vulkan)
49 #include "qrhivulkan_p_p.h"
50 #endif
51 #ifdef Q_OS_WIN
52 #include "qrhid3d11_p_p.h"
53 #endif
54 #if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
55 #include "qrhimetal_p_p.h"
56 #endif
57 
58 #include <memory>
59 
61 
62 Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
63 
64 
830  : m_d(d),
831  m_s(s)
832 {
833 }
834 
842 {
843  return a.depthClearValue() == b.depthClearValue()
844  && a.stencilClearValue() == b.stencilClearValue();
845 }
846 
854 {
855  return !(a == b);
856 }
857 
863 size_t qHash(const QRhiDepthStencilClearValue &v, size_t seed) noexcept
864 {
865  return seed * (uint(qFloor(qreal(v.depthClearValue()) * 100)) + v.stencilClearValue());
866 }
867 
868 #ifndef QT_NO_DEBUG_STREAM
870 {
871  QDebugStateSaver saver(dbg);
872  dbg.nospace() << "QRhiDepthStencilClearValue(depth-clear=" << v.depthClearValue()
873  << " stencil-clear=" << v.stencilClearValue()
874  << ')';
875  return dbg;
876 }
877 #endif
878 
923 QRhiViewport::QRhiViewport(float x, float y, float w, float h, float minDepth, float maxDepth)
924  : m_rect { { x, y, w, h } },
925  m_minDepth(minDepth),
926  m_maxDepth(maxDepth)
927 {
928 }
929 
936 bool operator==(const QRhiViewport &a, const QRhiViewport &b) noexcept
937 {
938  return a.viewport() == b.viewport()
939  && a.minDepth() == b.minDepth()
940  && a.maxDepth() == b.maxDepth();
941 }
942 
949 bool operator!=(const QRhiViewport &a, const QRhiViewport &b) noexcept
950 {
951  return !(a == b);
952 }
953 
959 size_t qHash(const QRhiViewport &v, size_t seed) noexcept
960 {
961  const std::array<float, 4> r = v.viewport();
962  return seed + uint(r[0]) + uint(r[1]) + uint(r[2]) + uint(r[3])
963  + uint(qFloor(qreal(v.minDepth()) * 100)) + uint(qFloor(qreal(v.maxDepth()) * 100));
964 }
965 
966 #ifndef QT_NO_DEBUG_STREAM
968 {
969  QDebugStateSaver saver(dbg);
970  const std::array<float, 4> r = v.viewport();
971  dbg.nospace() << "QRhiViewport(bottom-left-x=" << r[0]
972  << " bottom-left-y=" << r[1]
973  << " width=" << r[2]
974  << " height=" << r[3]
975  << " minDepth=" << v.minDepth()
976  << " maxDepth=" << v.maxDepth()
977  << ')';
978  return dbg;
979 }
980 #endif
981 
1018 QRhiScissor::QRhiScissor(int x, int y, int w, int h)
1019  : m_rect { { x, y, w, h } }
1020 {
1021 }
1022 
1029 bool operator==(const QRhiScissor &a, const QRhiScissor &b) noexcept
1030 {
1031  return a.scissor() == b.scissor();
1032 }
1033 
1040 bool operator!=(const QRhiScissor &a, const QRhiScissor &b) noexcept
1041 {
1042  return !(a == b);
1043 }
1044 
1050 size_t qHash(const QRhiScissor &v, size_t seed) noexcept
1051 {
1052  const std::array<int, 4> r = v.scissor();
1053  return seed + uint(r[0]) + uint(r[1]) + uint(r[2]) + uint(r[3]);
1054 }
1055 
1056 #ifndef QT_NO_DEBUG_STREAM
1058 {
1059  QDebugStateSaver saver(dbg);
1060  const std::array<int, 4> r = s.scissor();
1061  dbg.nospace() << "QRhiScissor(bottom-left-x=" << r[0]
1062  << " bottom-left-y=" << r[1]
1063  << " width=" << r[2]
1064  << " height=" << r[3]
1065  << ')';
1066  return dbg;
1067 }
1068 #endif
1069 
1149  : m_stride(stride),
1150  m_classification(cls),
1151  m_instanceStepRate(stepRate)
1152 {
1153 }
1154 
1162 {
1163  return a.stride() == b.stride()
1164  && a.classification() == b.classification()
1165  && a.instanceStepRate() == b.instanceStepRate();
1166 }
1167 
1175 {
1176  return !(a == b);
1177 }
1178 
1184 size_t qHash(const QRhiVertexInputBinding &v, size_t seed) noexcept
1185 {
1186  return seed + v.stride() + v.classification();
1187 }
1188 
1189 #ifndef QT_NO_DEBUG_STREAM
1191 {
1192  QDebugStateSaver saver(dbg);
1193  dbg.nospace() << "QRhiVertexInputBinding(stride=" << b.stride()
1194  << " cls=" << b.classification()
1195  << " step-rate=" << b.instanceStepRate()
1196  << ')';
1197  return dbg;
1198 }
1199 #endif
1200 
1314  : m_binding(binding),
1315  m_location(location),
1316  m_format(format),
1317  m_offset(offset),
1318  m_matrixSlice(matrixSlice)
1319 {
1320 }
1321 
1329 {
1330  return a.binding() == b.binding()
1331  && a.location() == b.location()
1332  && a.format() == b.format()
1333  && a.offset() == b.offset();
1334 }
1335 
1343 {
1344  return !(a == b);
1345 }
1346 
1352 size_t qHash(const QRhiVertexInputAttribute &v, size_t seed) noexcept
1353 {
1354  return seed + uint(v.binding()) + uint(v.location()) + uint(v.format()) + v.offset();
1355 }
1356 
1357 #ifndef QT_NO_DEBUG_STREAM
1359 {
1360  QDebugStateSaver saver(dbg);
1361  dbg.nospace() << "QRhiVertexInputAttribute(binding=" << a.binding()
1362  << " location=" << a.location()
1363  << " format=" << a.format()
1364  << " offset=" << a.offset()
1365  << ')';
1366  return dbg;
1367 }
1368 #endif
1369 
1393 {
1394  return a.m_bindings == b.m_bindings && a.m_attributes == b.m_attributes;
1395 }
1396 
1404 {
1405  return !(a == b);
1406 }
1407 
1413 size_t qHash(const QRhiVertexInputLayout &v, size_t seed) noexcept
1414 {
1415  return qHash(v.m_bindings, seed) + qHash(v.m_attributes, seed);
1416 }
1417 
1418 #ifndef QT_NO_DEBUG_STREAM
1420 {
1421  QDebugStateSaver saver(dbg);
1422  dbg.nospace() << "QRhiVertexInputLayout(bindings=" << v.m_bindings
1423  << " attributes=" << v.m_attributes
1424  << ')';
1425  return dbg;
1426 }
1427 #endif
1428 
1462  : m_type(type),
1463  m_shader(shader),
1464  m_shaderVariant(v)
1465 {
1466 }
1467 
1474 bool operator==(const QRhiShaderStage &a, const QRhiShaderStage &b) noexcept
1475 {
1476  return a.type() == b.type()
1477  && a.shader() == b.shader()
1478  && a.shaderVariant() == b.shaderVariant();
1479 }
1480 
1487 bool operator!=(const QRhiShaderStage &a, const QRhiShaderStage &b) noexcept
1488 {
1489  return !(a == b);
1490 }
1491 
1497 size_t qHash(const QRhiShaderStage &v, size_t seed) noexcept
1498 {
1499  return v.type() + qHash(v.shader(), seed) + v.shaderVariant();
1500 }
1501 
1502 #ifndef QT_NO_DEBUG_STREAM
1504 {
1505  QDebugStateSaver saver(dbg);
1506  dbg.nospace() << "QRhiShaderStage(type=" << s.type()
1507  << " shader=" << s.shader()
1508  << " variant=" << s.shaderVariant()
1509  << ')';
1510  return dbg;
1511 }
1512 #endif
1513 
1561  : m_texture(texture)
1562 {
1563 }
1564 
1570  : m_renderBuffer(renderBuffer)
1571 {
1572 }
1573 
1599 {
1600  m_colorAttachments.append(colorAttachment);
1601 }
1602 
1609  QRhiRenderBuffer *depthStencilBuffer)
1610  : m_depthStencilBuffer(depthStencilBuffer)
1611 {
1612  m_colorAttachments.append(colorAttachment);
1613 }
1614 
1624  QRhiTexture *depthTexture)
1625  : m_depthTexture(depthTexture)
1626 {
1627  m_colorAttachments.append(colorAttachment);
1628 }
1629 
1715  : m_image(image)
1716 {
1717 }
1718 
1727  : m_data(reinterpret_cast<const char *>(data), size)
1728 {
1729 }
1730 
1736  : m_data(data)
1737 {
1738 }
1739 
1765  : m_layer(layer),
1766  m_level(level),
1767  m_desc(desc)
1768 {
1769 }
1770 
1851 {
1852  m_entries.append(entry);
1853 }
1854 
1864 QRhiTextureUploadDescription::QRhiTextureUploadDescription(std::initializer_list<QRhiTextureUploadEntry> list)
1865  : m_entries(list)
1866 {
1867 }
1868 
1943  : m_texture(texture)
1944 {
1945 }
1946 
1982  : m_rhi(rhi)
1983 {
1985 }
1986 
1999 {
2000  // destroy() cannot be called here, due to virtuals; it is up to the
2001  // subclasses to do that.
2002 }
2003 
2035 {
2036  m_rhi->addDeleteLater(this);
2037 }
2038 
2043 {
2044  return m_objectName;
2045 }
2046 
2069 {
2070  m_objectName = name;
2071  m_objectName.replace(',', '_'); // cannot contain comma for QRhiProfiler
2072 }
2073 
2081 {
2082  return m_id;
2083 }
2084 
2196 QRhiBuffer::QRhiBuffer(QRhiImplementation *rhi, Type type_, UsageFlags usage_, int size_)
2197  : QRhiResource(rhi),
2198  m_type(type_), m_usage(usage_), m_size(size_)
2199 {
2200 }
2201 
2206 {
2207  return Buffer;
2208 }
2209 
2255 {
2256  return {};
2257 }
2258 
2294 {
2295  return nullptr;
2296 }
2297 
2304 {
2305 }
2306 
2364  int sampleCount_, Flags flags_,
2365  QRhiTexture::Format backingFormatHint_)
2366  : QRhiResource(rhi),
2367  m_type(type_), m_pixelSize(pixelSize_), m_sampleCount(sampleCount_), m_flags(flags_),
2368  m_backingFormatHint(backingFormatHint_)
2369 {
2370 }
2371 
2376 {
2377  return RenderBuffer;
2378 }
2379 
2424 {
2425  Q_UNUSED(src);
2426  return false;
2427 }
2428 
2596 QRhiTexture::QRhiTexture(QRhiImplementation *rhi, Format format_, const QSize &pixelSize_, int depth_,
2597  int arraySize_, int sampleCount_, Flags flags_)
2598  : QRhiResource(rhi),
2599  m_format(format_), m_pixelSize(pixelSize_), m_depth(depth_),
2600  m_arraySize(arraySize_), m_sampleCount(sampleCount_), m_flags(flags_)
2601 {
2602 }
2603 
2608 {
2609  return Texture;
2610 }
2611 
2631 {
2632  return {};
2633 }
2634 
2661 {
2662  Q_UNUSED(src);
2663  return false;
2664 }
2665 
2687 {
2688  Q_UNUSED(layout);
2689 }
2690 
2734  Filter magFilter_, Filter minFilter_, Filter mipmapMode_,
2735  AddressMode u_, AddressMode v_, AddressMode w_)
2736  : QRhiResource(rhi),
2737  m_magFilter(magFilter_), m_minFilter(minFilter_), m_mipmapMode(mipmapMode_),
2738  m_addressU(u_), m_addressV(v_), m_addressW(w_),
2739  m_compareOp(QRhiSampler::Never)
2740 {
2741 }
2742 
2747 {
2748  return Sampler;
2749 }
2750 
2766  : QRhiResource(rhi)
2767 {
2768 }
2769 
2774 {
2775  return RenderPassDescriptor;
2776 }
2777 
2860 {
2861  return nullptr;
2862 }
2863 
2875  : QRhiResource(rhi)
2876 {
2877 }
2878 
2883 {
2884  return RenderTarget;
2885 }
2886 
2967  Flags flags_)
2968  : QRhiRenderTarget(rhi),
2969  m_desc(desc_),
2970  m_flags(flags_)
2971 {
2972 }
2973 
2978 {
2979  return TextureRenderTarget;
2980 }
2981 
3101  : QRhiResource(rhi)
3102 {
3104 }
3105 
3110 {
3111  return ShaderResourceBindings;
3112 }
3113 
3136 {
3137  if (other == this)
3138  return true;
3139 
3140  if (!other)
3141  return false;
3142 
3143  // This can become a hot code path. Therefore we do not iterate and call
3144  // isLayoutCompatible() on m_bindings, but rather check a pre-calculated
3145  // hash code and then, if the hash matched, do a uint array comparison
3146  // (that's still more cache friendly).
3147 
3148  return m_layoutDescHash == other->m_layoutDescHash
3149  && m_layoutDesc == other->m_layoutDesc;
3150 }
3151 
3172 {
3173  srb->m_layoutDescHash = 0;
3174  srb->m_layoutDesc.clear();
3175  auto layoutDescAppender = std::back_inserter(srb->m_layoutDesc);
3176  for (const QRhiShaderResourceBinding &b : qAsConst(srb->m_bindings)) {
3177  const QRhiShaderResourceBinding::Data *d = b.data();
3178  srb->m_layoutDescHash ^= uint(d->binding) ^ uint(d->stage) ^ uint(d->type)
3179  ^ uint(d->type == QRhiShaderResourceBinding::SampledTexture ? d->u.stex.count : 1);
3180  layoutDescAppender = d->serialize(layoutDescAppender);
3181  }
3182 }
3183 
3244 {
3245  // i.e. everything that goes into a VkDescriptorSetLayoutBinding must match
3246  const int thisCount = d.type == QRhiShaderResourceBinding::SampledTexture ? d.u.stex.count : 1;
3247  const int otherCount = other.d.type == QRhiShaderResourceBinding::SampledTexture ? other.d.u.stex.count : 1;
3248  return d.binding == other.d.binding && d.stage == other.d.stage && d.type == other.d.type && thisCount == otherCount;
3249 }
3250 
3269  int binding, StageFlags stage, QRhiBuffer *buf)
3270 {
3272  b.d.binding = binding;
3273  b.d.stage = stage;
3274  b.d.type = UniformBuffer;
3275  b.d.u.ubuf.buf = buf;
3276  b.d.u.ubuf.offset = 0;
3277  b.d.u.ubuf.maybeSize = 0; // entire buffer
3278  b.d.u.ubuf.hasDynamicOffset = false;
3279  return b;
3280 }
3281 
3306  int binding, StageFlags stage, QRhiBuffer *buf, int offset, int size)
3307 {
3308  Q_ASSERT(size > 0);
3310  b.d.binding = binding;
3311  b.d.stage = stage;
3312  b.d.type = UniformBuffer;
3313  b.d.u.ubuf.buf = buf;
3314  b.d.u.ubuf.offset = offset;
3315  b.d.u.ubuf.maybeSize = size;
3316  b.d.u.ubuf.hasDynamicOffset = false;
3317  return b;
3318 }
3319 
3343  int binding, StageFlags stage, QRhiBuffer *buf, int size)
3344 {
3345  Q_ASSERT(size > 0);
3347  b.d.binding = binding;
3348  b.d.stage = stage;
3349  b.d.type = UniformBuffer;
3350  b.d.u.ubuf.buf = buf;
3351  b.d.u.ubuf.offset = 0;
3352  b.d.u.ubuf.maybeSize = size;
3353  b.d.u.ubuf.hasDynamicOffset = true;
3354  return b;
3355 }
3356 
3375  int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
3376 {
3378  b.d.binding = binding;
3379  b.d.stage = stage;
3380  b.d.type = SampledTexture;
3381  b.d.u.stex.count = 1;
3382  b.d.u.stex.texSamplers[0].tex = tex;
3383  b.d.u.stex.texSamplers[0].sampler = sampler;
3384  return b;
3385 }
3386 
3422  int binding, StageFlags stage, int count, const TextureAndSampler *texSamplers)
3423 {
3426  b.d.binding = binding;
3427  b.d.stage = stage;
3428  b.d.type = SampledTexture;
3429  b.d.u.stex.count = count;
3430  for (int i = 0; i < count; ++i) {
3431  if (texSamplers)
3432  b.d.u.stex.texSamplers[i] = texSamplers[i];
3433  else
3434  b.d.u.stex.texSamplers[i] = {};
3435  }
3436  return b;
3437 }
3438 
3456  int binding, StageFlags stage, QRhiTexture *tex, int level)
3457 {
3459  b.d.binding = binding;
3460  b.d.stage = stage;
3461  b.d.type = ImageLoad;
3462  b.d.u.simage.tex = tex;
3463  b.d.u.simage.level = level;
3464  return b;
3465 }
3466 
3484  int binding, StageFlags stage, QRhiTexture *tex, int level)
3485 {
3487  b.d.binding = binding;
3488  b.d.stage = stage;
3489  b.d.type = ImageStore;
3490  b.d.u.simage.tex = tex;
3491  b.d.u.simage.level = level;
3492  return b;
3493 }
3494 
3512  int binding, StageFlags stage, QRhiTexture *tex, int level)
3513 {
3515  b.d.binding = binding;
3516  b.d.stage = stage;
3517  b.d.type = ImageLoadStore;
3518  b.d.u.simage.tex = tex;
3519  b.d.u.simage.level = level;
3520  return b;
3521 }
3522 
3538  int binding, StageFlags stage, QRhiBuffer *buf)
3539 {
3541  b.d.binding = binding;
3542  b.d.stage = stage;
3543  b.d.type = BufferLoad;
3544  b.d.u.sbuf.buf = buf;
3545  b.d.u.sbuf.offset = 0;
3546  b.d.u.sbuf.maybeSize = 0; // entire buffer
3547  return b;
3548 }
3549 
3566  int binding, StageFlags stage, QRhiBuffer *buf, int offset, int size)
3567 {
3568  Q_ASSERT(size > 0);
3570  b.d.binding = binding;
3571  b.d.stage = stage;
3572  b.d.type = BufferLoad;
3573  b.d.u.sbuf.buf = buf;
3574  b.d.u.sbuf.offset = offset;
3575  b.d.u.sbuf.maybeSize = size;
3576  return b;
3577 }
3578 
3594  int binding, StageFlags stage, QRhiBuffer *buf)
3595 {
3597  b.d.binding = binding;
3598  b.d.stage = stage;
3599  b.d.type = BufferStore;
3600  b.d.u.sbuf.buf = buf;
3601  b.d.u.sbuf.offset = 0;
3602  b.d.u.sbuf.maybeSize = 0; // entire buffer
3603  return b;
3604 }
3605 
3622  int binding, StageFlags stage, QRhiBuffer *buf, int offset, int size)
3623 {
3624  Q_ASSERT(size > 0);
3626  b.d.binding = binding;
3627  b.d.stage = stage;
3628  b.d.type = BufferStore;
3629  b.d.u.sbuf.buf = buf;
3630  b.d.u.sbuf.offset = offset;
3631  b.d.u.sbuf.maybeSize = size;
3632  return b;
3633 }
3634 
3650  int binding, StageFlags stage, QRhiBuffer *buf)
3651 {
3653  b.d.binding = binding;
3654  b.d.stage = stage;
3655  b.d.type = BufferLoadStore;
3656  b.d.u.sbuf.buf = buf;
3657  b.d.u.sbuf.offset = 0;
3658  b.d.u.sbuf.maybeSize = 0; // entire buffer
3659  return b;
3660 }
3661 
3678  int binding, StageFlags stage, QRhiBuffer *buf, int offset, int size)
3679 {
3680  Q_ASSERT(size > 0);
3682  b.d.binding = binding;
3683  b.d.stage = stage;
3684  b.d.type = BufferLoadStore;
3685  b.d.u.sbuf.buf = buf;
3686  b.d.u.sbuf.offset = offset;
3687  b.d.u.sbuf.maybeSize = size;
3688  return b;
3689 }
3690 
3702 {
3703  const QRhiShaderResourceBinding::Data *da = a.data();
3704  const QRhiShaderResourceBinding::Data *db = b.data();
3705 
3706  if (da == db)
3707  return true;
3708 
3709 
3710  if (da->binding != db->binding
3711  || da->stage != db->stage
3712  || da->type != db->type)
3713  {
3714  return false;
3715  }
3716 
3717  switch (da->type) {
3719  if (da->u.ubuf.buf != db->u.ubuf.buf
3720  || da->u.ubuf.offset != db->u.ubuf.offset
3721  || da->u.ubuf.maybeSize != db->u.ubuf.maybeSize)
3722  {
3723  return false;
3724  }
3725  break;
3727  if (da->u.stex.count != db->u.stex.count)
3728  return false;
3729  for (int i = 0; i < da->u.stex.count; ++i) {
3730  if (da->u.stex.texSamplers[i].tex != db->u.stex.texSamplers[i].tex
3731  || da->u.stex.texSamplers[i].sampler != db->u.stex.texSamplers[i].sampler)
3732  {
3733  return false;
3734  }
3735  }
3736  break;
3738  Q_FALLTHROUGH();
3740  Q_FALLTHROUGH();
3742  if (da->u.simage.tex != db->u.simage.tex
3743  || da->u.simage.level != db->u.simage.level)
3744  {
3745  return false;
3746  }
3747  break;
3749  Q_FALLTHROUGH();
3751  Q_FALLTHROUGH();
3753  if (da->u.sbuf.buf != db->u.sbuf.buf
3754  || da->u.sbuf.offset != db->u.sbuf.offset
3755  || da->u.sbuf.maybeSize != db->u.sbuf.maybeSize)
3756  {
3757  return false;
3758  }
3759  break;
3760  default:
3761  Q_UNREACHABLE();
3762  return false;
3763  }
3764 
3765  return true;
3766 }
3767 
3775 {
3776  return !(a == b);
3777 }
3778 
3784 size_t qHash(const QRhiShaderResourceBinding &b, size_t seed) noexcept
3785 {
3786  const QRhiShaderResourceBinding::Data *d = b.data();
3787  size_t h = uint(d->binding) ^ uint(d->stage) ^ uint(d->type) ^ seed;
3788  switch (d->type) {
3790  h ^= qHash(reinterpret_cast<quintptr>(d->u.ubuf.buf));
3791  break;
3793  h ^= qHash(reinterpret_cast<quintptr>(d->u.stex.texSamplers[0].tex));
3794  h ^= qHash(reinterpret_cast<quintptr>(d->u.stex.texSamplers[0].sampler));
3795  break;
3797  Q_FALLTHROUGH();
3799  Q_FALLTHROUGH();
3801  h ^= qHash(reinterpret_cast<quintptr>(d->u.simage.tex));
3802  break;
3804  Q_FALLTHROUGH();
3806  Q_FALLTHROUGH();
3808  h ^= qHash(reinterpret_cast<quintptr>(d->u.sbuf.buf));
3809  break;
3810  default:
3811  break;
3812  }
3813  return h;
3814 }
3815 
3816 #ifndef QT_NO_DEBUG_STREAM
3818 {
3819  QDebugStateSaver saver(dbg);
3820  const QRhiShaderResourceBinding::Data *d = b.data();
3821  dbg.nospace() << "QRhiShaderResourceBinding("
3822  << "binding=" << d->binding
3823  << " stage=" << d->stage
3824  << " type=" << d->type;
3825  switch (d->type) {
3827  dbg.nospace() << " UniformBuffer("
3828  << "buffer=" << d->u.ubuf.buf
3829  << " offset=" << d->u.ubuf.offset
3830  << " maybeSize=" << d->u.ubuf.maybeSize
3831  << ')';
3832  break;
3834  dbg.nospace() << " SampledTextures("
3835  << "count=" << d->u.stex.count;
3836  for (int i = 0; i < d->u.stex.count; ++i) {
3837  dbg.nospace() << " texture=" << d->u.stex.texSamplers[i].tex
3838  << " sampler=" << d->u.stex.texSamplers[i].sampler;
3839  }
3840  dbg.nospace() << ')';
3841  break;
3843  dbg.nospace() << " ImageLoad("
3844  << "texture=" << d->u.simage.tex
3845  << " level=" << d->u.simage.level
3846  << ')';
3847  break;
3849  dbg.nospace() << " ImageStore("
3850  << "texture=" << d->u.simage.tex
3851  << " level=" << d->u.simage.level
3852  << ')';
3853  break;
3855  dbg.nospace() << " ImageLoadStore("
3856  << "texture=" << d->u.simage.tex
3857  << " level=" << d->u.simage.level
3858  << ')';
3859  break;
3861  dbg.nospace() << " BufferLoad("
3862  << "buffer=" << d->u.sbuf.buf
3863  << " offset=" << d->u.sbuf.offset
3864  << " maybeSize=" << d->u.sbuf.maybeSize
3865  << ')';
3866  break;
3868  dbg.nospace() << " BufferStore("
3869  << "buffer=" << d->u.sbuf.buf
3870  << " offset=" << d->u.sbuf.offset
3871  << " maybeSize=" << d->u.sbuf.maybeSize
3872  << ')';
3873  break;
3875  dbg.nospace() << " BufferLoadStore("
3876  << "buffer=" << d->u.sbuf.buf
3877  << " offset=" << d->u.sbuf.offset
3878  << " maybeSize=" << d->u.sbuf.maybeSize
3879  << ')';
3880  break;
3881  default:
3882  dbg.nospace() << " UNKNOWN()";
3883  break;
3884  }
3885  dbg.nospace() << ')';
3886  return dbg;
3887 }
3888 #endif
3889 
3890 #ifndef QT_NO_DEBUG_STREAM
3892 {
3893  QDebugStateSaver saver(dbg);
3894  dbg.nospace() << "QRhiShaderResourceBindings("
3895  << srb.m_bindings
3896  << ')';
3897  return dbg;
3898 }
3899 #endif
3900 
4100  : QRhiResource(rhi)
4101 {
4102 }
4103 
4108 {
4109  return GraphicsPipeline;
4110 }
4111 
4339  : QRhiResource(rhi)
4340 {
4341 }
4342 
4347 {
4348  return SwapChain;
4349 }
4350 
4476 {
4477  return ComputePipeline;
4478 }
4479 
4484  : QRhiResource(rhi)
4485 {
4486 }
4487 
4546  : QRhiResource(rhi)
4547 {
4548 }
4549 
4554 {
4555  return CommandBuffer;
4556 }
4557 
4558 static const char *resourceTypeStr(QRhiResource *res)
4559 {
4560  switch (res->resourceType()) {
4561  case QRhiResource::Buffer:
4562  return "Buffer";
4563  case QRhiResource::Texture:
4564  return "Texture";
4565  case QRhiResource::Sampler:
4566  return "Sampler";
4568  return "RenderBuffer";
4570  return "RenderPassDescriptor";
4572  return "RenderTarget";
4574  return "TextureRenderTarget";
4576  return "ShaderResourceBindings";
4578  return "GraphicsPipeline";
4580  return "SwapChain";
4582  return "ComputePipeline";
4584  return "CommandBuffer";
4585  default:
4586  Q_UNREACHABLE();
4587  break;
4588  }
4589  return "";
4590 }
4591 
4593 {
4594  qDeleteAll(resUpdPool);
4595 
4596  // Be nice and show something about leaked stuff. Though we may not get
4597  // this far with some backends where the allocator or the api may check
4598  // and freak out for unfreed graphics objects in the derived dtor already.
4599 #ifndef QT_NO_DEBUG
4600  // debug builds: just do it always
4601  static bool leakCheck = true;
4602 #else
4603  // release builds: opt-in
4604  static bool leakCheck = qEnvironmentVariableIntValue("QT_RHI_LEAK_CHECK");
4605 #endif
4606  if (!resources.isEmpty()) {
4607  if (leakCheck) {
4608  qWarning("QRhi %p going down with %d unreleased resources that own native graphics objects. This is not nice.",
4609  q, int(resources.count()));
4610  }
4611  for (QRhiResource *res : qAsConst(resources)) {
4612  if (leakCheck)
4613  qWarning(" %s resource %p (%s)", resourceTypeStr(res), res, res->m_objectName.constData());
4614 
4615  // Null out the resource's rhi pointer. This is why it makes sense to do null
4616  // checks in the destroy() implementations of the various resource types. It
4617  // allows to survive in bad applications that somehow manage to destroy a
4618  // resource of a QRhi after the QRhi itself.
4619  res->m_rhi = nullptr;
4620  }
4621  }
4622 }
4623 
4625 {
4629 }
4630 
4632  quint32 *bpl, quint32 *byteSize,
4633  QSize *blockDim) const
4634 {
4635  int xdim = 4;
4636  int ydim = 4;
4637  quint32 blockSize = 0;
4638 
4639  switch (format) {
4640  case QRhiTexture::BC1:
4641  blockSize = 8;
4642  break;
4643  case QRhiTexture::BC2:
4644  blockSize = 16;
4645  break;
4646  case QRhiTexture::BC3:
4647  blockSize = 16;
4648  break;
4649  case QRhiTexture::BC4:
4650  blockSize = 8;
4651  break;
4652  case QRhiTexture::BC5:
4653  blockSize = 16;
4654  break;
4655  case QRhiTexture::BC6H:
4656  blockSize = 16;
4657  break;
4658  case QRhiTexture::BC7:
4659  blockSize = 16;
4660  break;
4661 
4663  blockSize = 8;
4664  break;
4666  blockSize = 8;
4667  break;
4669  blockSize = 16;
4670  break;
4671 
4672  case QRhiTexture::ASTC_4x4:
4673  blockSize = 16;
4674  break;
4675  case QRhiTexture::ASTC_5x4:
4676  blockSize = 16;
4677  xdim = 5;
4678  break;
4679  case QRhiTexture::ASTC_5x5:
4680  blockSize = 16;
4681  xdim = ydim = 5;
4682  break;
4683  case QRhiTexture::ASTC_6x5:
4684  blockSize = 16;
4685  xdim = 6;
4686  ydim = 5;
4687  break;
4688  case QRhiTexture::ASTC_6x6:
4689  blockSize = 16;
4690  xdim = ydim = 6;
4691  break;
4692  case QRhiTexture::ASTC_8x5:
4693  blockSize = 16;
4694  xdim = 8;
4695  ydim = 5;
4696  break;
4697  case QRhiTexture::ASTC_8x6:
4698  blockSize = 16;
4699  xdim = 8;
4700  ydim = 6;
4701  break;
4702  case QRhiTexture::ASTC_8x8:
4703  blockSize = 16;
4704  xdim = ydim = 8;
4705  break;
4707  blockSize = 16;
4708  xdim = 10;
4709  ydim = 5;
4710  break;
4712  blockSize = 16;
4713  xdim = 10;
4714  ydim = 6;
4715  break;
4717  blockSize = 16;
4718  xdim = 10;
4719  ydim = 8;
4720  break;
4722  blockSize = 16;
4723  xdim = ydim = 10;
4724  break;
4726  blockSize = 16;
4727  xdim = 12;
4728  ydim = 10;
4729  break;
4731  blockSize = 16;
4732  xdim = ydim = 12;
4733  break;
4734 
4735  default:
4736  Q_UNREACHABLE();
4737  break;
4738  }
4739 
4740  const quint32 wblocks = uint((size.width() + xdim - 1) / xdim);
4741  const quint32 hblocks = uint((size.height() + ydim - 1) / ydim);
4742 
4743  if (bpl)
4744  *bpl = wblocks * blockSize;
4745  if (byteSize)
4746  *byteSize = wblocks * hblocks * blockSize;
4747  if (blockDim)
4748  *blockDim = QSize(xdim, ydim);
4749 }
4750 
4752  quint32 *bpl, quint32 *byteSize, quint32 *bytesPerPixel) const
4753 {
4754  if (isCompressedFormat(format)) {
4755  compressedFormatInfo(format, size, bpl, byteSize, nullptr);
4756  return;
4757  }
4758 
4759  quint32 bpc = 0;
4760  switch (format) {
4761  case QRhiTexture::RGBA8:
4762  bpc = 4;
4763  break;
4764  case QRhiTexture::BGRA8:
4765  bpc = 4;
4766  break;
4767  case QRhiTexture::R8:
4768  bpc = 1;
4769  break;
4770  case QRhiTexture::RG8:
4771  bpc = 2;
4772  break;
4773  case QRhiTexture::R16:
4774  bpc = 2;
4775  break;
4776  case QRhiTexture::RG16:
4777  bpc = 4;
4778  break;
4780  bpc = 1;
4781  break;
4782 
4783  case QRhiTexture::RGBA16F:
4784  bpc = 8;
4785  break;
4786  case QRhiTexture::RGBA32F:
4787  bpc = 16;
4788  break;
4789  case QRhiTexture::R16F:
4790  bpc = 2;
4791  break;
4792  case QRhiTexture::R32F:
4793  bpc = 4;
4794  break;
4795 
4796  case QRhiTexture::D16:
4797  bpc = 2;
4798  break;
4799  case QRhiTexture::D24:
4800  case QRhiTexture::D24S8:
4801  case QRhiTexture::D32F:
4802  bpc = 4;
4803  break;
4804 
4805  default:
4806  Q_UNREACHABLE();
4807  break;
4808  }
4809 
4810  if (bpl)
4811  *bpl = uint(size.width()) * bpc;
4812  if (byteSize)
4813  *byteSize = uint(size.width() * size.height()) * bpc;
4814  if (bytesPerPixel)
4815  *bytesPerPixel = bpc;
4816 }
4817 
4818 // Approximate because it excludes subresource alignment or multisampling.
4820  int mipCount, int layerCount)
4821 {
4822  quint32 approxSize = 0;
4823  for (int level = 0; level < mipCount; ++level) {
4824  quint32 byteSize = 0;
4825  const QSize size(qFloor(qreal(qMax(1, baseSize.width() >> level))),
4826  qFloor(qreal(qMax(1, baseSize.height() >> level))));
4827  textureFormatInfo(format, size, nullptr, &byteSize, nullptr);
4828  approxSize += byteSize;
4829  }
4830  approxSize *= depth; // 3D texture depth or 1 otherwise
4831  approxSize *= uint(layerCount); // 6 for cubemaps or 1 otherwise
4832  return approxSize;
4833 }
4834 
4836 {
4837  if (ps->cbeginShaderStages() == ps->cendShaderStages()) {
4838  qWarning("Cannot build a graphics pipeline without any stages");
4839  return false;
4840  }
4841 
4842  bool hasVertexStage = false;
4843  for (auto it = ps->cbeginShaderStages(), itEnd = ps->cendShaderStages(); it != itEnd; ++it) {
4844  if (!it->shader().isValid()) {
4845  qWarning("Empty shader passed to graphics pipeline");
4846  return false;
4847  }
4848  if (it->type() == QRhiShaderStage::Vertex)
4849  hasVertexStage = true;
4850  }
4851  if (!hasVertexStage) {
4852  qWarning("Cannot build a graphics pipeline without a vertex stage");
4853  return false;
4854  }
4855 
4856  if (!ps->renderPassDescriptor()) {
4857  qWarning("Cannot build a graphics pipeline without a QRhiRenderPassDescriptor");
4858  return false;
4859  }
4860 
4861  if (!ps->shaderResourceBindings()) {
4862  qWarning("Cannot build a graphics pipeline without QRhiShaderResourceBindings");
4863  return false;
4864  }
4865 
4866  return true;
4867 }
4868 
4870 {
4871 #ifndef QT_NO_DEBUG
4872  bool bindingsOk = true;
4873  const int CHECKED_BINDINGS_COUNT = 64;
4874  bool bindingSeen[CHECKED_BINDINGS_COUNT] = {};
4875  for (auto it = srb->cbeginBindings(), end = srb->cendBindings(); it != end; ++it) {
4876  const int binding = it->data()->binding;
4877  if (binding >= CHECKED_BINDINGS_COUNT)
4878  continue;
4879  if (binding < 0) {
4880  qWarning("Invalid binding number %d", binding);
4881  bindingsOk = false;
4882  continue;
4883  }
4884  switch (it->data()->type) {
4886  if (!bindingSeen[binding]) {
4887  bindingSeen[binding] = true;
4888  } else {
4889  qWarning("Uniform buffer duplicates an existing binding number %d", binding);
4890  bindingsOk = false;
4891  }
4892  break;
4894  if (!bindingSeen[binding]) {
4895  bindingSeen[binding] = true;
4896  } else {
4897  qWarning("Combined image sampler duplicates an existing binding number %d", binding);
4898  bindingsOk = false;
4899  }
4900  break;
4902  Q_FALLTHROUGH();
4904  Q_FALLTHROUGH();
4906  if (!bindingSeen[binding]) {
4907  bindingSeen[binding] = true;
4908  } else {
4909  qWarning("Image duplicates an existing binding number %d", binding);
4910  bindingsOk = false;
4911  }
4912  break;
4914  Q_FALLTHROUGH();
4916  Q_FALLTHROUGH();
4918  if (!bindingSeen[binding]) {
4919  bindingSeen[binding] = true;
4920  } else {
4921  qWarning("Buffer duplicates an existing binding number %d", binding);
4922  bindingsOk = false;
4923  }
4924  break;
4925  default:
4926  qWarning("Unknown binding type %d", int(it->data()->type));
4927  bindingsOk = false;
4928  break;
4929  }
4930  }
4931 
4932  if (!bindingsOk) {
4933  qWarning() << *srb;
4934  return false;
4935  }
4936 #else
4937  Q_UNUSED(srb);
4938 #endif
4939  return true;
4940 }
4941 
4946 {
4947 }
4948 
4953 {
4954  if (!d)
4955  return;
4956 
4957  qDeleteAll(d->pendingDeleteResources);
4958  d->pendingDeleteResources.clear();
4959 
4960  runCleanup();
4961 
4962  d->destroy();
4963  delete d;
4964 }
4965 
4979 {
4980  std::unique_ptr<QRhi> r(new QRhi);
4981 
4982  switch (impl) {
4983  case Null:
4984  r->d = new QRhiNull(static_cast<QRhiNullInitParams *>(params));
4985  break;
4986  case Vulkan:
4987 #if QT_CONFIG(vulkan)
4988  r->d = new QRhiVulkan(static_cast<QRhiVulkanInitParams *>(params),
4989  static_cast<QRhiVulkanNativeHandles *>(importDevice));
4990  break;
4991 #else
4992  Q_UNUSED(importDevice);
4993  qWarning("This build of Qt has no Vulkan support");
4994  break;
4995 #endif
4996  case OpenGLES2:
4997 #ifndef QT_NO_OPENGL
4998  r->d = new QRhiGles2(static_cast<QRhiGles2InitParams *>(params),
4999  static_cast<QRhiGles2NativeHandles *>(importDevice));
5000  break;
5001 #else
5002  qWarning("This build of Qt has no OpenGL support");
5003  break;
5004 #endif
5005  case D3D11:
5006 #ifdef Q_OS_WIN
5007  r->d = new QRhiD3D11(static_cast<QRhiD3D11InitParams *>(params),
5008  static_cast<QRhiD3D11NativeHandles *>(importDevice));
5009  break;
5010 #else
5011  qWarning("This platform has no Direct3D 11 support");
5012  break;
5013 #endif
5014  case Metal:
5015 #if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
5016  r->d = new QRhiMetal(static_cast<QRhiMetalInitParams *>(params),
5017  static_cast<QRhiMetalNativeHandles *>(importDevice));
5018  break;
5019 #else
5020  qWarning("This platform has no Metal support");
5021  break;
5022 #endif
5023  default:
5024  break;
5025  }
5026 
5027  if (r->d) {
5028  r->d->q = r.get();
5029 
5030  if (flags.testFlag(EnableProfiling)) {
5031  QRhiProfilerPrivate *profD = QRhiProfilerPrivate::get(&r->d->profiler);
5032  profD->rhiDWhenEnabled = r->d;
5033  const_cast<QLoggingCategory &>(QRHI_LOG_INFO()).setEnabled(QtDebugMsg, true);
5034  }
5035 
5036  // Play nice with QSG_INFO since that is still the most commonly used
5037  // way to get graphics info printed from Qt Quick apps, and the Quick
5038  // scenegraph is our primary user.
5039  if (qEnvironmentVariableIsSet("QSG_INFO"))
5040  const_cast<QLoggingCategory &>(QRHI_LOG_INFO()).setEnabled(QtDebugMsg, true);
5041 
5042  r->d->debugMarkers = flags.testFlag(EnableDebugMarkers);
5043 
5044  if (r->d->create(flags)) {
5045  r->d->implType = impl;
5046  r->d->implThread = QThread::currentThread();
5047  return r.release();
5048  }
5049  }
5050 
5051  return nullptr;
5052 }
5053 
5058 {
5059  return d->implType;
5060 }
5061 
5065 const char *QRhi::backendName() const
5066 {
5067  switch (d->implType) {
5068  case QRhi::Null:
5069  return "Null";
5070  case QRhi::Vulkan:
5071  return "Vulkan";
5072  case QRhi::OpenGLES2:
5073  return "OpenGL";
5074  case QRhi::D3D11:
5075  return "D3D11";
5076  case QRhi::Metal:
5077  return "Metal";
5078  default:
5079  return "Unknown";
5080  }
5081 }
5082 
5115 #ifndef QT_NO_DEBUG_STREAM
5116 static inline const char *deviceTypeStr(QRhiDriverInfo::DeviceType type)
5117 {
5118  switch (type) {
5120  return "Unknown";
5122  return "Integrated";
5124  return "Discrete";
5126  return "External";
5128  return "Virtual";
5130  return "Cpu";
5131  default:
5132  return "";
5133  }
5134 }
5136 {
5137  QDebugStateSaver saver(dbg);
5138  dbg.nospace() << "QRhiDriverInfo(deviceName=" << info.deviceName
5139  << " deviceId=0x" << Qt::hex << info.deviceId
5140  << " vendorId=0x" << info.vendorId
5141  << " deviceType=" << deviceTypeStr(info.deviceType)
5142  << ')';
5143  return dbg;
5144 }
5145 #endif
5146 
5152 {
5153  return d->driverInfo();
5154 }
5155 
5160 {
5161  return d->implThread;
5162 }
5163 
5177 {
5178  d->addCleanupCallback(callback);
5179 }
5180 
5190 {
5191  for (const CleanupCallback &f : qAsConst(d->cleanupCallbacks))
5192  f(this);
5193 
5194  d->cleanupCallbacks.clear();
5195 }
5196 
5221 QRhiResourceUpdateBatch::QRhiResourceUpdateBatch(QRhiImplementation *rhi)
5223 {
5224  d->q = this;
5225  d->rhi = rhi;
5226 }
5227 
5229 {
5230  delete d;
5231 }
5232 
5243 {
5244  d->free();
5245 }
5246 
5285 {
5286  d->merge(other->d);
5287 }
5288 
5303 {
5304  return d->hasOptimalCapacity();
5305 }
5306 
5327 {
5328  if (size > 0) {
5329  const int idx = d->activeBufferOpCount++;
5330  const int opListSize = d->bufferOps.size();
5331  if (idx < opListSize)
5333  else
5335  }
5336 }
5337 
5347 {
5348  if (size > 0) {
5349  const int idx = d->activeBufferOpCount++;
5350  if (idx < d->bufferOps.size())
5352  else
5354  }
5355 }
5356 
5362 {
5363  if (buf->size() > 0) {
5364  const int idx = d->activeBufferOpCount++;
5365  if (idx < d->bufferOps.size())
5367  else
5369  }
5370 }
5371 
5397 {
5398  const int idx = d->activeBufferOpCount++;
5399  if (idx < d->bufferOps.size())
5401  else
5403 }
5404 
5413 {
5414  if (desc.cbeginEntries() != desc.cendEntries()) {
5415  const int idx = d->activeTextureOpCount++;
5416  if (idx < d->textureOps.size())
5418  else
5420  }
5421 }
5422 
5432 {
5435 }
5436 
5450 {
5451  const int idx = d->activeTextureOpCount++;
5452  if (idx < d->textureOps.size())
5454  else
5456 }
5457 
5520 {
5521  const int idx = d->activeTextureOpCount++;
5522  if (idx < d->textureOps.size())
5524  else
5526 }
5527 
5544 {
5545  const int idx = d->activeTextureOpCount++;
5546  if (idx < d->textureOps.size())
5548  else
5550 }
5551 
5569 {
5570  auto nextFreeBatch = [this]() -> QRhiResourceUpdateBatch * {
5571  auto isFree = [this](int i) -> QRhiResourceUpdateBatch * {
5572  const quint64 mask = 1ULL << quint64(i);
5573  if (!(d->resUpdPoolMap & mask)) {
5574  d->resUpdPoolMap |= mask;
5575  QRhiResourceUpdateBatch *u = d->resUpdPool[i];
5577  d->lastResUpdIdx = i;
5578  return u;
5579  }
5580  return nullptr;
5581  };
5582  const int poolSize = d->resUpdPool.size();
5583  for (int i = d->lastResUpdIdx + 1; i < poolSize; ++i) {
5584  if (QRhiResourceUpdateBatch *u = isFree(i))
5585  return u;
5586  }
5587  for (int i = 0; i <= d->lastResUpdIdx; ++i) {
5588  if (QRhiResourceUpdateBatch *u = isFree(i))
5589  return u;
5590  }
5591  return nullptr;
5592  };
5593 
5594  QRhiResourceUpdateBatch *u = nextFreeBatch();
5595  if (!u) {
5596  const int oldSize = d->resUpdPool.count();
5597  const int newSize = oldSize + qMin(4, qMax(0, 64 - oldSize));
5598  d->resUpdPool.resize(newSize);
5599  for (int i = oldSize; i < newSize; ++i)
5600  d->resUpdPool[i] = new QRhiResourceUpdateBatch(d);
5601  u = nextFreeBatch();
5602  if (!u)
5603  qWarning("Resource update batch pool exhausted (max is 64)");
5604  }
5605 
5606  return u;
5607 }
5608 
5610 {
5611  Q_ASSERT(poolIndex >= 0 && rhi->resUpdPool[poolIndex] == q);
5612 
5613  activeBufferOpCount = 0;
5615 
5616  const quint64 mask = 1ULL << quint64(poolIndex);
5617  rhi->resUpdPoolMap &= ~mask;
5618  poolIndex = -1;
5619 
5620  textureOps.clear();
5621 }
5622 
5624 {
5625  int combinedSize = activeBufferOpCount + other->activeBufferOpCount;
5626  if (bufferOps.size() < combinedSize)
5627  bufferOps.resize(combinedSize);
5628  for (int i = activeBufferOpCount; i < combinedSize; ++i)
5629  bufferOps[i] = std::move(other->bufferOps[i - activeBufferOpCount]);
5630  activeBufferOpCount += other->activeBufferOpCount;
5631 
5632  combinedSize = activeTextureOpCount + other->activeTextureOpCount;
5633  if (textureOps.size() < combinedSize)
5634  textureOps.resize(combinedSize);
5635  for (int i = activeTextureOpCount; i < combinedSize; ++i)
5636  textureOps[i] = std::move(other->textureOps[i - activeTextureOpCount]);
5637  activeTextureOpCount += other->activeTextureOpCount;
5638 }
5639 
5641 {
5644 }
5645 
5647 {
5648  Q_ASSERT(poolIndex == -1); // must not be in use
5649 
5650  activeBufferOpCount = 0;
5651  bufferOps.clear();
5652 
5654  textureOps.clear();
5655 }
5656 
5665 {
5666  if (resourceUpdates)
5667  m_rhi->resourceUpdate(this, resourceUpdates);
5668 }
5669 
5720  const QColor &colorClearValue,
5721  const QRhiDepthStencilClearValue &depthStencilClearValue,
5722  QRhiResourceUpdateBatch *resourceUpdates,
5723  BeginPassFlags flags)
5724 {
5725  m_rhi->beginPass(this, rt, colorClearValue, depthStencilClearValue, resourceUpdates, flags);
5726 }
5727 
5737 {
5738  m_rhi->endPass(this, resourceUpdates);
5739 }
5740 
5757 {
5758  Q_ASSERT(ps != nullptr);
5759  m_rhi->setGraphicsPipeline(this, ps);
5760 }
5761 
5815  int dynamicOffsetCount,
5816  const DynamicOffset *dynamicOffsets)
5817 {
5818  m_rhi->setShaderResources(this, srb, dynamicOffsetCount, dynamicOffsets);
5819 }
5820 
5877 void QRhiCommandBuffer::setVertexInput(int startBinding, int bindingCount, const VertexInput *bindings,
5878  QRhiBuffer *indexBuf, quint32 indexOffset,
5879  IndexFormat indexFormat)
5880 {
5881  m_rhi->setVertexInput(this, startBinding, bindingCount, bindings, indexBuf, indexOffset, indexFormat);
5882 }
5883 
5899 {
5900  m_rhi->setViewport(this, viewport);
5901 }
5902 
5918 {
5919  m_rhi->setScissor(this, scissor);
5920 }
5921 
5932 {
5933  m_rhi->setBlendConstants(this, c);
5934 }
5935 
5946 {
5947  m_rhi->setStencilRef(this, refValue);
5948 }
5949 
5966  quint32 instanceCount,
5967  quint32 firstVertex,
5968  quint32 firstInstance)
5969 {
5970  m_rhi->draw(this, vertexCount, instanceCount, firstVertex, firstInstance);
5971 }
5972 
6003  quint32 instanceCount,
6004  quint32 firstIndex,
6005  qint32 vertexOffset,
6006  quint32 firstInstance)
6007 {
6008  m_rhi->drawIndexed(this, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
6009 }
6010 
6023 {
6024  m_rhi->debugMarkBegin(this, name);
6025 }
6026 
6036 {
6037  m_rhi->debugMarkEnd(this);
6038 }
6039 
6051 {
6052  m_rhi->debugMarkMsg(this, msg);
6053 }
6054 
6073 {
6074  m_rhi->beginComputePass(this, resourceUpdates, flags);
6075 }
6076 
6084 {
6085  m_rhi->endComputePass(this, resourceUpdates);
6086 }
6087 
6102 {
6103  m_rhi->setComputePipeline(this, ps);
6104 }
6105 
6125 void QRhiCommandBuffer::dispatch(int x, int y, int z)
6126 {
6127  m_rhi->dispatch(this, x, y, z);
6128 }
6129 
6140 {
6141  return m_rhi->nativeHandles(this);
6142 }
6143 
6184 {
6185  m_rhi->beginExternal(this);
6186 }
6187 
6199 {
6200  m_rhi->endExternal(this);
6201 }
6202 
6207 int QRhi::ubufAligned(int v) const
6208 {
6209  const int byteAlign = ubufAlignment();
6210  return (v + byteAlign - 1) & ~(byteAlign - 1);
6211 }
6212 
6217 {
6218  return qFloor(std::log2(qMax(size.width(), size.height()))) + 1;
6219 }
6220 
6225 QSize QRhi::sizeForMipLevel(int mipLevel, const QSize &baseLevelSize) const
6226 {
6227  const int w = qMax(1, baseLevelSize.width() >> mipLevel);
6228  const int h = qMax(1, baseLevelSize.height() >> mipLevel);
6229  return QSize(w, h);
6230 }
6231 
6239 {
6240  return d->isYUpInFramebuffer();
6241 }
6242 
6252 bool QRhi::isYUpInNDC() const
6253 {
6254  return d->isYUpInNDC();
6255 }
6256 
6278 {
6279  return d->isClipDepthZeroToOne();
6280 }
6281 
6300 {
6301  return d->clipSpaceCorrMatrix();
6302 }
6303 
6311 {
6313 }
6314 
6319 {
6320  return d->isFeatureSupported(feature);
6321 }
6322 
6330 {
6331  return d->resourceLimit(limit);
6332 }
6333 
6345 {
6346  return d->nativeHandles();
6347 }
6348 
6366 {
6368 }
6369 
6378 {
6379  return &d->profiler;
6380 }
6381 
6395 {
6397 
6398  for (QRhiResourceUpdateBatch *u : d->resUpdPool) {
6399  if (u->d->poolIndex < 0)
6400  u->d->trimOpLists();
6401  }
6402 }
6403 
6447 {
6448  return d->isDeviceLost();
6449 }
6450 
6479 {
6480  return d->pipelineCacheData();
6481 }
6482 
6511 {
6513 }
6514 
6521 {
6522  return d->createGraphicsPipeline();
6523 }
6524 
6534 {
6535  return d->createComputePipeline();
6536 }
6537 
6544 {
6545  return d->createShaderResourceBindings();
6546 }
6547 
6563  QRhiBuffer::UsageFlags usage,
6564  int size)
6565 {
6566  return d->createBuffer(type, usage, size);
6567 }
6568 
6590  const QSize &pixelSize,
6591  int sampleCount,
6593  QRhiTexture::Format backingFormatHint)
6594 {
6595  return d->createRenderBuffer(type, pixelSize, sampleCount, flags, backingFormatHint);
6596 }
6597 
6610  const QSize &pixelSize,
6611  int sampleCount,
6613 {
6614  return d->createTexture(format, pixelSize, 1, 0, sampleCount, flags);
6615 }
6616 
6633  int width, int height, int depth,
6634  int sampleCount,
6636 {
6637  if (depth > 0)
6639 
6641 }
6642 
6663  int arraySize,
6664  const QSize &pixelSize,
6665  int sampleCount,
6667 {
6669  return d->createTexture(format, pixelSize, 1, arraySize, sampleCount, flags);
6670 }
6671 
6680  QRhiSampler::Filter minFilter,
6681  QRhiSampler::Filter mipmapMode,
6682  QRhiSampler::AddressMode addressU,
6683  QRhiSampler::AddressMode addressV,
6684  QRhiSampler::AddressMode addressW)
6685 {
6686  return d->createSampler(magFilter, minFilter, mipmapMode, addressU, addressV, addressW);
6687 }
6688 
6698 {
6699  return d->createTextureRenderTarget(desc, flags);
6700 }
6701 
6708 {
6709  return d->createSwapChain();
6710 }
6711 
6760 {
6761  if (d->inFrame)
6762  qWarning("Attempted to call beginFrame() within a still active frame; ignored");
6763 
6764  QRhi::FrameOpResult r = !d->inFrame ? d->beginFrame(swapChain, flags) : FrameOpSuccess;
6765  if (r == FrameOpSuccess)
6766  d->inFrame = true;
6767 
6768  return r;
6769 }
6770 
6795 {
6796  if (!d->inFrame)
6797  qWarning("Attempted to call endFrame() without an active frame; ignored");
6798 
6799  QRhi::FrameOpResult r = d->inFrame ? d->endFrame(swapChain, flags) : FrameOpSuccess;
6800  d->inFrame = false;
6801  // deleteLater is a high level QRhi concept the backends know
6802  // nothing about - handle it here.
6803  qDeleteAll(d->pendingDeleteResources);
6804  d->pendingDeleteResources.clear();
6805 
6806  return r;
6807 }
6808 
6817 {
6818  return d->inFrame;
6819 }
6820 
6861 {
6862  return d->currentFrameSlot;
6863 }
6864 
6905 {
6906  if (d->inFrame)
6907  qWarning("Attempted to call beginOffscreenFrame() within a still active frame; ignored");
6908 
6910  if (r == FrameOpSuccess)
6911  d->inFrame = true;
6912 
6913  return r;
6914 }
6915 
6922 {
6923  if (!d->inFrame)
6924  qWarning("Attempted to call endOffscreenFrame() without an active frame; ignored");
6925 
6927  d->inFrame = false;
6928  qDeleteAll(d->pendingDeleteResources);
6929  d->pendingDeleteResources.clear();
6930 
6931  return r;
6932 }
6933 
6946 {
6947  return d->finish();
6948 }
6949 
6960 {
6961  return d->supportedSampleCounts();
6962 }
6963 
6975 {
6976  return d->ubufAlignment();
6977 }
6978 
6980 
6982 {
6983  return counter.fetchAndAddRelaxed(1) + 1;
6984 }
6985 
6987 {
6988  return m_buffers.isEmpty() && m_textures.isEmpty();
6989 }
6990 
6992 {
6993  m_buffers.clear();
6994  m_textures.clear();
6995 }
6996 
6999 {
7000  return QRhiPassResourceTracker::BufferStage(qMin(int(a), int(b)));
7001 }
7002 
7004  const UsageState &state)
7005 {
7006  auto it = m_buffers.find(buf);
7007  if (it != m_buffers.end()) {
7008  if (it->access != *access) {
7009  const QByteArray name = buf->name();
7010  qWarning("Buffer %p (%s) used with different accesses within the same pass, this is not allowed.",
7011  buf, name.constData());
7012  return;
7013  }
7014  if (it->stage != *stage) {
7015  it->stage = earlierStage(it->stage, *stage);
7016  *stage = it->stage;
7017  }
7018  return;
7019  }
7020 
7021  Buffer b;
7022  b.slot = slot;
7023  b.access = *access;
7024  b.stage = *stage;
7025  b.stateAtPassBegin = state; // first use -> initial state
7026  m_buffers.insert(buf, b);
7027 }
7028 
7031 {
7032  return QRhiPassResourceTracker::TextureStage(qMin(int(a), int(b)));
7033 }
7034 
7035 static inline bool isImageLoadStore(QRhiPassResourceTracker::TextureAccess access)
7036 {
7040 }
7041 
7043  const UsageState &state)
7044 {
7045  auto it = m_textures.find(tex);
7046  if (it != m_textures.end()) {
7047  if (it->access != *access) {
7048  // Different subresources of a texture may be used for both load
7049  // and store in the same pass. (think reading from one mip level
7050  // and writing to another one in a compute shader) This we can
7051  // handle by treating the entire resource as read-write.
7052  if (isImageLoadStore(it->access) && isImageLoadStore(*access)) {
7054  *access = it->access;
7055  } else {
7056  const QByteArray name = tex->name();
7057  qWarning("Texture %p (%s) used with different accesses within the same pass, this is not allowed.",
7058  tex, name.constData());
7059  }
7060  }
7061  if (it->stage != *stage) {
7062  it->stage = earlierStage(it->stage, *stage);
7063  *stage = it->stage;
7064  }
7065  return;
7066  }
7067 
7068  Texture t;
7069  t.access = *access;
7070  t.stage = *stage;
7071  t.stateAtPassBegin = state; // first use -> initial state
7072  m_textures.insert(tex, t);
7073 }
7074 
7076 {
7077  // pick the earlier stage (as this is going to be dstAccessMask)
7084 
7085  Q_UNREACHABLE();
7087 }
7088 
7090 {
7091  // pick the earlier stage (as this is going to be dstAccessMask)
7098 
7099  Q_UNREACHABLE();
7101 }
7102 
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
const char msg[]
Definition: arch.cpp:46
FT_UInt idx
Definition: cffcmap.c:135
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
QByteArray & replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
Definition: qbytearray.h:278
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
operator<<(QDataStream &ds, qfloat16 f)
Definition: qfloat16.cpp:327
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:65
QDebug & nospace()
Definition: qdebug.h:113
Convenience class for custom QDebug operators.
Definition: qdebug.h:176
template< typename Enum > size_t qHash(QFlags< Enum > flags, size_t seed=0) noexcept
template< typename Enum > bool operator==(Enum lhs, QFlags< Enum > rhs)
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:73
The QLoggingCategory class represents a category, or 'area' in the logging infrastructure.
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition: qmatrix4x4.h:61
virtual char * beginFullDynamicBufferUpdateForCurrentFrame()
Definition: qrhi.cpp:2293
QRhiResource::Type resourceType() const override
Definition: qrhi.cpp:2205
virtual void endFullDynamicBufferUpdateForCurrentFrame()
Definition: qrhi.cpp:2303
virtual NativeBuffer nativeBuffer()
Definition: qrhi.cpp:2254
QRhiBuffer(QRhiImplementation *rhi, Type type_, UsageFlags usage_, int size_)
an array with pointers to the native object handles.
Definition: qrhi.cpp:2196
QRhiColorAttachment()=default
void endPass(QRhiResourceUpdateBatch *resourceUpdates=nullptr)
Definition: qrhi.cpp:5736
void debugMarkMsg(const QByteArray &msg)
Definition: qrhi.cpp:6050
void draw(quint32 vertexCount, quint32 instanceCount=1, quint32 firstVertex=0, quint32 firstInstance=0)
Definition: qrhi.cpp:5965
void setBlendConstants(const QColor &c)
Definition: qrhi.cpp:5931
void endExternal()
Definition: qrhi.cpp:6198
void setScissor(const QRhiScissor &scissor)
Definition: qrhi.cpp:5917
void beginComputePass(QRhiResourceUpdateBatch *resourceUpdates=nullptr, BeginPassFlags flags={})
Definition: qrhi.cpp:6072
void drawIndexed(quint32 indexCount, quint32 instanceCount=1, quint32 firstIndex=0, qint32 vertexOffset=0, quint32 firstInstance=0)
Definition: qrhi.cpp:6002
void setStencilRef(quint32 refValue)
Definition: qrhi.cpp:5945
QPair< QRhiBuffer *, quint32 > VertexInput
Definition: qrhi_p.h:1426
const QRhiNativeHandles * nativeHandles()
Definition: qrhi.cpp:6139
QRhiCommandBuffer(QRhiImplementation *rhi)
Definition: qrhi.cpp:4545
void resourceUpdate(QRhiResourceUpdateBatch *resourceUpdates)
Definition: qrhi.cpp:5664
void dispatch(int x, int y, int z)
Definition: qrhi.cpp:6125
void beginPass(QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, QRhiResourceUpdateBatch *resourceUpdates=nullptr, BeginPassFlags flags={})
Definition: qrhi.cpp:5719
void setShaderResources(QRhiShaderResourceBindings *srb=nullptr, int dynamicOffsetCount=0, const DynamicOffset *dynamicOffsets=nullptr)
Definition: qrhi.cpp:5814
void beginExternal()
Definition: qrhi.cpp:6183
void debugMarkBegin(const QByteArray &name)
Definition: qrhi.cpp:6022
void setViewport(const QRhiViewport &viewport)
Definition: qrhi.cpp:5898
QRhiResource::Type resourceType() const override
Definition: qrhi.cpp:4553
void debugMarkEnd()
Definition: qrhi.cpp:6035
void endComputePass(QRhiResourceUpdateBatch *resourceUpdates=nullptr)
Definition: qrhi.cpp:6083
QPair< int, quint32 > DynamicOffset
Definition: qrhi_p.h:1422
void setComputePipeline(QRhiComputePipeline *ps)
Definition: qrhi.cpp:6101
void setVertexInput(int startBinding, int bindingCount, const VertexInput *bindings, QRhiBuffer *indexBuf=nullptr, quint32 indexOffset=0, IndexFormat indexFormat=IndexUInt16)
Definition: qrhi.cpp:5877
void setGraphicsPipeline(QRhiGraphicsPipeline *ps)
Definition: qrhi.cpp:5756
QRhiResource::Type resourceType() const override
Definition: qrhi.cpp:4475
QRhiComputePipeline(QRhiImplementation *rhi)
Definition: qrhi.cpp:4483
size_t qHash(const QRhiDepthStencilClearValue &v, size_t seed) noexcept
Definition: qrhi.cpp:863
bool operator!=(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClearValue &b) noexcept
Definition: qrhi.cpp:853
bool operator==(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClearValue &b) noexcept
Definition: qrhi.cpp:841
QRhiRenderPassDescriptor * renderPassDescriptor() const
Definition: qrhi_p.h:1283
QRhiShaderResourceBindings * shaderResourceBindings() const
Definition: qrhi_p.h:1280
QRhiGraphicsPipeline(QRhiImplementation *rhi)
Definition: qrhi.cpp:4099
QRhiResource::Type resourceType() const override
Definition: qrhi.cpp:4107
const QRhiShaderStage * cendShaderStages() const
Definition: qrhi_p.h:1275
const QRhiShaderStage * cbeginShaderStages() const
Definition: qrhi_p.h:1274
Definition: qrhi_p.h:1536
bool isClipDepthZeroToOne() const
Definition: qrhi.cpp:6277
FrameOpResult endOffscreenFrame(EndFrameFlags flags={})
Definition: qrhi.cpp:6921
bool makeThreadLocalNativeContextCurrent()
Definition: qrhi.cpp:6365
bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags={}) const
Definition: qrhi.cpp:6310
int ubufAligned(int v) const
Definition: qrhi.cpp:6207
int resourceLimit(ResourceLimit limit) const
Definition: qrhi.cpp:6329
QRhiTexture * newTextureArray(QRhiTexture::Format format, int arraySize, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
Definition: qrhi.cpp:6662
QMatrix4x4 clipSpaceCorrMatrix() const
Definition: qrhi.cpp:6299
QThread * thread() const
Definition: qrhi.cpp:5159
bool isYUpInFramebuffer() const
Definition: qrhi.cpp:6238
bool isYUpInNDC() const
Definition: qrhi.cpp:6252
bool isFeatureSupported(QRhi::Feature feature) const
Definition: qrhi.cpp:6318
void runCleanup()
Definition: qrhi.cpp:5189
QRhiShaderResourceBindings * newShaderResourceBindings()
Definition: qrhi.cpp:6543
QList< int > supportedSampleCounts() const
Definition: qrhi.cpp:6959
QSize sizeForMipLevel(int mipLevel, const QSize &baseLevelSize) const
Definition: qrhi.cpp:6225
QRhiRenderBuffer * newRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount=1, QRhiRenderBuffer::Flags flags={}, QRhiTexture::Format backingFormatHint=QRhiTexture::UnknownFormat)
Definition: qrhi.cpp:6589
Implementation backend() const
Definition: qrhi.cpp:5057
Implementation
Definition: qrhi_p.h:1538
@ Metal
Definition: qrhi_p.h:1543
@ Vulkan
Definition: qrhi_p.h:1540
@ Null
Definition: qrhi_p.h:1539
@ D3D11
Definition: qrhi_p.h:1542
@ OpenGLES2
Definition: qrhi_p.h:1541
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, int size)
Definition: qrhi.cpp:6562
int currentFrameSlot() const
Definition: qrhi.cpp:6860
FrameOpResult beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags={})
Definition: qrhi.cpp:6759
QRhi::FrameOpResult finish()
Definition: qrhi.cpp:6945
QRhiComputePipeline * newComputePipeline()
Definition: qrhi.cpp:6533
QRhiSwapChain * newSwapChain()
Definition: qrhi.cpp:6707
FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, BeginFrameFlags flags={})
Definition: qrhi.cpp:6904
QRhiSampler * newSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode addressU, QRhiSampler::AddressMode addressV, QRhiSampler::AddressMode addressW=QRhiSampler::Repeat)
Definition: qrhi.cpp:6679
QRhiTextureRenderTarget * newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags={})
Definition: qrhi.cpp:6696
bool isRecordingFrame() const
Definition: qrhi.cpp:6816
const char * backendName() const
Definition: qrhi.cpp:5065
QRhiGraphicsPipeline * newGraphicsPipeline()
Definition: qrhi.cpp:6520
void addCleanupCallback(const CleanupCallback &callback)
Definition: qrhi.cpp:5176
static QRhi * create(Implementation impl, QRhiInitParams *params, Flags flags={}, QRhiNativeHandles *importDevice=nullptr)
Definition: qrhi.cpp:4978
QRhi()
Definition: qrhi.cpp:4945
QByteArray pipelineCacheData()
Definition: qrhi.cpp:6478
int mipLevelsForSize(const QSize &size) const
Definition: qrhi.cpp:6216
~QRhi()
Definition: qrhi.cpp:4952
FrameOpResult endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags={})
Definition: qrhi.cpp:6794
ResourceLimit
Definition: qrhi_p.h:1604
QRhiProfiler * profiler()
Definition: qrhi.cpp:6377
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
Definition: qrhi.cpp:6609
void setPipelineCacheData(const QByteArray &data)
Definition: qrhi.cpp:6510
QRhiDriverInfo driverInfo() const
Definition: qrhi.cpp:5151
Feature
Definition: qrhi_p.h:1561
const QRhiNativeHandles * nativeHandles()
Definition: qrhi.cpp:6344
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
Definition: qrhi.cpp:5568
int ubufAlignment() const
Definition: qrhi.cpp:6974
FrameOpResult
Definition: qrhi_p.h:1554
@ FrameOpSuccess
Definition: qrhi_p.h:1555
bool isDeviceLost() const
Definition: qrhi.cpp:6446
void releaseCachedResources()
Definition: qrhi.cpp:6394
std::function< void(QRhi *)> CleanupCallback
Definition: qrhi_p.h:1631
@ EnableProfiling
Definition: qrhi_p.h:1547
@ EnableDebugMarkers
Definition: qrhi_p.h:1548
virtual bool isClipDepthZeroToOne() const =0
virtual void endExternal(QRhiCommandBuffer *cb)=0
virtual QRhiSwapChain * createSwapChain()=0
virtual QRhiBuffer * createBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, int size)=0
virtual void beginPass(QRhiCommandBuffer *cb, QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, QRhiResourceUpdateBatch *resourceUpdates, QRhiCommandBuffer::BeginPassFlags flags)=0
virtual void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps)=0
virtual const QRhiNativeHandles * nativeHandles(QRhiCommandBuffer *cb)=0
virtual void releaseCachedResources()=0
virtual ~QRhiImplementation()
Definition: qrhi.cpp:4592
virtual bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const =0
virtual QRhiDriverInfo driverInfo() const =0
bool isCompressedFormat(QRhiTexture::Format format) const
Definition: qrhi.cpp:4624
void updateLayoutDesc(QRhiShaderResourceBindings *srb)
Definition: qrhi.cpp:3171
virtual bool isYUpInFramebuffer() const =0
virtual void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)=0
virtual void debugMarkEnd(QRhiCommandBuffer *cb)=0
virtual QRhi::FrameOpResult finish()=0
virtual QRhiTexture * createTexture(QRhiTexture::Format format, const QSize &pixelSize, int depth, int arraySize, int sampleCount, QRhiTexture::Flags flags)=0
virtual QRhiComputePipeline * createComputePipeline()=0
virtual QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags)=0
virtual void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)=0
virtual int ubufAlignment() const =0
void compressedFormatInfo(QRhiTexture::Format format, const QSize &size, quint32 *bpl, quint32 *byteSize, QSize *blockDim) const
Definition: qrhi.cpp:4631
virtual QRhiSampler * createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode u, QRhiSampler::AddressMode v, QRhiSampler::AddressMode w)=0
virtual QRhi::FrameOpResult endOffscreenFrame(QRhi::EndFrameFlags flags)=0
quint32 approxByteSizeForTexture(QRhiTexture::Format format, const QSize &baseSize, int depth, int mipCount, int layerCount)
Definition: qrhi.cpp:4819
virtual QRhiShaderResourceBindings * createShaderResourceBindings()=0
virtual void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)=0
virtual QRhiRenderBuffer * createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount, QRhiRenderBuffer::Flags flags, QRhiTexture::Format backingFormatHint)=0
bool sanityCheckShaderResourceBindings(QRhiShaderResourceBindings *srb)
Definition: qrhi.cpp:4869
virtual void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates, QRhiCommandBuffer::BeginPassFlags flags)=0
virtual void setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)=0
virtual void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)=0
virtual int resourceLimit(QRhi::ResourceLimit limit) const =0
virtual void setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBindings *srb, int dynamicOffsetCount, const QRhiCommandBuffer::DynamicOffset *dynamicOffsets)=0
virtual void setPipelineCacheData(const QByteArray &data)=0
virtual bool isDeviceLost() const =0
virtual void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)=0
virtual void beginExternal(QRhiCommandBuffer *cb)=0
virtual QMatrix4x4 clipSpaceCorrMatrix() const =0
virtual void dispatch(QRhiCommandBuffer *cb, int x, int y, int z)=0
virtual bool makeThreadLocalNativeContextCurrent()=0
void addDeleteLater(QRhiResource *res)
Definition: qrhi_p_p.h:211
virtual void setVertexInput(QRhiCommandBuffer *cb, int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings, QRhiBuffer *indexBuf, quint32 indexOffset, QRhiCommandBuffer::IndexFormat indexFormat)=0
virtual QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags)=0
virtual void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)=0
bool sanityCheckGraphicsPipeline(QRhiGraphicsPipeline *ps)
Definition: qrhi.cpp:4835
virtual void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg)=0
virtual QList< int > supportedSampleCounts() const =0
void addCleanupCallback(const QRhi::CleanupCallback &callback)
Definition: qrhi_p_p.h:219
virtual bool isYUpInNDC() const =0
virtual void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount, quint32 instanceCount, quint32 firstIndex, qint32 vertexOffset, quint32 firstInstance)=0
virtual bool isFeatureSupported(QRhi::Feature feature) const =0
virtual void setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline *ps)=0
void textureFormatInfo(QRhiTexture::Format format, const QSize &size, quint32 *bpl, quint32 *byteSize, quint32 *bytesPerPixel) const
Definition: qrhi.cpp:4751
virtual void draw(QRhiCommandBuffer *cb, quint32 vertexCount, quint32 instanceCount, quint32 firstVertex, quint32 firstInstance)=0
virtual void destroy()=0
virtual QByteArray pipelineCacheData()=0
virtual QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags)=0
virtual void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)=0
virtual QRhiTextureRenderTarget * createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags)=0
virtual QRhiGraphicsPipeline * createGraphicsPipeline()=0
static TextureStage toPassTrackerTextureStage(QRhiShaderResourceBinding::StageFlags stages)
Definition: qrhi.cpp:7089
static BufferStage toPassTrackerBufferStage(QRhiShaderResourceBinding::StageFlags stages)
Definition: qrhi.cpp:7075
bool isEmpty() const
Definition: qrhi.cpp:6986
void registerBuffer(QRhiBuffer *buf, int slot, BufferAccess *access, BufferStage *stage, const UsageState &state)
Definition: qrhi.cpp:7003
void registerTexture(QRhiTexture *tex, TextureAccess *access, TextureStage *stage, const UsageState &state)
Definition: qrhi.cpp:7042
static QRhiProfilerPrivate * get(QRhiProfiler *p)
QRhiImplementation * rhiDWhenEnabled
QRhiReadbackDescription()=default
QRhiRenderBuffer(QRhiImplementation *rhi, Type type_, const QSize &pixelSize_, int sampleCount_, Flags flags_, QRhiTexture::Format backingFormatHint_)
Definition: qrhi.cpp:2363
QRhiResource::Type resourceType() const override
Definition: qrhi.cpp:2375
virtual bool createFrom(NativeRenderBuffer src)
Definition: qrhi.cpp:2423
QRhiResource::Type resourceType() const override
Definition: qrhi.cpp:2773
virtual const QRhiNativeHandles * nativeHandles()
Definition: qrhi.cpp:2859
QRhiRenderPassDescriptor(QRhiImplementation *rhi)
Definition: qrhi.cpp:2765
QRhiResource::Type resourceType() const override
Definition: qrhi.cpp:2882
QRhiRenderTarget(QRhiImplementation *rhi)
Definition: qrhi.cpp:2874
QRhiResource(QRhiImplementation *rhi)
Definition: qrhi.cpp:1981
QByteArray m_objectName
Definition: qrhi_p.h:710
@ RenderBuffer
Definition: qrhi_p.h:680
@ RenderPassDescriptor
Definition: qrhi_p.h:681
@ ComputePipeline
Definition: qrhi_p.h:687
@ GraphicsPipeline
Definition: qrhi_p.h:685
@ CommandBuffer
Definition: qrhi_p.h:688
@ TextureRenderTarget
Definition: qrhi_p.h:683
@ ShaderResourceBindings
Definition: qrhi_p.h:684
@ RenderTarget
Definition: qrhi_p.h:682
virtual ~QRhiResource()
Definition: qrhi.cpp:1998
quint64 m_id
Definition: qrhi_p.h:709
QByteArray name() const
Definition: qrhi.cpp:2042
quint64 globalResourceId() const
Definition: qrhi.cpp:2080
void setName(const QByteArray &name)
Definition: qrhi.cpp:2068
QRhiImplementation * m_rhi
Definition: qrhi_p.h:708
void deleteLater()
Definition: qrhi.cpp:2034
void uploadStaticBuffer(QRhiBuffer *buf, int offset, int size, const void *data)
Definition: qrhi.cpp:5346
void merge(QRhiResourceUpdateBatch *other)
Definition: qrhi.cpp:5284
void generateMips(QRhiTexture *tex)
Definition: qrhi.cpp:5543
void uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
Definition: qrhi.cpp:5412
void updateDynamicBuffer(QRhiBuffer *buf, int offset, int size, const void *data)
Definition: qrhi.cpp:5326
void readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
Definition: qrhi.cpp:5519
void readBackBuffer(QRhiBuffer *buf, int offset, int size, QRhiBufferReadbackResult *result)
Definition: qrhi.cpp:5396
void copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc=QRhiTextureCopyDescription())
Definition: qrhi.cpp:5449
bool hasOptimalCapacity() const
Definition: qrhi.cpp:5302
QVarLengthArray< BufferOp, BUFFER_OPS_STATIC_ALLOC > bufferOps
Definition: qrhi_p_p.h:505
bool hasOptimalCapacity() const
Definition: qrhi.cpp:5640
QRhiImplementation * rhi
Definition: qrhi_p_p.h:512
QVarLengthArray< TextureOp, TEXTURE_OPS_STATIC_ALLOC > textureOps
Definition: qrhi_p_p.h:509
static const int BUFFER_OPS_STATIC_ALLOC
Definition: qrhi_p_p.h:504
static QRhiResourceUpdateBatchPrivate * get(QRhiResourceUpdateBatch *b)
Definition: qrhi_p_p.h:520
void merge(QRhiResourceUpdateBatchPrivate *other)
Definition: qrhi.cpp:5623
static const int TEXTURE_OPS_STATIC_ALLOC
Definition: qrhi_p_p.h:508
QRhiResource::Type resourceType() const override
Definition: qrhi.cpp:2746
QRhiSampler(QRhiImplementation *rhi, Filter magFilter_, Filter minFilter_, Filter mipmapMode_, AddressMode u_, AddressMode v_, AddressMode w_)
Definition: qrhi.cpp:2733
size_t qHash(const QRhiScissor &v, size_t seed) noexcept
Definition: qrhi.cpp:1050
bool operator==(const QRhiScissor &a, const QRhiScissor &b) noexcept
Definition: qrhi.cpp:1029
bool operator!=(const QRhiScissor &a, const QRhiScissor &b) noexcept
Definition: qrhi.cpp:1040
QRhiScissor()=default
static QRhiShaderResourceBinding bufferStore(int binding, StageFlags stage, QRhiBuffer *buf)
Definition: qrhi.cpp:3593
static QRhiShaderResourceBinding imageLoadStore(int binding, StageFlags stage, QRhiTexture *tex, int level)
Definition: qrhi.cpp:3511
bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) noexcept
Definition: qrhi.cpp:3774
size_t qHash(const QRhiShaderResourceBinding &b, size_t seed) noexcept
Definition: qrhi.cpp:3784
static QRhiShaderResourceBinding uniformBufferWithDynamicOffset(int binding, StageFlags stage, QRhiBuffer *buf, int size)
Definition: qrhi.cpp:3342
bool isLayoutCompatible(const QRhiShaderResourceBinding &other) const
Definition: qrhi.cpp:3243
static QRhiShaderResourceBinding bufferLoad(int binding, StageFlags stage, QRhiBuffer *buf)
Definition: qrhi.cpp:3537
static QRhiShaderResourceBinding sampledTexture(int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
Definition: qrhi.cpp:3374
static QRhiShaderResourceBinding imageLoad(int binding, StageFlags stage, QRhiTexture *tex, int level)
Definition: qrhi.cpp:3455
bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) noexcept
Definition: qrhi.cpp:3701
static QRhiShaderResourceBinding bufferLoadStore(int binding, StageFlags stage, QRhiBuffer *buf)
Definition: qrhi.cpp:3649
static QRhiShaderResourceBinding imageStore(int binding, StageFlags stage, QRhiTexture *tex, int level)
Definition: qrhi.cpp:3483
static QRhiShaderResourceBinding sampledTextures(int binding, StageFlags stage, int count, const TextureAndSampler *texSamplers)
Definition: qrhi.cpp:3421
static QRhiShaderResourceBinding uniformBuffer(int binding, StageFlags stage, QRhiBuffer *buf)
Definition: qrhi.cpp:3268
static const int LAYOUT_DESC_ENTRIES_PER_BINDING
Definition: qrhi_p.h:428
bool isLayoutCompatible(const QRhiShaderResourceBindings *other) const
Definition: qrhi.cpp:3135
QVarLengthArray< QRhiShaderResourceBinding, BINDING_PREALLOC > m_bindings
Definition: qrhi_p.h:1080
QRhiShaderResourceBindings(QRhiImplementation *rhi)
Definition: qrhi.cpp:3100
static const int BINDING_PREALLOC
Definition: qrhi_p.h:1078
const QRhiShaderResourceBinding * cendBindings() const
Definition: qrhi_p.h:1062
const QRhiShaderResourceBinding * cbeginBindings() const
Definition: qrhi_p.h:1061
QVector< quint32 > m_layoutDesc
Definition: qrhi_p.h:1085
QRhiResource::Type resourceType() const override
Definition: qrhi.cpp:3109
QRhiShaderStage()=default
bool operator==(const QRhiShaderStage &a, const QRhiShaderStage &b) noexcept
Definition: qrhi.cpp:1474
bool operator!=(const QRhiShaderStage &a, const QRhiShaderStage &b) noexcept
Definition: qrhi.cpp:1487
size_t qHash(const QRhiShaderStage &v, size_t seed) noexcept
Definition: qrhi.cpp:1497
QRhiResource::Type resourceType() const override
Definition: qrhi.cpp:4346
QRhiSwapChain(QRhiImplementation *rhi)
Definition: qrhi.cpp:4338
QRhiTexture(QRhiImplementation *rhi, Format format_, const QSize &pixelSize_, int depth_, int arraySize_, int sampleCount_, Flags flags_)
64-bit integer containing the native object handle.
Definition: qrhi.cpp:2596
@ ThreeDimensional
Definition: qrhi_p.h:775
@ TextureArray
Definition: qrhi_p.h:777
QRhiResource::Type resourceType() const override
Definition: qrhi.cpp:2607
@ ASTC_10x8
Definition: qrhi_p.h:824
@ ASTC_12x12
Definition: qrhi_p.h:827
@ ASTC_8x5
Definition: qrhi_p.h:819
@ ASTC_10x5
Definition: qrhi_p.h:822
@ ETC2_RGBA8
Definition: qrhi_p.h:812
@ ASTC_5x5
Definition: qrhi_p.h:816
@ ASTC_4x4
Definition: qrhi_p.h:814
@ ASTC_6x6
Definition: qrhi_p.h:818
@ ASTC_12x10
Definition: qrhi_p.h:826
@ ETC2_RGB8
Definition: qrhi_p.h:810
@ ASTC_5x4
Definition: qrhi_p.h:815
@ RED_OR_ALPHA8
Definition: qrhi_p.h:790
@ ASTC_6x5
Definition: qrhi_p.h:817
@ ASTC_8x8
Definition: qrhi_p.h:821
@ ASTC_10x6
Definition: qrhi_p.h:823
@ ASTC_10x10
Definition: qrhi_p.h:825
@ ETC2_RGB8A1
Definition: qrhi_p.h:811
@ ASTC_8x6
Definition: qrhi_p.h:820
virtual void setNativeLayout(int layout)
Definition: qrhi.cpp:2686
virtual bool createFrom(NativeTexture src)
Definition: qrhi.cpp:2660
virtual NativeTexture nativeTexture()
Definition: qrhi.cpp:2630
QRhiResource::Type resourceType() const override
Definition: qrhi.cpp:2977
QRhiTextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc_, Flags flags_)
Definition: qrhi.cpp:2965
Definition: qrhi_p.h:565
QRhiTextureUploadEntry()=default
bool operator!=(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribute &b) noexcept
Definition: qrhi.cpp:1342
bool operator==(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribute &b) noexcept
Definition: qrhi.cpp:1328
size_t qHash(const QRhiVertexInputAttribute &v, size_t seed) noexcept
Definition: qrhi.cpp:1352
QRhiVertexInputAttribute()=default
bool operator==(const QRhiVertexInputBinding &a, const QRhiVertexInputBinding &b) noexcept
Definition: qrhi.cpp:1161
QRhiVertexInputBinding()=default
size_t qHash(const QRhiVertexInputBinding &v, size_t seed) noexcept
Definition: qrhi.cpp:1184
bool operator!=(const QRhiVertexInputBinding &a, const QRhiVertexInputBinding &b) noexcept
Definition: qrhi.cpp:1174
bool operator!=(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) noexcept
Definition: qrhi.cpp:1403
QRhiViewport()=default
bool operator==(const QRhiViewport &a, const QRhiViewport &b) noexcept
Definition: qrhi.cpp:936
size_t qHash(const QRhiViewport &v, size_t seed) noexcept
Definition: qrhi.cpp:959
bool operator!=(const QRhiViewport &a, const QRhiViewport &b) noexcept
Definition: qrhi.cpp:949
bool isEmpty() const
Definition: qset.h:88
qsizetype count() const
Definition: qset.h:190
void clear()
Definition: qset.h:97
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:55
constexpr int height() const noexcept
Definition: qsize.h:160
constexpr int width() const noexcept
Definition: qsize.h:157
static QThread * currentThread()
Definition: qthread.cpp:879
constexpr size_type size() const noexcept
void resize(qsizetype sz)
qsizetype count() const
void append(const T &t)
QRhiTexture * tex
QRhiShaderResourceBindings * srb
QRhiGraphicsPipeline * ps
qDeleteAll(list.begin(), list.end())
else opt state
[0]
int sampleCount
Definition: examplefw.h:126
auto it unsigned count const
Definition: hb-iter.hh:848
backing_store_ptr info
[4]
Definition: jmemsys.h:161
QRhiTextureRenderTarget * rt
Definition: mrt.cpp:84
QRhiRenderBuffer * rb
QTextStream & hex(QTextStream &stream)
Definition: image.cpp:51
#define Q_BASIC_ATOMIC_INITIALIZER(a)
const int blockSize
#define Q_FALLTHROUGH()
#define Q_UNREACHABLE()
EGLOutputLayerEXT layer
Flags
unsigned int quint32
Definition: qglobal.h:288
size_t quintptr
Definition: qglobal.h:310
int qint32
Definition: qglobal.h:287
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
unsigned long long quint64
Definition: qglobal.h:299
unsigned int uint
Definition: qglobal.h:334
@ desc
@ QtDebugMsg
Definition: qlogging.h:61
#define qWarning
Definition: qlogging.h:179
#define Q_LOGGING_CATEGORY(name,...)
int qFloor(T v)
Definition: qmath.h:78
GLenum type
Definition: qopengl.h:270
GLint location
GLboolean GLboolean GLboolean b
GLbitfield stages
GLsizei const GLfloat * v
[13]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLenum GLuint GLint level
GLboolean r
[2]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLuint end
GLuint sampler
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLenum src
const void GLsizei GLsizei stride
GLint GLsizei width
GLenum GLenum dst
GLenum access
GLenum GLuint GLenum GLsizei const GLchar * buf
GLbitfield flags
GLenum GLuint texture
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLuint name
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLuint counter
void ** params
GLuint res
Definition: qopenglext.h:8867
const GLubyte * c
Definition: qopenglext.h:12701
GLuint entry
Definition: qopenglext.h:11002
GLuint shader
Definition: qopenglext.h:665
GLint limit
Definition: qopenglext.h:9975
GLdouble GLdouble t
[9]
Definition: qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition: qopenglext.h:259
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLdouble s
[6]
Definition: qopenglext.h:235
GLsizeiptr const void GLenum usage
Definition: qopenglext.h:543
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
@ desc
Q_UNUSED(salary)
[21]
QVBoxLayout * layout
QMimeDatabase db
[0]
QSharedPointer< T > other(t)
[5]
view viewport() -> scroll(dx, dy, deviceRect)
QStringList::Iterator it
QStringList list
[0]
Contains information about the underlying native resources of a buffer.
Definition: qrhi_p.h:730
@ IntegratedDevice
Definition: qrhi_p.h:1512
static BufferOp staticUpload(QRhiBuffer *buf, int offset, int size, const void *data)
Definition: qrhi_p_p.h:407
static BufferOp read(QRhiBuffer *buf, int offset, int size, QRhiBufferReadbackResult *result)
Definition: qrhi_p_p.h:427
static void changeToStaticUpload(BufferOp *op, QRhiBuffer *buf, int offset, int size, const void *data)
Definition: qrhi_p_p.h:418
static void changeToDynamicUpdate(BufferOp *op, QRhiBuffer *buf, int offset, int size, const void *data)
Definition: qrhi_p_p.h:398
static BufferOp dynamicUpdate(QRhiBuffer *buf, int offset, int size, const void *data)
Definition: qrhi_p_p.h:387
static TextureOp copy(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc)
Definition: qrhi_p_p.h:475
static TextureOp upload(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
Definition: qrhi_p_p.h:459
static TextureOp genMips(QRhiTexture *tex)
Definition: qrhi_p_p.h:494
static TextureOp read(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
Definition: qrhi_p_p.h:485
TextureAndSampler texSamplers[MAX_TEX_SAMPLER_ARRAY_SIZE]
Definition: qrhi_p.h:395
StorageBufferData sbuf
Definition: qrhi_p.h:410
QRhiShaderResourceBinding::StageFlags stage
Definition: qrhi_p.h:384
SampledTextureData stex
Definition: qrhi_p.h:408
StorageImageData simage
Definition: qrhi_p.h:409
UniformBufferData ubuf
Definition: qrhi_p.h:407
static const int MAX_TEX_SAMPLER_ARRAY_SIZE
Definition: qrhi_p.h:392
union QRhiShaderResourceBinding::Data::@552 u
QRhiShaderResourceBinding::Type type
Definition: qrhi_p.h:385
Contains information about the underlying native resources of a texture.
Definition: qrhi_p.h:830
Definition: moc.h:48
QRhiShaderResourceBinding bindings[2]
Definition: texuploads.cpp:72