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