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
|
// slang-emit-cpp.h
#ifndef SLANG_EMIT_CPP_H
#define SLANG_EMIT_CPP_H
#include "slang-emit-c-like.h"
#include "slang-ir-clone.h"
#include "slang-ir-type-set.h"
#include "slang-hlsl-intrinsic-set.h"
#include "../core/slang-string-slice-pool.h"
namespace Slang
{
class CPPSourceEmitter: public CLikeSourceEmitter
{
public:
typedef CLikeSourceEmitter Super;
typedef uint32_t SemanticUsedFlags;
struct SemanticUsedFlag
{
enum Enum : SemanticUsedFlags
{
DispatchThreadID = 0x01,
GroupThreadID = 0x02,
GroupID = 0x04,
};
};
struct TypeDimension
{
bool isScalar() const { return rowCount <= 1 && colCount <= 1; }
int rowCount;
int colCount;
};
struct GlobalParamInfo
{
typedef GlobalParamInfo ThisType;
bool operator<(const ThisType& rhs) const { return offset < rhs.offset; }
bool operator==(const ThisType& rhs) const { return offset == rhs.offset; }
bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
IRInst* inst;
UInt offset;
UInt size;
};
virtual void useType(IRType* type);
virtual void emitCall(const HLSLIntrinsic* specOp, IRInst* inst, const IRUse* operands, int numOperands, const EmitOpInfo& inOuterPrec);
virtual void emitTypeDefinition(IRType* type);
virtual void emitSpecializedOperationDefinition(const HLSLIntrinsic* specOp);
static UnownedStringSlice getBuiltinTypeName(IROp op);
SourceWriter* getSourceWriter() const { return m_writer; }
CPPSourceEmitter(const Desc& desc);
protected:
// Implement CLikeSourceEmitter interface
virtual void emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformParameterGroupType* type) SLANG_OVERRIDE;
virtual void emitEntryPointAttributesImpl(IRFunc* irFunc, IREntryPointDecoration* entryPointDecor) SLANG_OVERRIDE;
virtual void emitSimpleTypeImpl(IRType* type) SLANG_OVERRIDE;
virtual void emitTypeImpl(IRType* type, const StringSliceLoc* nameLoc) SLANG_OVERRIDE;
virtual void emitVectorTypeNameImpl(IRType* elementType, IRIntegerValue elementCount) SLANG_OVERRIDE;
virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE;
virtual void emitPreprocessorDirectivesImpl() SLANG_OVERRIDE;
virtual void emitSimpleValueImpl(IRInst* value) SLANG_OVERRIDE;
virtual void emitSimpleFuncParamImpl(IRParam* param) SLANG_OVERRIDE;
virtual void emitModuleImpl(IRModule* module) SLANG_OVERRIDE;
virtual void emitSimpleFuncImpl(IRFunc* func) SLANG_OVERRIDE;
virtual void emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPrec) SLANG_OVERRIDE;
virtual void emitParamTypeImpl(IRType* type, String const& name) SLANG_OVERRIDE;
virtual void emitWitnessTable(IRWitnessTable* witnessTable) SLANG_OVERRIDE;
virtual void emitInterface(IRInterfaceType* interfaceType) SLANG_OVERRIDE;
virtual bool tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* varType) SLANG_OVERRIDE;
virtual void emitIntrinsicCallExprImpl(IRCall* inst, IRTargetIntrinsicDecoration* targetIntrinsic, EmitOpInfo const& inOuterPrec) SLANG_OVERRIDE;
virtual void emitLoopControlDecorationImpl(IRLoopControlDecoration* decl) SLANG_OVERRIDE;
// Replaceable for classes derived from CPPSourceEmitter
virtual SlangResult calcTypeName(IRType* type, CodeGenTarget target, StringBuilder& out);
virtual SlangResult calcFuncName(const HLSLIntrinsic* specOp, StringBuilder& out);
virtual SlangResult calcScalarFuncName(HLSLIntrinsic::Op op, IRBasicType* type, StringBuilder& outBuilder);
// Emits a struct of function pointers defined in `interfaceType`.
void _maybeEmitWitnessTableTypeDefinition(IRInterfaceType* interfaceType, const List<IRWitnessTableEntry*>& sortedWitnessTableEntries);
void _maybeEmitSpecializedOperationDefinition(const HLSLIntrinsic* specOp);
void _emitForwardDeclarations(const List<EmitAction>& actions);
void _calcGlobalParams(const List<EmitAction>& actions, List<GlobalParamInfo>& outParams, IRGlobalParam** outEntryPointGlobalParams);
void _emitUniformStateMembers(const List<EmitAction>& actions, IRGlobalParam** outEntryPointGlobalParams);
void _emitAryDefinition(const HLSLIntrinsic* specOp);
// Really we don't want any of these defined like they are here, they should be defined in slang stdlib
void _emitAnyAllDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
void _emitConstructConvertDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
void _emitConstructFromScalarDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
void _emitGetAtDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
void _emitInitDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
void _emitSignature(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
void _emitInOutParamType(IRType* type, String const& name, IRType* valueType);
UnownedStringSlice _getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op op, IRType*const* argTypes, Int argCount, IRType* retType);
static TypeDimension _getTypeDimension(IRType* type, bool vecSwap);
static void _emitAccess(const UnownedStringSlice& name, const TypeDimension& dimension, int row, int col, SourceWriter* writer);
UnownedStringSlice _getScalarFuncName(HLSLIntrinsic::Op operation, IRBasicType* scalarType);
UnownedStringSlice _getFuncName(const HLSLIntrinsic* specOp);
// Returns a StringSlice representing the mangled name of a witness table
// wrapper function.
UnownedStringSlice _getWitnessTableWrapperFuncName(IRFunc* func);
UnownedStringSlice _getTypeName(IRType* type);
SlangResult _calcCPPTextureTypeName(IRTextureTypeBase* texType, StringBuilder& outName);
void _emitEntryPointDefinitionStart(IRFunc* func, IRGlobalParam* entryPointGlobalParams, const String& funcName, const UnownedStringSlice& varyingTypeName);
void _emitEntryPointDefinitionEnd(IRFunc* func);
void _emitEntryPointGroup(const Int sizeAlongAxis[kThreadGroupAxisCount], const String& funcName);
void _emitEntryPointGroupRange(const Int sizeAlongAxis[kThreadGroupAxisCount], const String& funcName);
void _emitInitAxisValues(const Int sizeAlongAxis[kThreadGroupAxisCount], const UnownedStringSlice& mulName, const UnownedStringSlice& addName);
bool _tryEmitInstExprAsIntrinsic(IRInst* inst, const EmitOpInfo& inOuterPrec);
// Emit the actual definition (including intializer list)
// of all the witness table objects in `pendingWitnessTableDefinitions`.
void _emitWitnessTableDefinitions();
// Emit wrapper functions that are referenced in witness tables.
// Wrapper functions wraps the actual member function, and takes a `void*`
// as the `this` parameter instead of the actual object type, so that
// their signature is agnostic to the object type.
void _emitWitnessTableWrappers();
HLSLIntrinsic* _addIntrinsic(HLSLIntrinsic::Op op, IRType* returnType, IRType*const* argTypes, Index argTypeCount);
static bool _isVariable(IROp op);
Dictionary<IRType*, StringSlicePool::Handle> m_typeNameMap;
Dictionary<const HLSLIntrinsic*, StringSlicePool::Handle> m_intrinsicNameMap;
Dictionary<IRFunc*, StringSlicePool::Handle> m_witnessTableWrapperFuncNameMap;
IRTypeSet m_typeSet;
RefPtr<HLSLIntrinsicOpLookup> m_opLookup;
HLSLIntrinsicSet m_intrinsicSet;
HashSet<const HLSLIntrinsic*> m_intrinsicEmitted;
StringSlicePool m_slicePool;
SemanticUsedFlags m_semanticUsedFlags;
// Witness tables pending for emitting their definitions.
// They must be emitted last, after the entire `Context` class so those member functions defined
// in `Context` may be referenced.
List<IRWitnessTable*> pendingWitnessTableDefinitions;
};
}
#endif
|