5#include <QtQuick3DRuntimeRender/private/qssgrhieffectsystem_p.h>
6#include <QtQuick3DRuntimeRender/private/qssgrenderer_p.h>
7#include <QtQuick3DRuntimeRender/private/qssgrhiquadrenderer_p.h>
8#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
9#include <qtquick3d_tracepoints_p.h>
11#include <QtQuick3DUtils/private/qssgassert_p.h>
13#include <QtCore/qloggingcategory.h>
40 : m_sgContext(sgContext)
55 m_outSize = outputSize;
61 const auto foundIt = std::find_if(m_textures.cbegin(), m_textures.cend(), findTexture);
73 const bool gotMatch =
result !=
nullptr;
84 const auto found = std::find_if(m_textures.cbegin(), m_textures.cend(), findUnused);
85 if (found != m_textures.cend()) {
96 QRhi *rhi = m_sgContext->rhi();
98 const bool needsRebuild =
result->texture && (
result->texture->pixelSize() !=
size || formatChanged);
107 }
else if (needsRebuild) {
111 result->texture->create();
114 if (!
result->renderTarget) {
117 result->renderTarget->setRenderPassDescriptor(
result->renderPassDescriptor);
118 result->renderTarget->create();
120 }
else if (needsRebuild) {
122 delete result->renderPassDescriptor;
123 result->renderPassDescriptor =
result->renderTarget->newCompatibleRenderPassDescriptor();
124 result->renderTarget->setRenderPassDescriptor(
result->renderPassDescriptor);
126 result->renderTarget->create();
133 rtName += bufferName;
134 result->renderTarget->setName(rtName);
137 result->name = bufferName;
145 if (!
texture->flags.isSceneLifetime())
149void QSSGRhiEffectSystem::releaseTextures()
151 for (
auto *
t :
std::as_const(m_textures))
160 QSSG_ASSERT(m_sgContext !=
nullptr,
return inTexture);
161 const auto &rhiContext = m_sgContext->rhiContext();
162 const auto &
renderer = m_sgContext->renderer();
165 m_depthTexture = inDepthTexture;
166 m_cameraClipRange = cameraClipRange;
168 m_currentUbufIndex = 0;
169 auto *currentEffect = &firstEffect;
171 auto *latestOutput = doRenderEffect(currentEffect, &firstTex);
172 firstTex.texture =
nullptr;
174 while ((currentEffect = currentEffect->m_nextEffect)) {
175 auto *effectOut = doRenderEffect(currentEffect, latestOutput);
176 releaseTexture(latestOutput);
177 latestOutput = effectOut;
181 return latestOutput ? latestOutput->texture :
nullptr;
184void QSSGRhiEffectSystem::releaseResources()
189 m_shaderPipelines.
clear();
218 switch (theCommand->
m_type) {
220 allocateBufferCmd(
static_cast<QSSGAllocateBuffer *
>(theCommand), inTexture, inEffect);
238 if (applyCommand->m_samplerName.isEmpty())
241 addTextureToShaderPipeline(applyCommand->m_samplerName,
buffer->texture,
buffer->desc);
250 applyValueCmd(
static_cast<QSSGApplyValue *
>(theCommand), inEffect);
255 currentOutput = findTexture(bindCmd->m_bufferName);
260 bindShaderCmd(
static_cast<QSSGBindShader *
>(theCommand), inEffect);
267 inEffect->
outputFormat : targetCmd->m_outputFormat.format;
274 currentOutput = getTexture(tmpName, m_outSize, rhiFormat,
true, inEffect);
275 finalOutputTexture = currentOutput;
280 renderCmd(currentInput, currentOutput);
281 currentInput = inTexture;
291 return finalOutputTexture;
312 if (!m_currentShaderPipeline)
324 bool texAdded =
false;
327 const auto &theBufferManager(m_sgContext->bufferManager());
331 toRhi(textureProperty.minFilterType),
332 toRhi(textureProperty.magFilterType),
334 toRhi(textureProperty.horizontalClampType),
335 toRhi(textureProperty.verticalClampType),
338 addTextureToShaderPipeline(textureProperty.name,
texture.m_texture,
desc);
344 qCDebug(lcEffectSystem) <<
"Using dummy texture for property" << textureProperty.name;
345 addTextureToShaderPipeline(textureProperty.name,
nullptr, {});
353 if (!m_currentShaderPipeline)
358 return (prop.name == inCmd->m_propertyName);
368 "vec2 qt_effectTextureMapUV(vec2 uv)\n"
374 "vec2 qt_effectTextureMapUV(vec2 uv)\n"
376 " return vec2(uv.x, 1.0 - uv.y);\n"
383 bool isYUpInFramebuffer)
386 qCDebug(lcEffectSystem) <<
" generating new shader pipeline for: " <<
key;
416 m_currentTextures.
clear();
417 m_pendingClears.
clear();
418 m_currentShaderPipeline =
nullptr;
420 QRhi *rhi = m_sgContext->rhi();
421 const auto &shaderLib = m_sgContext->shaderLibraryManager();
422 const auto &shaderCache = m_sgContext->shaderCache();
436 const auto it = m_shaderPipelines.
constFind(cacheKey);
437 if (
it != m_shaderPipelines.
cend())
438 m_currentShaderPipeline = (*it).get();
442 if (!m_currentShaderPipeline) {
448 if (!m_currentShaderPipeline && !shaderLib->m_preGeneratedShaderEntries.isEmpty()) {
451 if (foundIt != pregenEntries.
cend()) {
461 m_currentShaderPipeline =
shader.get();
465 if (!m_currentShaderPipeline) {
471 const auto &shaderPipeline = shaderCache->tryNewPipelineFromPersistentCache(qsbcKey,
475 if (shaderPipeline) {
476 m_shaderPipelines.
insert(cacheKey, shaderPipeline);
477 m_currentShaderPipeline = shaderPipeline.get();
481 if (!m_currentShaderPipeline) {
485 const auto &
generator = m_sgContext->shaderProgramGenerator();
488 m_currentShaderPipeline =
stages.get();
493 const auto &rhiContext = m_sgContext->rhiContext();
495 if (m_currentShaderPipeline) {
496 const void *cacheKey1 =
reinterpret_cast<const void *
>(
this);
497 const void *cacheKey2 =
reinterpret_cast<const void *
>(
qintptr(m_currentUbufIndex));
502 m_currentUBufData =
nullptr;
505 rhiContext->stats().registerEffectShaderGenerationTime(
timer.elapsed());
510 if (!m_currentShaderPipeline)
514 qWarning(
"No effect render target?");
520 const auto &rhiContext = m_sgContext->rhiContext();
521 const auto &
renderer = m_sgContext->renderer();
533 if (rt !=
target->renderTarget) {
540 m_pendingClears.
clear();
543 const QSize outputSize =
target->texture->pixelSize();
544 addCommonEffectUniforms(inputSize, outputSize);
546 const void *cacheKey1 =
reinterpret_cast<const void *
>(
this);
547 const void *cacheKey2 =
reinterpret_cast<const void *
>(
qintptr(m_currentUbufIndex));
550 m_currentUBufData =
nullptr;
553 renderer->rhiQuadRenderer()->prepareQuad(rhiContext.get(), rub);
563 qCDebug(lcEffectSystem) <<
" -> texture binding" << binding <<
"for" << rhiTex.name;
565 QRhiTexture *
texture = rhiTex.texture ? rhiTex.texture : rhiContext->dummyTexture({}, rub);
569 rhiContext->sampler(rhiTex.samplerDesc));
579 m_currentUbufIndex++;
584void QSSGRhiEffectSystem::addCommonEffectUniforms(
const QSize &inputSize,
const QSize &outputSize)
586 const auto &rhiContext = m_sgContext->rhiContext();
587 QRhi *rhi = rhiContext->rhi();
591 mvp.
data()[5] = -1.0f;
600 float fc = float(m_sgContext->frameCount());
614 if (m_depthTexture) {
620 addTextureToShaderPipeline(
"qt_depthTexture", m_depthTexture, depthSamplerDesc);
624void QSSGRhiEffectSystem::addTextureToShaderPipeline(
const QByteArray &
name,
628 if (!m_currentShaderPipeline)
638 m_currentTextures.
insert(
name, {
name,
texture, validDescription ? samplerDescription : defaultDescription});
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
const_iterator constFind(const Key &key) const noexcept
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.
float * data()
Returns a pointer to the raw data of this matrix.
static FeatureSet toFeatureSet(const T &ssgFeatureSet)
virtual char * beginFullDynamicBufferUpdateForCurrentFrame()
virtual void endFullDynamicBufferUpdateForCurrentFrame()
To be called when the entire contents of the buffer data has been updated in the memory block returne...
virtual QRhiRenderPassDescriptor * newCompatibleRenderPassDescriptor() const =0
QRhiRenderPassDescriptor * renderPassDescriptor() const
virtual bool create()=0
Creates the corresponding native graphics resources.
Format
Specifies the texture format.
bool isClipDepthZeroToOne() const
bool isYUpInFramebuffer() const
QRhiTextureRenderTarget * newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags={})
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
static const char * toString(QSSGRenderTextureCubeFace value)
static QRhiTexture::Format toRhiFormat(const QSSGRenderTextureFormat format)
static QRhiCommandBuffer::BeginPassFlags commonPassFlags()
QRhiTexture * process(const QSSGRenderEffect &firstEffect, QRhiTexture *inTexture, QRhiTexture *inDepthTexture, QVector2D cameraClipRange)
void setup(QSize outputSize)
static QSSGRenderTextureFormat::Format overriddenOutputFormat(const QSSGRenderEffect *inEffect)
static QSSGRhiShaderPipelinePtr buildShaderForEffect(const QSSGBindShader &inCmd, QSSGProgramGenerator &generator, QSSGShaderLibraryManager &shaderLib, QSSGShaderCache &shaderCache, bool isYUpInFramebuffer)
QSSGRhiEffectSystem(const std::shared_ptr< QSSGRenderContextInterface > &sgContext)
void setUniformValue(char *ubufData, const char *name, const QVariant &value, QSSGRenderShaderDataType type)
void ensureCombinedMainLightsUniformBuffer(QRhiBuffer **ubuf)
int bindingForTexture(const char *name, int hint=-1)
QSSGCustomShaderMetaData getShaderMetaData(const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
QByteArray getShaderSource(const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
const_iterator cend() const noexcept
const_iterator constFind(const T &value) const
iterator insert(const T &value)
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
QByteArray toLatin1() const &
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
The QVector2D class represents a vector or vertex in 2D space.
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
static const QCssKnownValue properties[NumProperties - 1]
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei const GLubyte * commands
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLint GLsizei GLsizei GLenum format
#define Q_QUICK3D_PROFILE_START(Type)
#define Q_QUICK3D_PROFILE_END_WITH_ID(Type, Payload, POID)
#define Q_QUICK3D_PROFILE_END_WITH_STRING(Type, Payload, Str)
#define QSSG_ASSERT(cond, action)
#define QSSGRHICTX_STAT(ctx, f)
std::shared_ptr< QSSGRhiShaderPipeline > QSSGRhiShaderPipelinePtr
QRhiSampler::Filter toRhi(QSSGRenderTextureFilterOp op)
static const char * effect_builtin_textureMapUVFlipped
static const char * effect_builtin_textureMapUV
static QT_BEGIN_NAMESPACE const QRhiShaderResourceBinding::StageFlags VISIBILITY_ALL
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define Q_TRACE_SCOPE(x,...)
QRandomGenerator generator(sseq)
QSvgRenderer * renderer
[0]
QByteArray generateSha() const
QSSGRenderTextureFormat m_format
QSSGRenderTextureFilterOp m_filterOp
QSSGRenderTextureCoordOp m_texCoordOp
QSSGAllocateBufferFlags m_bufferFlags
QByteArray m_propertyName
QByteArray m_propertyName
QByteArray m_shaderPathKey
QSSGRenderTextureFormat m_outputFormat
const char * typeAsString() const
QString debugString() const
QByteArray m_shaderPathKey
QVector< Command > commands
QSSGRenderTextureFormat::Format outputFormat
QVector< Property > properties
QSSGRhiSamplerDescription desc
QRhiRenderPassDescriptor * renderPassDescriptor
QSSGAllocateBufferFlags flags
QRhiTextureRenderTarget * renderTarget
QSSGRhiEffectTexture & operator=(const QSSGRhiEffectTexture &)=delete
const QSSGRhiShaderPipeline * shaderPipeline
QRhiSampler::Filter magFilter
void addUniformBuffer(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiBuffer *buf, int offset, int size)
void addTexture(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
virtual void append(const QByteArray &data)