30
30
struct StructFormatData
31
31
{
32
32
ShaderConstant structDef;
33
+ uint32_t pointerTypeId = 0 ;
33
34
uint32_t offset = 0 ;
34
35
};
35
36
@@ -86,6 +87,7 @@ ShaderConstant BufferFormatter::ParseFormatString(const QString &formatString, u
86
87
QRegularExpression structUseRegex (
87
88
lit (" ^" // start of the line
88
89
" ([A-Za-z_][A-Za-z0-9_]*)" // struct type name
90
+ " (\\ *)?" // maybe a pointer
89
91
" \\ s+([A-Za-z@_][A-Za-z0-9@_]*)" // variable name
90
92
" (\\ s*\\ [[0-9]+\\ ])?" // optional array dimension
91
93
" $" ));
@@ -119,6 +121,8 @@ ShaderConstant BufferFormatter::ParseFormatString(const QString &formatString, u
119
121
if (!tightPacking)
120
122
cur->structDef .type .descriptor .arrayByteStride = (cur->offset + 0xFU ) & (~0xFU );
121
123
124
+ cur->pointerTypeId = PointerTypeRegistry::GetTypeID (cur->structDef .type );
125
+
122
126
cur = &root;
123
127
continue ;
124
128
}
@@ -140,6 +144,7 @@ ShaderConstant BufferFormatter::ParseFormatString(const QString &formatString, u
140
144
}
141
145
142
146
cur = &structelems[lastStruct];
147
+ cur->structDef .type .descriptor .name = lastStruct;
143
148
continue ;
144
149
}
145
150
}
@@ -152,34 +157,55 @@ ShaderConstant BufferFormatter::ParseFormatString(const QString &formatString, u
152
157
{
153
158
StructFormatData &structContext = structelems[structMatch.captured (1 )];
154
159
155
- QString varName = structMatch.captured (2 );
160
+ bool isPointer = !structMatch.captured (2 ).trimmed ().isEmpty ();
161
+
162
+ QString varName = structMatch.captured (3 );
156
163
157
- QString arrayDim = structMatch.captured (3 ).trimmed ();
158
- uint32_t arrayCount = 1 ;
159
- if (!arrayDim.isEmpty ())
164
+ if (isPointer)
160
165
{
161
- arrayDim = arrayDim.mid (1 , arrayDim.count () - 2 );
162
- bool ok = false ;
163
- arrayCount = arrayDim.toUInt (&ok);
164
- if (!ok)
165
- arrayCount = 1 ;
166
+ // if not tight packing, align up to pointer size
167
+ if (!tightPacking)
168
+ cur->offset = (cur->offset + 0x7 ) & (~0x7 );
169
+
170
+ el.name = varName;
171
+ el.byteOffset = cur->offset ;
172
+ el.type .descriptor .pointerTypeID = structContext.pointerTypeId ;
173
+ el.type .descriptor .type = VarType::ULong;
174
+ el.type .descriptor .displayAsHex = true ;
175
+ el.type .descriptor .arrayByteStride = 8 ;
176
+
177
+ cur->offset += 8 ;
178
+ cur->structDef .type .members .push_back (el);
166
179
}
180
+ else
181
+ {
182
+ QString arrayDim = structMatch.captured (4 ).trimmed ();
183
+ uint32_t arrayCount = 1 ;
184
+ if (!arrayDim.isEmpty ())
185
+ {
186
+ arrayDim = arrayDim.mid (1 , arrayDim.count () - 2 );
187
+ bool ok = false ;
188
+ arrayCount = arrayDim.toUInt (&ok);
189
+ if (!ok)
190
+ arrayCount = 1 ;
191
+ }
167
192
168
- // cbuffer packing rules, structs are always float4 base aligned
169
- if (!tightPacking)
170
- cur->offset = (cur->offset + 0xFU ) & (~0xFU );
193
+ // cbuffer packing rules, structs are always float4 base aligned
194
+ if (!tightPacking)
195
+ cur->offset = (cur->offset + 0xFU ) & (~0xFU );
171
196
172
- el = structContext.structDef ;
173
- el.name = varName;
174
- el.byteOffset = cur->offset ;
175
- el.type .descriptor .elements = arrayCount;
197
+ el = structContext.structDef ;
198
+ el.name = varName;
199
+ el.byteOffset = cur->offset ;
200
+ el.type .descriptor .elements = arrayCount;
176
201
177
- cur->structDef .type .members .push_back (el);
202
+ cur->structDef .type .members .push_back (el);
178
203
179
- // undo the padding after the last struct
180
- uint32_t padding = el.type .descriptor .arrayByteStride - structContext.offset ;
204
+ // undo the padding after the last struct
205
+ uint32_t padding = el.type .descriptor .arrayByteStride - structContext.offset ;
181
206
182
- cur->offset += el.type .descriptor .elements * el.type .descriptor .arrayByteStride - padding;
207
+ cur->offset += el.type .descriptor .elements * el.type .descriptor .arrayByteStride - padding;
208
+ }
183
209
184
210
continue ;
185
211
}
@@ -760,7 +786,24 @@ QString BufferFormatter::DeclareStruct(QList<QString> &declaredStructs, const QS
760
786
761
787
QString varTypeName = members[i].type .descriptor .name ;
762
788
763
- if (!members[i].type .members .isEmpty ())
789
+ if (members[i].type .descriptor .pointerTypeID != ~0U )
790
+ {
791
+ const ShaderVariableType &pointeeType =
792
+ PointerTypeRegistry::GetTypeDescriptor (members[i].type .descriptor .pointerTypeID );
793
+
794
+ varTypeName = pointeeType.descriptor .name ;
795
+
796
+ if (!declaredStructs.contains (varTypeName))
797
+ {
798
+ declaredStructs.push_back (varTypeName);
799
+ ret = DeclareStruct (declaredStructs, varTypeName, pointeeType.members ,
800
+ pointeeType.descriptor .arrayByteStride ) +
801
+ lit (" \n " ) + ret;
802
+ }
803
+
804
+ varTypeName += lit (" *" );
805
+ }
806
+ else if (!members[i].type .members .isEmpty ())
764
807
{
765
808
// GL structs don't give us typenames (boo!) so give them unique names. This will mean some
766
809
// structs get duplicated if they're used in multiple places, but not much we can do about
@@ -1453,6 +1496,9 @@ QString TypeString(const ShaderVariable &v)
1453
1496
return QFormatStr (" %1[%2]" ).arg (TypeString (v.members [0 ])).arg (v.members .count ());
1454
1497
}
1455
1498
1499
+ if (v.isPointer )
1500
+ return PointerTypeRegistry::GetTypeDescriptor (v.GetPointer ()).descriptor .name + " *" ;
1501
+
1456
1502
QString typeStr = ToQStr (v.type );
1457
1503
1458
1504
if (v.displayAsHex )
@@ -1504,6 +1550,9 @@ QString RowString(const ShaderVariable &v, uint32_t row, VarType type)
1504
1550
if (type == VarType::Unknown)
1505
1551
type = v.type ;
1506
1552
1553
+ if (v.isPointer )
1554
+ return ToQStr (v.GetPointer ());
1555
+
1507
1556
if (type == VarType::Double)
1508
1557
return RowValuesToString ((int )v.columns , v.displayAsHex , v.value .dv [row * v.columns + 0 ],
1509
1558
v.value .dv [row * v.columns + 1 ], v.value .dv [row * v.columns + 2 ],
@@ -1562,6 +1611,9 @@ QString RowTypeString(const ShaderVariable &v)
1562
1611
if (v.rows == 0 && v.columns == 0 )
1563
1612
return lit (" -" );
1564
1613
1614
+ if (v.isPointer )
1615
+ return PointerTypeRegistry::GetTypeDescriptor (v.GetPointer ()).descriptor .name + " *" ;
1616
+
1565
1617
QString typeStr = ToQStr (v.type );
1566
1618
1567
1619
if (v.displayAsHex )
0 commit comments