199void QSGMaterialShaderPrivate::prepare(QShader::Variant vertexShaderVariant)
204 memset(
static_cast<
void *>(combinedImageSamplerBindings), 0,
sizeof(combinedImageSamplerBindings));
205 memset(
static_cast<
void *>(combinedImageSamplerCount), 0,
sizeof(combinedImageSamplerCount));
206 vertexShader = fragmentShader =
nullptr;
207 masterUniformData.clear();
209 clearCachedRendererData();
211 for (QShader::Stage stage : { QShader::VertexStage, QShader::FragmentStage }) {
212 auto it = shaderFileNames.constFind(stage);
213 if (it != shaderFileNames.cend()) {
214 const QShader s = loadShader(*it);
217 shaders[stage] = ShaderStageData(s);
219 shaderFileNames.erase(it);
223 auto vsIt = shaders.find(QShader::VertexStage);
224 if (vsIt != shaders.end()) {
225 vsIt->shaderVariant = vertexShaderVariant;
226 vsIt->vertexInputLocations.clear();
227 vsIt->qt_order_attrib_location = -1;
229 const QShaderDescription desc = vsIt->shader.description();
230 const QList<QShaderDescription::InOutVariable> vertexInputs = desc.inputVariables();
231 for (
const QShaderDescription::InOutVariable &v : vertexInputs) {
232 if (vertexShaderVariant == QShader::BatchableVertexShader
233 && v.name == QByteArrayLiteral(
"_qt_order")) {
234 vsIt->qt_order_attrib_location = v.location;
236 vsIt->vertexInputLocations.append(v.location);
240 if (vsIt->vertexInputLocations.contains(vsIt->qt_order_attrib_location)) {
241 qWarning(
"Vertex input clash in rewritten (batchable) vertex shader at input location %d. "
242 "Vertex shaders must avoid using this location.", vsIt->qt_order_attrib_location);
246 for (
auto it = shaders.begin(); it != shaders.end(); ++it) {
247 const QShaderDescription desc = it->shader.description();
249 const QList<QShaderDescription::UniformBlock> ubufs = desc.uniformBlocks();
250 const int ubufCount = ubufs.size();
252 qWarning(
"Multiple uniform blocks found in shader. "
253 "This should be avoided as Qt Quick supports only one.");
255 for (
int i = 0; i < ubufCount; ++i) {
256 const QShaderDescription::UniformBlock &ubuf(ubufs[i]);
257 if (ubufBinding == -1 && ubuf.binding >= 0) {
258 ubufBinding = ubuf.binding;
259 ubufSize = ubuf.size;
260 ubufStages |= toSrbStage(it->shader.stage());
261 masterUniformData.fill(
'\0', ubufSize);
262 }
else if (ubufBinding == ubuf.binding && ubuf.binding >= 0) {
263 if (ubuf.size > ubufSize) {
264 ubufSize = ubuf.size;
265 masterUniformData.fill(
'\0', ubufSize);
267 ubufStages |= toSrbStage(it->shader.stage());
269 qWarning(
"Uniform block %s (binding %d) ignored", ubuf.blockName.constData(),
274 const QList<QShaderDescription::InOutVariable> imageSamplers = desc.combinedImageSamplers();
275 const int imageSamplersCount = imageSamplers.size();
276 for (
int i = 0; i < imageSamplersCount; ++i) {
277 const QShaderDescription::InOutVariable &var(imageSamplers[i]);
282 if (var.binding < MAX_SHADER_RESOURCE_BINDINGS) {
283 combinedImageSamplerBindings[var.binding] |= toSrbStage(it->shader.stage());
286 for (
int dim : var.arrayDims)
289 combinedImageSamplerCount[var.binding] = count;
291 qWarning(
"Encountered invalid combined image sampler (%s) binding %d",
292 var.name.constData(), var.binding);
296 if (it.key() == QShader::VertexStage)
297 vertexShader = &it.value();
298 else if (it.key() == QShader::FragmentStage)
299 fragmentShader = &it.value();
302 if (vertexShader && vertexShaderVariant == QShader::BatchableVertexShader && vertexShader->qt_order_attrib_location == -1)
303 qWarning(
"No rewriter-inserted attribute found, this should not happen.");