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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
// slang-artifact-associated-impl.h
#ifndef SLANG_ARTIFACT_ASSOCIATED_IMPL_H
#define SLANG_ARTIFACT_ASSOCIATED_IMPL_H
#include "../core/slang-com-object.h"
#include "../core/slang-memory-arena.h"
#include "slang-artifact-associated.h"
#include "slang-artifact-diagnostic-util.h"
#include "slang-artifact-util.h"
#include "slang-com-helper.h"
#include "slang-com-ptr.h"
namespace Slang
{
class ArtifactDiagnostics : public ComBaseObject, public IArtifactDiagnostics
{
public:
typedef ArtifactDiagnostics ThisType;
SLANG_COM_BASE_IUNKNOWN_ALL
// ICastable
SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
// IClonable
SLANG_NO_THROW virtual void* SLANG_MCALL clone(const Guid& intf) SLANG_OVERRIDE;
// IDiagnostic
SLANG_NO_THROW virtual const Diagnostic* SLANG_MCALL getAt(Index i) SLANG_OVERRIDE
{
return &m_diagnostics[i];
}
SLANG_NO_THROW virtual Count SLANG_MCALL getCount() SLANG_OVERRIDE
{
return m_diagnostics.getCount();
}
SLANG_NO_THROW virtual void SLANG_MCALL add(const Diagnostic& diagnostic) SLANG_OVERRIDE;
SLANG_NO_THROW virtual void SLANG_MCALL removeAt(Index i) SLANG_OVERRIDE
{
m_diagnostics.removeAt(i);
}
SLANG_NO_THROW virtual SlangResult SLANG_MCALL getResult() SLANG_OVERRIDE { return m_result; }
SLANG_NO_THROW virtual void SLANG_MCALL setResult(SlangResult res) SLANG_OVERRIDE
{
m_result = res;
}
SLANG_NO_THROW virtual void SLANG_MCALL setRaw(const CharSlice& slice) SLANG_OVERRIDE;
SLANG_NO_THROW virtual void SLANG_MCALL appendRaw(const CharSlice& slice) SLANG_OVERRIDE;
SLANG_NO_THROW virtual TerminatedCharSlice SLANG_MCALL getRaw() SLANG_OVERRIDE
{
return SliceUtil::asTerminatedCharSlice(m_raw);
}
SLANG_NO_THROW virtual void SLANG_MCALL reset() SLANG_OVERRIDE;
SLANG_NO_THROW virtual Count SLANG_MCALL getCountAtLeastSeverity(Diagnostic::Severity severity)
SLANG_OVERRIDE;
SLANG_NO_THROW virtual Count SLANG_MCALL getCountBySeverity(Diagnostic::Severity severity)
SLANG_OVERRIDE;
SLANG_NO_THROW virtual bool SLANG_MCALL hasOfAtLeastSeverity(Diagnostic::Severity severity)
SLANG_OVERRIDE;
SLANG_NO_THROW virtual Count SLANG_MCALL getCountByStage(
Diagnostic::Stage stage,
Count outCounts[Int(Diagnostic::Severity::CountOf)]) SLANG_OVERRIDE;
SLANG_NO_THROW virtual void SLANG_MCALL removeBySeverity(Diagnostic::Severity severity)
SLANG_OVERRIDE;
SLANG_NO_THROW virtual void SLANG_MCALL maybeAddNote(const CharSlice& in) SLANG_OVERRIDE;
SLANG_NO_THROW virtual void SLANG_MCALL requireErrorDiagnostic() SLANG_OVERRIDE;
SLANG_NO_THROW virtual void SLANG_MCALL calcSummary(ISlangBlob** outBlob) SLANG_OVERRIDE;
SLANG_NO_THROW virtual void SLANG_MCALL calcSimplifiedSummary(ISlangBlob** outBlob)
SLANG_OVERRIDE;
/// Default ctor
ArtifactDiagnostics()
: ComBaseObject()
{
}
/// Copy ctor
ArtifactDiagnostics(const ThisType& rhs);
/// Create
static ComPtr<IArtifactDiagnostics> create()
{
return ComPtr<IArtifactDiagnostics>(new ThisType);
}
protected:
void* getInterface(const Guid& uuid);
void* getObject(const Guid& uuid);
SliceAllocator m_allocator;
List<Diagnostic> m_diagnostics;
SlangResult m_result = SLANG_OK;
// Raw diagnostics
StringBuilder m_raw;
};
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactPostEmitMetadata !!!!!!!!!!!!!!!!!!!!!!!!!! */
struct ShaderBindingRange
{
slang::ParameterCategory category = slang::ParameterCategory::None;
UInt spaceIndex = 0;
UInt registerIndex = 0;
UInt registerCount = 0; // 0 for unsized
bool isInfinite() const { return registerCount == 0; }
bool containsBinding(slang::ParameterCategory _category, UInt _spaceIndex, UInt _registerIndex)
const
{
return category == _category && spaceIndex == _spaceIndex &&
registerIndex <= _registerIndex &&
(isInfinite() || registerCount + registerIndex > _registerIndex);
}
bool intersectsWith(const ShaderBindingRange& other) const
{
if (category != other.category || spaceIndex != other.spaceIndex)
return false;
const bool leftIntersection =
(registerIndex < other.registerIndex + other.registerCount) || other.isInfinite();
const bool rightIntersection =
(other.registerIndex < registerIndex + registerCount) || isInfinite();
return leftIntersection && rightIntersection;
}
bool adjacentTo(const ShaderBindingRange& other) const
{
if (category != other.category || spaceIndex != other.spaceIndex)
return false;
const bool leftIntersection =
(registerIndex <= other.registerIndex + other.registerCount) || other.isInfinite();
const bool rightIntersection =
(other.registerIndex <= registerIndex + registerCount) || isInfinite();
return leftIntersection && rightIntersection;
}
void mergeWith(const ShaderBindingRange other)
{
UInt newRegisterIndex = Math::Min(registerIndex, other.registerIndex);
if (other.isInfinite())
registerCount = 0;
else if (!isInfinite())
registerCount = Math::Max(
registerIndex + registerCount,
other.registerIndex + other.registerCount) -
newRegisterIndex;
registerIndex = newRegisterIndex;
}
static bool isUsageTracked(slang::ParameterCategory category)
{
switch (category)
{
case slang::ConstantBuffer:
case slang::ShaderResource:
case slang::UnorderedAccess:
case slang::SamplerState:
case slang::DescriptorTableSlot:
case slang::VaryingInput:
case slang::VaryingOutput:
case slang::SpecializationConstant:
case slang::SubElementRegisterSpace:
return true;
default:
return false;
}
}
};
class ArtifactPostEmitMetadata : public ComBaseObject, public IArtifactPostEmitMetadata
{
public:
typedef ArtifactPostEmitMetadata ThisType;
SLANG_CLASS_GUID(0x6f82509f, 0xe48b, 0x4b83, {0xa3, 0x84, 0x5d, 0x70, 0x83, 0x19, 0x83, 0xcc})
SLANG_COM_BASE_IUNKNOWN_ALL
// ICastable
SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
// IArtifactPostEmitMetadata
SLANG_NO_THROW virtual Slice<ShaderBindingRange> SLANG_MCALL getUsedBindingRanges()
SLANG_OVERRIDE;
SLANG_NO_THROW virtual Slice<String> SLANG_MCALL getExportedFunctionMangledNames()
SLANG_OVERRIDE;
// IMetadata
SLANG_NO_THROW virtual SlangResult isParameterLocationUsed(
SlangParameterCategory category, // is this a `t` register? `s` register?
SlangUInt spaceIndex, // `space` for D3D12, `set` for Vulkan
SlangUInt registerIndex, // `register` for D3D12, `binding` for Vulkan
bool& outUsed) SLANG_OVERRIDE;
SLANG_NO_THROW virtual const char* SLANG_MCALL getDebugBuildIdentifier() SLANG_OVERRIDE;
void* getInterface(const Guid& uuid);
void* getObject(const Guid& uuid);
static ComPtr<IArtifactPostEmitMetadata> create()
{
return ComPtr<IArtifactPostEmitMetadata>(new ThisType);
}
List<ShaderBindingRange> m_usedBindings;
List<String> m_exportedFunctionMangledNames;
String m_debugBuildIdentifier;
};
} // namespace Slang
#endif
|