67void QSSGRenderEffect::finalizeShaders(
const QSSGRenderLayer &layer, QSSGRenderContextInterface *renderContext)
72 if (!shaderPrepData.valid)
75 QRhi *rhi = renderContext->rhiContext()->rhi();
77 for (
int i = 0, ie = shaderPrepData.passes.size(); i != ie; ++i) {
78 const ShaderPrepPassData &pass(shaderPrepData.passes[i]);
82 const bool isLastEffect = m_nextEffect ==
nullptr;
83 const bool isLastPass = i == ie - 1;
84 const bool shouldTonemapIfEnabled = isLastEffect && isLastPass;
86 QSSGShaderFeatures features;
87 QByteArray completeVertexShader;
88 QByteArray completeFragmentShader;
89 QByteArray sourceCodeForHash;
91 const bool multiview = layer.viewCount >= 2;
92 const int srcIdx = multiview ? QSSGRenderCustomMaterial::MultiViewShaderPathKeyIndex : QSSGRenderCustomMaterial::RegularShaderPathKeyIndex;
94 if (!pass.vertexShaderCode[srcIdx].isEmpty()) {
95 QByteArray code = pass.vertexShaderCode[srcIdx];
97 code.append(effect_vertex_main_pre);
98 if (!pass.vertexMetaData[srcIdx].flags.testFlag(QSSGCustomShaderMetaData::OverridesPosition))
99 code.append(effect_vertex_main_position);
100 code.append(effect_vertex_main_post);
101 completeVertexShader = code;
102 sourceCodeForHash += code;
105 if (!pass.fragmentShaderCode[srcIdx].isEmpty()) {
106 QByteArray code = pass.fragmentShaderCode[srcIdx];
107 if (shouldTonemapIfEnabled)
108 code.append(effect_fragment_main_with_tonemapping);
110 code.append(effect_fragment_main);
111 completeFragmentShader = code;
112 sourceCodeForHash += code;
115 QByteArray shaderPathKey = pass.shaderPathKeyPrefix;
116 shaderPathKey.append(
':' + QCryptographicHash::hash(sourceCodeForHash, QCryptographicHash::Algorithm::Sha1).toHex());
121 shaderPathKey.append(rhi->isYUpInFramebuffer() ? QByteArrayLiteral(
":1") : QByteArrayLiteral(
":0"));
123 if (shouldTonemapIfEnabled) {
127 const QSSGRenderLayer::TonemapMode tonemapMode = layer.tonemapMode;
128 shaderPathKey.append(
':' + QByteArray::number(
int(tonemapMode)));
129 QSSGLayerRenderData::setTonemapFeatures(features, tonemapMode);
132 shaderPathKey.append(multiview ? QByteArrayLiteral(
":1") : QByteArrayLiteral(
":0"));
136 if (!completeVertexShader.isEmpty()) {
137 renderContext->shaderLibraryManager()->setShaderSource(shaderPathKey,
138 QSSGShaderCache::ShaderType::Vertex,
139 completeVertexShader,
140 pass.vertexMetaData[srcIdx]);
142 if (!completeFragmentShader.isEmpty()) {
143 QSSGCustomShaderMetaData metaData = pass.fragmentMetaData[srcIdx];
144 metaData.features = features;
145 renderContext->shaderLibraryManager()->setShaderSource(shaderPathKey,
146 QSSGShaderCache::ShaderType::Fragment,
147 completeFragmentShader,
152 delete commands[pass.bindShaderCmdIndex];
153 commands[pass.bindShaderCmdIndex] =
new QSSGBindShader(shaderPathKey);
156 shaderPrepData.valid =
false;