1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QSSGSHADERRESOURCEMERGECONTEXT_P_H
5#define QSSGSHADERRESOURCEMERGECONTEXT_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qssgrendershadercodegenerator_p.h"
19#include "qssgrendershadermetadata_p.h"
20
21QT_BEGIN_NAMESPACE
22
23class QSSGShaderResourceMergeContext
24{
25public:
26 // Resource bindings 0..2 are reserved for uniform buffers.
27 // (0 is cbMain, 1 is cbLights)
28 static const int FIRST_CUSTOM_RESOURCE_BINDING_POINT = 3;
29
30 struct InOutVar {
31 QSSGShaderGeneratorStageFlags stageOutputFrom;
32 QSSGShaderGeneratorStageFlags stagesInputIn;
33 QByteArray type;
34 QByteArray name;
35 int location;
36 bool output;
37 };
38
39 struct Sampler {
40 QByteArray type;
41 QByteArray name;
42 QSSGRenderShaderMetadata::Uniform::Condition conditionType;
43 QByteArray conditionName;
44 int binding;
45 };
46
47 struct BlockMember {
48 QByteArray type;
49 QByteArray name;
50 QSSGRenderShaderMetadata::Uniform::Condition conditionType;
51 QByteArray conditionName;
52 };
53
54 // Using QMap intentionally - while it is not strictly required to use an
55 // ordered map, being sorted by key when iterating is helpful to get the
56 // same ordered list of vertex inputs, uniforms, etc. on every run, which
57 // in turn helps shader (disk) cache efficiency due to not generating a
58 // different shader string just because QHash decided to iterate entries in
59 // a different order.
60 QMap<QByteArray, InOutVar> m_inOutVars;
61 QMap<QByteArray, Sampler> m_samplers;
62 QMap<QByteArray, BlockMember> m_uniformMembers;
63
64 int m_nextFreeResourceBinding = FIRST_CUSTOM_RESOURCE_BINDING_POINT;
65 QHash<int, int> m_nextFreeInLocation;
66 QHash<int, int> m_nextFreeOutLocation;
67
68 void registerInput(QSSGShaderGeneratorStage stage, const QByteArray &type, const QByteArray &name)
69 {
70 auto it = m_inOutVars.find(key: name);
71 if (it != m_inOutVars.end()) {
72 it->stagesInputIn |= stage;
73 return;
74 }
75 InOutVar var { .stageOutputFrom: {}, .stagesInputIn: stage, .type: type, .name: name, .location: m_nextFreeInLocation[int(stage)]++, .output: false };
76 m_inOutVars.insert(key: name, value: var);
77 }
78
79 void registerOutput(QSSGShaderGeneratorStage stage, const QByteArray &type, const QByteArray &name)
80 {
81 auto it = m_inOutVars.find(key: name);
82 if (it != m_inOutVars.end()) {
83 it->stageOutputFrom |= stage;
84 return;
85 }
86 InOutVar var { .stageOutputFrom: stage, .stagesInputIn: {}, .type: type, .name: name, .location: m_nextFreeOutLocation[int(stage)]++, .output: true };
87 m_inOutVars.insert(key: name, value: var);
88 }
89
90 void registerSampler(const QByteArray &type,
91 const QByteArray &name,
92 QSSGRenderShaderMetadata::Uniform::Condition conditionType = QSSGRenderShaderMetadata::Uniform::None,
93 const QByteArray &conditionName = QByteArray())
94 {
95 if (m_samplers.contains(key: name))
96 return;
97 Sampler var { .type: type, .name: name, .conditionType: conditionType, .conditionName: conditionName, .binding: m_nextFreeResourceBinding++ };
98 m_samplers.insert(key: name, value: var);
99 }
100
101 void registerUniformMember(const QByteArray &type,
102 const QByteArray &name,
103 QSSGRenderShaderMetadata::Uniform::Condition conditionType = QSSGRenderShaderMetadata::Uniform::None,
104 const QByteArray &conditionName = QByteArray())
105 {
106 auto it = m_uniformMembers.constFind(key: name);
107 if (it != m_uniformMembers.constEnd()) {
108 if (it->conditionType != conditionType) {
109 qWarning(msg: "Encountered uniform %s with different conditions, this is not supported.",
110 name.constData());
111 }
112 return;
113 }
114 BlockMember var { .type: type, .name: name, .conditionType: conditionType, .conditionName: conditionName };
115 m_uniformMembers.insert(key: name, value: var);
116 }
117};
118
119QT_END_NAMESPACE
120
121#endif
122

source code of qtquick3d/src/runtimerender/qssgshaderresourcemergecontext_p.h