5#include <QtQuick3DUtils/private/qssgmesh_p.h>
6#include <QtQuick3DUtils/private/qssgassert_p.h>
7#include <QtQuick3DRuntimeRender/private/qssgrenderableimage_p.h>
8#include <QtQuick3DRuntimeRender/private/qssgrendermesh_p.h>
9#include <QtQuick3DUtils/private/qssgutils_p.h>
10#include <QtQuick3DUtils/private/qssgassert_p.h>
11#include <QtCore/QVariant>
12#include <qtquick3d_tracepoints_p.h>
23 QRhiBuffer::UsageFlags usageMask,
29 m_indexFormat(indexFormat)
34 qWarning(
"Failed to build QRhiBuffer with size %d", m_buffer->
size());
115 const auto &vertexInputs =
shaders.vertexInputs();
121 auto vertexInputVar = vertexInputs.constFind(
sem);
122 if (vertexInputVar != vertexInputs.constEnd()) {
124 attrs.last().setLocation(vertexInputVar->location);
131 if (instanceBufferBinding > 0) {
132 auto instanceBufferLocations =
shaders.instanceBufferLocations();
135 instanceBufferLocations.transform0,
140 instanceBufferLocations.transform1,
145 instanceBufferLocations.transform2,
147 sizeof(
float) * 4 * 2));
150 instanceBufferLocations.color,
152 sizeof(
float) * 4 * 3));
155 instanceBufferLocations.data,
157 sizeof(
float) * 4 * 4));
165 switch (cullFaceMode) {
173 qWarning(
"FrontAndBack cull mode not supported");
195 if (blk.binding == 0) {
196 m_ub0Size = blk.size;
227 }
else if (
var.name ==
"qt_instanceTransform0") {
229 }
else if (
var.name ==
"qt_instanceTransform1") {
231 }
else if (
var.name ==
"qt_instanceTransform2") {
233 }
else if (
var.name ==
"qt_instanceColor") {
235 }
else if (
var.name ==
"qt_instanceData") {
246 m_combinedImageSamplers[
var.name] =
var;
248 std::fill(m_materialImageSamplerBindings,
310 const float v = inValue.
value<
float>();
377 float v[2] = { float(
s.width()), float(
s.height()) };
384 float v[2] = { float(
s.width()), float(
s.height()) };
391 float v[2] = { float(
p.x()), float(
p.y()) };
398 float v[2] = { float(
p.x()), float(
p.y()) };
405 float v[4] = { float(
r.x()), float(
r.y()), float(
r.width()), float(
r.height()) };
412 float v[4] = { float(
r.x()), float(
r.y()), float(
r.width()), float(
r.height()) };
419 float v[4] = { float(
q.x()), float(
q.y()), float(
q.z()), float(
q.scalar()) };
424 qWarning(
"Attempted to set uniform %s value with unsupported data type %i",
441 if (!storeIndex || *storeIndex == -1) {
444 if (
it != m_uniformIndex.
cend()) {
451 const int new_idx = m_uniforms.
size();
452 m_uniformIndex[
name] = new_idx;
456 qWarning(
"Attempted to set uniform with too long name: %s",
name);
468 if (u.offset == SIZE_MAX && u.maybeExists) {
471 u.offset =
it->offset;
474 qWarning(
"Uniform block member '%s' got %d bytes whereas the true size is %d",
475 it->name.constData(),
483 if (u.offset == SIZE_MAX) {
485 u.maybeExists =
false;
489 char *
dst = ubufData + u.offset;
493 const float *
src =
static_cast<const float *
>(
data);
494 memcpy(
dst,
src, 3 *
sizeof(
float));
495 memcpy(
dst + 4 *
sizeof(
float),
src + 3, 3 *
sizeof(
float));
496 memcpy(
dst + 8 *
sizeof(
float),
src + 6, 3 *
sizeof(
float));
511 constexpr size_t std140BaseTypeSize = 4 *
sizeof(float);
513 if (!storeIndex || *storeIndex == -1) {
517 if (
it != m_uniformIndex.
cend()) {
519 ua = &m_uniformArrays[
index];
524 ua = &m_uniformArrays.
last();
527 qWarning(
"Attempted to set uniform array with too long name: %s",
name);
533 ua = &m_uniformArrays[*storeIndex];
539 if (ua->offset == SIZE_MAX && ua->maybeExists) {
542 ua->offset =
it->offset;
546 if (ua->offset == SIZE_MAX) {
548 ua->maybeExists =
false;
556 if (uniformSize != ua->size) {
557 qWarning(
"Uniform block member '%s' got %d bytes whereas the true size is %d",
567 char *
p = ubufData + ua->offset;
581 for (
size_t i = 0;
i < itemCount; ++
i)
582 memcpy(
p +
i * std140BaseTypeSize, &
v[
i], ua->
typeSize);
596 for (
size_t i = 0;
i < itemCount; ++
i)
597 memcpy(
p +
i * std140BaseTypeSize, &
v[
i], ua->
typeSize);
611 for (
size_t i = 0;
i < itemCount; ++
i)
612 memcpy(
p +
i * std140BaseTypeSize, &
v[
i], ua->
typeSize);
631 const float *
v =
static_cast<const float *
>(
data);
640 for (
size_t i = 0;
i < itemCount; ++
i)
641 memcpy(
p +
i * std140BaseTypeSize, &
v[
i], ua->
typeSize);
655 for (
size_t i = 0;
i < itemCount; ++
i)
656 memcpy(
p +
i * std140BaseTypeSize, &
v[
i], ua->
typeSize);
670 for (
size_t i = 0;
i < itemCount; ++
i)
671 memcpy(
p +
i * std140BaseTypeSize, &
v[
i], ua->
typeSize);
699 for (
size_t i = 0;
i < itemCount; ++
i) {
701 memcpy(
p +
i * std140BaseTypeSize, &vi, ua->
typeSize);
716 for (
size_t i = 0;
i < itemCount; ++
i)
717 memcpy(
p +
i * std140BaseTypeSize, &
v[
i], ua->
typeSize);
731 for (
size_t i = 0;
i < itemCount; ++
i)
732 memcpy(
p +
i * std140BaseTypeSize, &
v[
i], ua->
typeSize);
746 for (
size_t i = 0;
i < itemCount; ++
i)
747 memcpy(
p +
i * std140BaseTypeSize, &
v[
i], ua->
typeSize);
776 memcpy(
p +
i * ua->
typeSize,
v[
i].constData(), 3 *
sizeof(
float));
777 memcpy(
p +
i * ua->
typeSize + 4 *
sizeof(
float),
v[
i].constData() + 3, 3 *
sizeof(
float));
778 memcpy(
p +
i * ua->
typeSize + 8 *
sizeof(
float),
v[
i].constData() + 6, 3 *
sizeof(
float));
809 qWarning(
"Attempted to set uniform %s value with type %d that is unsupported for uniform arrays",
822 if ((*ubuf)->size() < totalBufferSize) {
823 (*ubuf)->setSize(totalBufferSize);
839 const int binding = m_materialImageSamplerBindings[
hint];
845 const int binding =
it != m_combinedImageSamplers.
cend() ?
it->binding : -1;
847 m_materialImageSamplerBindings[
hint] = binding;
873 m_drawCallData.
clear();
881 m_computePipelines.
clear();
883 m_dummyTextures.
clear();
885 for (
const auto &samplerInfo : std::as_const(m_samplers))
886 delete samplerInfo.second;
890 for (
const auto &
particleData : std::as_const(m_particleData))
893 m_particleData.
clear();
895 for (
const auto &instanceData : std::as_const(m_instanceBuffers)) {
896 if (instanceData.owned)
897 delete instanceData.buffer;
900 m_instanceBuffers.
clear();
902 for (
const auto &instanceData : std::as_const(m_instanceBuffersLod)) {
903 if (instanceData.owned)
904 delete instanceData.buffer;
907 m_instanceBuffersLod.
clear();
956 ps->
setShaderStages(
key.state.shaderPipeline->cbeginStages(),
key.state.shaderPipeline->cendStages());
961 QRhiGraphicsPipeline::Flags
flags;
962 if (
key.state.scissorEnable)
978 for (
int i = 0;
i <
key.state.colorAttachmentCount; ++
i)
979 targetBlends[
i] = blend;
992 if (
key.state.usesStencilRef)
1000 qWarning(
"Failed to build graphics pipeline state");
1020 qWarning(
"Failed to build compute pipeline");
1032 auto compareSampler = [samplerDescription](
const SamplerInfo &
info){
return info.first == samplerDescription; };
1033 const auto found = std::find_if(m_samplers.cbegin(), m_samplers.cend(), compareSampler);
1034 if (found != m_samplers.cend())
1035 return found->second;
1039 samplerDescription.
mipmap,
1043 if (!newSampler->
create()) {
1044 qWarning(
"Failed to build image sampler");
1048 m_samplers <<
SamplerInfo{samplerDescription, newSampler};
1066 static bool warnShown =
false;
1069 qWarning(
"Attempted to use an unsupported filtering or wrap mode, "
1070 "this is likely due to lacking proper support for non-power-of-two textures on this platform.\n"
1071 "If this is with WebGL, try updating the application to use QQuick3D::idealSurfaceFormat() in main() "
1072 "in order to ensure WebGL 2 is used.");
1101 for (
auto subset : mesh->
subsets) {
1102 if (subset.rhi.targetsTexture)
1113 const void *modelNode =
model;
1114 auto it = m_drawCallData.
begin();
1115 while (
it != m_drawCallData.
end()) {
1116 if (
it.key().model == modelNode) {
1135 image.fill(fillColor);
1138 qWarning(
"Failed to build dummy texture");
1161 info.renderPasses.clear();
1162 info.externalRenderPass = {};
1163 info.currentRenderPassIndex = -1;
1170 const int rpCount =
info.renderPasses.
size();
1171 qDebug(
"%d render passes in 3D renderer %p", rpCount,
layer);
1172 for (
int i = 0;
i < rpCount; ++
i) {
1174 qDebug(
"Render pass %d: rt name='%s' target size %dx%d pixels",
1178 if (
info.externalRenderPass.indexedDraws.callCount ||
info.externalRenderPass.instancedIndexedDraws.callCount
1179 ||
info.externalRenderPass.draws.callCount ||
info.externalRenderPass.instancedDraws.callCount)
1181 qDebug(
"Within external render passes:");
1205 info.currentRenderPassIndex =
info.renderPasses.
size() - 1;
1210 Q_TRACE(QSSG_renderPass_exit);
1212 info.currentRenderPassIndex = -1;
1228 rp.instancedIndexedDraws.vertexOrIndexCount += indexCount;
1231 rp.indexedDraws.callCount += 1;
1232 rp.indexedDraws.vertexOrIndexCount += indexCount;
1243 rp.instancedDraws.vertexOrIndexCount += vertexCount;
1246 rp.draws.callCount += 1;
1247 rp.draws.vertexOrIndexCount += vertexCount;
1253 qDebug(
"%llu indexed draw calls with %llu indices in total, "
1254 "%llu non-indexed draw calls with %llu vertices in total",
1258 qDebug(
"%llu instanced indexed draw calls with %llu indices and %llu instances in total, "
1259 "%llu instanced non-indexed draw calls with %llu indices and %llu instances in total",
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
The QColor class provides colors based on RGB, HSV or CMYK values.
qint64 size() const
Returns the file size in bytes.
iterator begin()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
const_iterator constFind(const Key &key) const noexcept
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
T take(const Key &key)
Removes the item with the key from the hash and returns the value associated with it.
iterator erase(const_iterator it)
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
const_iterator cend() const noexcept
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
The QQuaternion class represents a quaternion consisting of a vector and scalar.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
Type
Specifies storage type of buffer resource.
virtual bool create()=0
Creates the corresponding native graphics resources.
IndexFormat
Specifies the index data type.
void setShaderStage(const QRhiShaderStage &stage)
Sets the shader to use.
void setShaderResourceBindings(QRhiShaderResourceBindings *srb)
Associates with srb describing the resource binding layout and the resources (QRhiBuffer,...
@ CompileShadersWithDebugInfo
void setStencilFront(const StencilOpState &state)
Sets the stencil test state for front faces.
void setCullMode(CullMode mode)
Sets the specified face culling mode.
void setTargetBlends(std::initializer_list< TargetBlend > list)
Sets the list of render target blend settings.
void setStencilTest(bool enable)
Enables or disables stencil tests based on enable.
void setDepthWrite(bool enable)
Controls the writing out of depth data into the depth buffer based on enable.
void setShaderResourceBindings(QRhiShaderResourceBindings *srb)
Associates with srb describing the resource binding layout and the resources (QRhiBuffer,...
void setDepthOp(CompareOp op)
Sets the depth comparison function op.
void setSlopeScaledDepthBias(float bias)
Sets the slope scaled depth bias.
void setVertexInputLayout(const QRhiVertexInputLayout &layout)
Specifies the vertex input layout.
CullMode
Specifies the culling mode.
void setFlags(Flags f)
Sets the flags f.
void setShaderStages(std::initializer_list< QRhiShaderStage > list)
Sets the list of shader stages.
void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc)
Associates with the specified QRhiRenderPassDescriptor desc.
void setSampleCount(int s)
Sets the sample count.
void setTopology(Topology t)
Sets the primitive topology t.
Topology
Specifies the primitive topology.
virtual bool create()=0
Creates the corresponding native graphics resources.
void setDepthTest(bool enable)
Enables or disables depth testing based on enable.
void setDepthBias(int bias)
Sets the depth bias.
void setPolygonMode(PolygonMode mode)
Sets the polygon mode.
void setLineWidth(float width)
Sets the line width.
void setStencilWriteMask(quint32 mask)
Sets the stencil write mask.
virtual QSize pixelSize() const =0
void uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
Enqueues uploading the image data for one or more mip levels in one or more layers of the texture tex...
void setBindings(std::initializer_list< QRhiShaderResourceBinding > list)
Sets the list of bindings.
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
int ubufAligned(int v) const
bool isFeatureSupported(QRhi::Feature feature) const
QRhiShaderResourceBindings * newShaderResourceBindings()
QRhiComputePipeline * newComputePipeline()
QRhiSampler * newSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode addressU, QRhiSampler::AddressMode addressV, QRhiSampler::AddressMode addressW=QRhiSampler::Repeat)
QRhiGraphicsPipeline * newGraphicsPipeline()
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
QSSGRhiBuffer(QSSGRhiContext &context, QRhiBuffer::Type type, QRhiBuffer::UsageFlags usageMask, quint32 stride, qsizetype size, QRhiCommandBuffer::IndexFormat indexFormat=QRhiCommandBuffer::IndexUInt16)
static bool rendererDebugEnabled()
void start(QSSGRenderLayer *layer)
QSSGRenderLayer * layerKey
void cleanupLayerInfo(QSSGRenderLayer *layer)
void beginRenderPass(QRhiTextureRenderTarget *rt)
static bool profilingEnabled()
QHash< QSSGRenderLayer *, PerLayerInfo > perLayerInfo
void drawIndexed(quint32 indexCount, quint32 instanceCount)
void draw(quint32 vertexCount, quint32 instanceCount)
void stop(QSSGRenderLayer *layer)
QSet< QSSGRenderLayer * > dynamicDataSources
void printRenderPass(const RenderPassInfo &rp)
QRhiTexture * dummyTexture(QRhiTexture::Flags flags, QRhiResourceUpdateBatch *rub, const QSize &size=QSize(64, 64), const QColor &fillColor=Qt::black)
void releaseDrawCallData(QSSGRhiDrawCallData &dcd)
void initialize(QRhi *rhi)
void cleanupDrawCallData(const QSSGRenderModel *model)
void releaseMesh(QSSGRenderMesh *mesh)
static bool shaderDebuggingEnabled()
QSSGRhiContext(QRhi *rhi=nullptr)
void checkAndAdjustForNPoT(QRhiTexture *texture, QSSGRhiSamplerDescription *samplerDescription)
void registerMesh(QSSGRenderMesh *mesh)
void releaseCachedResources()
void releaseTexture(QRhiTexture *texture)
void registerTexture(QRhiTexture *texture)
QRhiShaderResourceBindings * srb(const QSSGRhiShaderResourceBindingList &bindings)
QRhiComputePipeline * computePipeline(const QSSGComputePipelineStateKey &key, QRhiShaderResourceBindings *srb)
QRhiGraphicsPipeline * pipeline(const QSSGGraphicsPipelineStateKey &key, QRhiRenderPassDescriptor *rpDesc, QRhiShaderResourceBindings *srb)
QRhiSampler * sampler(const QSSGRhiSamplerDescription &samplerDescription)
QSSGRhiParticleData & particleData(const QSSGRenderGraphObject *particlesOrModel)
void setUniformValue(char *ubufData, const char *name, const QVariant &value, QSSGRenderShaderDataType type)
void addStage(const QRhiShaderStage &stage, StageFlags flags={})
void ensureUniformBuffer(QRhiBuffer **ubuf)
int offsetOfUniform(const QByteArray &name)
void ensureCombinedMainLightsUniformBuffer(QRhiBuffer **ubuf)
int bindingForTexture(const char *name, int hint=-1)
void setUniformArray(char *ubufData, const char *name, const void *data, size_t itemCount, QSSGRenderShaderDataType type, int *storeIndex=nullptr)
struct QSSGRhiShaderPipeline::InstanceLocations instanceLocations
void setUniform(char *ubufData, const char *name, const void *data, size_t size, int *storeIndex=nullptr, UniformFlags flags={})
bool remove(const T &value)
iterator insert(const T &value)
QList< InOutVariable > inputVariables() const
QList< InOutVariable > combinedImageSamplers() const
QList< UniformBlock > uniformBlocks() const
QShaderDescription description() const
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
constexpr size_type size() const noexcept
const T & at(qsizetype idx) const
const_iterator cbegin() const noexcept
const_iterator cend() const noexcept
void push_back(const T &t)
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
const void * constData() const
The QVector2D class represents a vector or vertex in 2D space.
The QVector3D class represents a vector or vertex in 3D space.
The QVector4D class represents a vector or vertex in 4D space.
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
Combined button and popup list for selecting options.
#define Q_STATIC_ASSERT(Condition)
std::pair< T1, T2 > QPair
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter * iter
static struct AttrInfo attrs[]
constexpr quint32 qNextPowerOfTwo(quint32 v)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
const void GLsizei GLsizei stride
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat GLfloat GLfloat h
GLdouble GLdouble GLdouble GLdouble q
GLsizei GLsizei GLuint * shaders
#define QSSG_ASSERT_X(cond, msg, action)
#define QSSG_ASSERT(cond, action)
QPair< QSSGRhiSamplerDescription, QRhiSampler * > SamplerInfo
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
#define Q_TRACE_ENABLED(x)
#define Q_TRACE_POINT(provider, tracepoint,...)
QSqlQueryModel * model
[16]
QFileInfo info(fileName)
[8]
static const char * getLightmapUVAttrName()
static const char * getNormalAttrName()
static const char * getUV1AttrName()
static const char * getTexBinormalAttrName()
static const char * getPositionAttrName()
static const char * getTexTanAttrName()
static const char * getColorAttrName()
static const char * getJointAttrName()
static const char * getUV0AttrName()
static const char * getWeightAttrName()
QVector< QSSGRenderSubset > subsets
quint64 vertexOrIndexCount
quint64 vertexOrIndexCount
InstancedDrawInfo instancedDraws
InstancedDrawInfo instancedIndexedDraws
QSSGRhiShaderResourceBindingList bindings
QRhiShaderResourceBindings * srb
QRhiGraphicsPipeline * pipeline
static QRhiGraphicsPipeline::CullMode toCullMode(QSSGCullFaceMode cullFaceMode)
QRhiSampler::AddressMode hTiling
QRhiSampler::Filter minFilter
QRhiSampler::Filter magFilter
QRhiSampler::AddressMode vTiling
QRhiSampler::Filter mipmap
QRhiSampler::AddressMode zTiling
QRhiShaderResourceBinding v[MAX_SIZE]
\variable QShaderDescription::InOutVariable::name