69void QSSGRenderEffect::finalizeShaders(
const QSSGRenderLayer &layer, QSSGRenderContextInterface *renderContext)
74 if (!shaderPrepData.valid)
77 QRhi *rhi = renderContext->rhiContext()->rhi();
79 for (
int i = 0, ie = shaderPrepData.passes.size(); i != ie; ++i) {
80 const ShaderPrepPassData &pass(shaderPrepData.passes[i]);
84 const bool isLastEffect = m_nextEffect ==
nullptr;
85 const bool isLastPass = i == ie - 1;
86 const bool shouldTonemapIfEnabled = isLastEffect && isLastPass;
88 QSSGShaderFeatures features;
89 QByteArray completeVertexShader;
90 QByteArray completeFragmentShader;
91 QByteArray sourceCodeForHash;
93 const bool multiview = layer.viewCount >= 2;
94 const int srcIdx = multiview ? QSSGRenderCustomMaterial::MultiViewShaderPathKeyIndex : QSSGRenderCustomMaterial::RegularShaderPathKeyIndex;
96 if (!pass.vertexShaderCode[srcIdx].isEmpty()) {
97 QByteArray code = pass.vertexShaderCode[srcIdx];
99 code.append(effect_vertex_main_pre);
100 if (!pass.vertexMetaData[srcIdx].flags.testFlag(QSSGCustomShaderMetaData::OverridesPosition))
101 code.append(effect_vertex_main_position);
102 code.append(effect_vertex_main_post);
103 completeVertexShader = code;
104 sourceCodeForHash += code;
107 if (!pass.fragmentShaderCode[srcIdx].isEmpty()) {
108 QByteArray code = pass.fragmentShaderCode[srcIdx];
109 if (shouldTonemapIfEnabled)
110 code.append(effect_fragment_main_with_tonemapping);
112 code.append(effect_fragment_main);
113 completeFragmentShader = code;
114 sourceCodeForHash += code;
117 QByteArray shaderPathKey = pass.shaderPathKeyPrefix;
118 shaderPathKey.append(
':' + QCryptographicHash::hash(sourceCodeForHash, QCryptographicHash::Algorithm::Sha1).toHex());
123 shaderPathKey.append(rhi->isYUpInFramebuffer() ? QByteArrayLiteral(
":1") : QByteArrayLiteral(
":0"));
125 if (shouldTonemapIfEnabled) {
129 const QSSGRenderLayer::TonemapMode tonemapMode = layer.tonemapMode;
130 shaderPathKey.append(
':' + QByteArray::number(
int(tonemapMode)));
131 QSSGLayerRenderData::setTonemapFeatures(features, tonemapMode);
134 shaderPathKey.append(multiview ? QByteArrayLiteral(
":1") : QByteArrayLiteral(
":0"));
138 if (!completeVertexShader.isEmpty()) {
139 renderContext->shaderLibraryManager()->setShaderSource(shaderPathKey,
140 QSSGShaderCache::ShaderType::Vertex,
141 completeVertexShader,
142 pass.vertexMetaData[srcIdx]);
144 if (!completeFragmentShader.isEmpty()) {
145 QSSGCustomShaderMetaData metaData = pass.fragmentMetaData[srcIdx];
146 metaData.features = features;
147 renderContext->shaderLibraryManager()->setShaderSource(shaderPathKey,
148 QSSGShaderCache::ShaderType::Fragment,
149 completeFragmentShader,
154 delete commands[pass.bindShaderCmdIndex];
155 commands[pass.bindShaderCmdIndex] =
new QSSGBindShader(shaderPathKey);
158 shaderPrepData.valid =
false;