blob: 6d36a1770c2fd89700dc87a30f44e9847a194d64 [file] [log] [blame]
Jamie Madill8daaba12014-06-13 10:04:33 -04001//
2// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// StructureHLSL.cpp:
7// Definitions of methods for HLSL translation of GLSL structures.
8//
9
10#include "compiler/translator/StructureHLSL.h"
11#include "common/utilities.h"
12#include "compiler/translator/OutputHLSL.h"
13#include "compiler/translator/Types.h"
14#include "compiler/translator/util.h"
15#include "compiler/translator/UtilsHLSL.h"
16
17namespace sh
18{
19
Jamie Madill33a74bd2014-08-18 15:47:59 -040020Std140PaddingHelper::Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
21 unsigned *uniqueCounter)
Jamie Madilld7b1ab52016-12-12 14:42:19 -050022 : mPaddingCounter(uniqueCounter), mElementIndex(0), mStructElementIndexes(&structElementIndexes)
23{
24}
Jamie Madill8daaba12014-06-13 10:04:33 -040025
Jamie Madill80d934b2015-02-19 10:16:12 -050026Std140PaddingHelper::Std140PaddingHelper(const Std140PaddingHelper &other)
27 : mPaddingCounter(other.mPaddingCounter),
28 mElementIndex(other.mElementIndex),
29 mStructElementIndexes(other.mStructElementIndexes)
Jamie Madilld7b1ab52016-12-12 14:42:19 -050030{
31}
Jamie Madill80d934b2015-02-19 10:16:12 -050032
33Std140PaddingHelper &Std140PaddingHelper::operator=(const Std140PaddingHelper &other)
34{
Jamie Madilld7b1ab52016-12-12 14:42:19 -050035 mPaddingCounter = other.mPaddingCounter;
36 mElementIndex = other.mElementIndex;
Jamie Madill80d934b2015-02-19 10:16:12 -050037 mStructElementIndexes = other.mStructElementIndexes;
38 return *this;
39}
40
Jamie Madill33a74bd2014-08-18 15:47:59 -040041TString Std140PaddingHelper::next()
42{
43 unsigned value = (*mPaddingCounter)++;
44 return str(value);
45}
46
Jamie Madill8daaba12014-06-13 10:04:33 -040047int Std140PaddingHelper::prePadding(const TType &type)
48{
49 if (type.getBasicType() == EbtStruct || type.isMatrix() || type.isArray())
50 {
51 // no padding needed, HLSL will align the field to a new register
52 mElementIndex = 0;
53 return 0;
54 }
55
Jamie Madilld7b1ab52016-12-12 14:42:19 -050056 const GLenum glType = GLVariableType(type);
Jamie Madillf2575982014-06-25 16:04:54 -040057 const int numComponents = gl::VariableComponentCount(glType);
Jamie Madill8daaba12014-06-13 10:04:33 -040058
59 if (numComponents >= 4)
60 {
61 // no padding needed, HLSL will align the field to a new register
62 mElementIndex = 0;
63 return 0;
64 }
65
66 if (mElementIndex + numComponents > 4)
67 {
68 // no padding needed, HLSL will align the field to a new register
69 mElementIndex = numComponents;
70 return 0;
71 }
72
Jamie Madilld7b1ab52016-12-12 14:42:19 -050073 const int alignment = numComponents == 3 ? 4 : numComponents;
Jamie Madill8daaba12014-06-13 10:04:33 -040074 const int paddingOffset = (mElementIndex % alignment);
Jamie Madilld7b1ab52016-12-12 14:42:19 -050075 const int paddingCount = (paddingOffset != 0 ? (alignment - paddingOffset) : 0);
Jamie Madill8daaba12014-06-13 10:04:33 -040076
77 mElementIndex += paddingCount;
78 mElementIndex += numComponents;
79 mElementIndex %= 4;
80
81 return paddingCount;
82}
83
84TString Std140PaddingHelper::prePaddingString(const TType &type)
85{
86 int paddingCount = prePadding(type);
87
88 TString padding;
89
90 for (int paddingIndex = 0; paddingIndex < paddingCount; paddingIndex++)
91 {
Jamie Madill33a74bd2014-08-18 15:47:59 -040092 padding += " float pad_" + next() + ";\n";
Jamie Madill8daaba12014-06-13 10:04:33 -040093 }
94
95 return padding;
96}
97
98TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRowMajorPacking)
99{
100 if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct)
101 {
102 return "";
103 }
104
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500105 int numComponents = 0;
Jamie Madill8daaba12014-06-13 10:04:33 -0400106 TStructure *structure = type.getStruct();
107
108 if (type.isMatrix())
109 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500110 // This method can also be called from structureString, which does not use layout
111 // qualifiers.
Jamie Madill8daaba12014-06-13 10:04:33 -0400112 // Thus, use the method parameter for determining the matrix packing.
113 //
114 // Note HLSL row major packing corresponds to GL API column-major, and vice-versa, since we
115 // wish to always transpose GL matrices to play well with HLSL's matrix array indexing.
116 //
117 const bool isRowMajorMatrix = !useHLSLRowMajorPacking;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500118 const GLenum glType = GLVariableType(type);
119 numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix);
Jamie Madill8daaba12014-06-13 10:04:33 -0400120 }
121 else if (structure)
122 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500123 const TString &structName =
124 QualifiedStructNameString(*structure, useHLSLRowMajorPacking, true);
Jamie Madill80d934b2015-02-19 10:16:12 -0500125 numComponents = mStructElementIndexes->find(structName)->second;
Jamie Madill8daaba12014-06-13 10:04:33 -0400126
127 if (numComponents == 0)
128 {
129 return "";
130 }
131 }
132 else
133 {
134 const GLenum glType = GLVariableType(type);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500135 numComponents = gl::VariableComponentCount(glType);
Jamie Madill8daaba12014-06-13 10:04:33 -0400136 }
137
138 TString padding;
139 for (int paddingOffset = numComponents; paddingOffset < 4; paddingOffset++)
140 {
Jamie Madill33a74bd2014-08-18 15:47:59 -0400141 padding += " float pad_" + next() + ";\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400142 }
143 return padding;
144}
145
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500146StructureHLSL::StructureHLSL() : mUniquePaddingCounter(0)
147{
148}
Jamie Madill8daaba12014-06-13 10:04:33 -0400149
Jamie Madill33a74bd2014-08-18 15:47:59 -0400150Std140PaddingHelper StructureHLSL::getPaddingHelper()
151{
152 return Std140PaddingHelper(mStd140StructElementIndexes, &mUniquePaddingCounter);
153}
154
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500155TString StructureHLSL::defineQualified(const TStructure &structure,
156 bool useHLSLRowMajorPacking,
157 bool useStd140Packing)
Jamie Madill8daaba12014-06-13 10:04:33 -0400158{
159 if (useStd140Packing)
160 {
Jamie Madill33a74bd2014-08-18 15:47:59 -0400161 Std140PaddingHelper padHelper = getPaddingHelper();
Jamie Madill8daaba12014-06-13 10:04:33 -0400162 return define(structure, useHLSLRowMajorPacking, useStd140Packing, &padHelper);
163 }
164 else
165 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +0800166 return define(structure, useHLSLRowMajorPacking, useStd140Packing, nullptr);
Jamie Madill8daaba12014-06-13 10:04:33 -0400167 }
168}
169
170TString StructureHLSL::defineNameless(const TStructure &structure)
171{
Yunchao Hef81ce4a2017-04-24 10:49:17 +0800172 return define(structure, false, false, nullptr);
Jamie Madill8daaba12014-06-13 10:04:33 -0400173}
174
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500175TString StructureHLSL::define(const TStructure &structure,
176 bool useHLSLRowMajorPacking,
177 bool useStd140Packing,
178 Std140PaddingHelper *padHelper)
Jamie Madill8daaba12014-06-13 10:04:33 -0400179{
180 const TFieldList &fields = structure.fields();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500181 const bool isNameless = (structure.name() == "");
182 const TString &structName =
183 QualifiedStructNameString(structure, useHLSLRowMajorPacking, useStd140Packing);
Jamie Madill8daaba12014-06-13 10:04:33 -0400184 const TString declareString = (isNameless ? "struct" : "struct " + structName);
185
186 TString string;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500187 string += declareString +
188 "\n"
Jamie Madill8daaba12014-06-13 10:04:33 -0400189 "{\n";
190
Olli Etuaho96963162016-03-21 11:54:33 +0200191 for (const TField *field : fields)
Jamie Madill8daaba12014-06-13 10:04:33 -0400192 {
Olli Etuaho96963162016-03-21 11:54:33 +0200193 const TType &fieldType = *field->type();
194 if (!IsSampler(fieldType.getBasicType()))
Jamie Madill8daaba12014-06-13 10:04:33 -0400195 {
Olli Etuaho96963162016-03-21 11:54:33 +0200196 const TStructure *fieldStruct = fieldType.getStruct();
197 const TString &fieldTypeString =
198 fieldStruct ? QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking,
199 useStd140Packing)
200 : TypeString(fieldType);
Jamie Madill8daaba12014-06-13 10:04:33 -0400201
Olli Etuaho96963162016-03-21 11:54:33 +0200202 if (padHelper)
203 {
204 string += padHelper->prePaddingString(fieldType);
205 }
Jamie Madill8daaba12014-06-13 10:04:33 -0400206
Olli Etuaho96963162016-03-21 11:54:33 +0200207 string += " " + fieldTypeString + " " + DecorateField(field->name(), structure) +
208 ArrayString(fieldType) + ";\n";
209
210 if (padHelper)
211 {
212 string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking);
213 }
Jamie Madill8daaba12014-06-13 10:04:33 -0400214 }
215 }
216
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500217 // Nameless structs do not finish with a semicolon and newline, to leave room for an instance
218 // variable
Jamie Madill8daaba12014-06-13 10:04:33 -0400219 string += (isNameless ? "} " : "};\n");
220
221 return string;
222}
223
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200224TString StructureHLSL::addConstructor(const TType &type,
225 const TString &name,
226 const TIntermSequence *parameters)
Jamie Madill8daaba12014-06-13 10:04:33 -0400227{
228 if (name == "")
229 {
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200230 return TString(); // Nameless structures don't have constructors
Jamie Madill8daaba12014-06-13 10:04:33 -0400231 }
232
233 if (type.getStruct() && mStructNames.find(name) != mStructNames.end())
234 {
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200235 return TString(name); // Already added
Jamie Madill8daaba12014-06-13 10:04:33 -0400236 }
237
238 TType ctorType = type;
239 ctorType.clearArrayness();
240 ctorType.setPrecision(EbpHigh);
241 ctorType.setQualifier(EvqTemporary);
242
243 typedef std::vector<TType> ParameterArray;
244 ParameterArray ctorParameters;
245
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200246 TString constructorFunctionName;
247
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500248 const TStructure *structure = type.getStruct();
Jamie Madill8daaba12014-06-13 10:04:33 -0400249 if (structure)
250 {
Olli Etuahoc2157a02017-08-09 18:52:59 +0300251 const TFieldList &fields = structure->fields();
252 for (const TField *field : fields)
253 {
254 const TType *fieldType = field->type();
255 if (!IsSampler(fieldType->getBasicType()))
256 {
257 ctorParameters.push_back(*fieldType);
258 }
259 if (fieldType->getBasicType() == EbtStruct)
260 {
261 addConstructor(*fieldType, StructNameString(*fieldType->getStruct()), nullptr);
262 }
263 }
264
Jamie Madill8daaba12014-06-13 10:04:33 -0400265 mStructNames.insert(name);
266
267 // Add element index
268 storeStd140ElementIndex(*structure, false);
269 storeStd140ElementIndex(*structure, true);
270
271 const TString &structString = defineQualified(*structure, false, false);
272
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500273 if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) ==
274 mStructDeclarations.end())
Jamie Madill8daaba12014-06-13 10:04:33 -0400275 {
276 // Add row-major packed struct for interface blocks
277 TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500278 defineQualified(*structure, true, false) +
279 "#pragma pack_matrix(column_major)\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400280
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500281 TString std140String = defineQualified(*structure, false, true);
Jamie Madill8daaba12014-06-13 10:04:33 -0400282 TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500283 defineQualified(*structure, true, true) +
284 "#pragma pack_matrix(column_major)\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400285
286 mStructDeclarations.push_back(structString);
287 mStructDeclarations.push_back(rowMajorString);
288 mStructDeclarations.push_back(std140String);
289 mStructDeclarations.push_back(std140RowMajorString);
290 }
291
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200292 constructorFunctionName = TString(name);
Jamie Madill8daaba12014-06-13 10:04:33 -0400293 }
294 else if (parameters)
295 {
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200296 for (auto parameter : *parameters)
Jamie Madill8daaba12014-06-13 10:04:33 -0400297 {
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200298 const TType &paramType = parameter->getAsTyped()->getType();
299 ctorParameters.push_back(paramType);
Jamie Madill8daaba12014-06-13 10:04:33 -0400300 }
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200301 constructorFunctionName = TString(name) + DisambiguateFunctionName(parameters);
Jamie Madill8daaba12014-06-13 10:04:33 -0400302 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500303 else
304 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400305
306 TString constructor;
307
308 if (ctorType.getStruct())
309 {
310 constructor += name + " " + name + "_ctor(";
311 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500312 else // Built-in type
Jamie Madill8daaba12014-06-13 10:04:33 -0400313 {
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200314 constructor += TypeString(ctorType) + " " + constructorFunctionName + "(";
Jamie Madill8daaba12014-06-13 10:04:33 -0400315 }
316
317 for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++)
318 {
Austin Kinross3ae64652015-01-26 15:51:39 -0800319 const TType &paramType = ctorParameters[parameter];
Jamie Madill8daaba12014-06-13 10:04:33 -0400320
Austin Kinross3ae64652015-01-26 15:51:39 -0800321 constructor += TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType);
Jamie Madill8daaba12014-06-13 10:04:33 -0400322
323 if (parameter < ctorParameters.size() - 1)
324 {
325 constructor += ", ";
326 }
327 }
328
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500329 constructor +=
330 ")\n"
331 "{\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400332
333 if (ctorType.getStruct())
334 {
Olli Etuaho96963162016-03-21 11:54:33 +0200335 constructor += " " + name + " structure";
336 if (ctorParameters.empty())
337 {
338 constructor += ";\n";
339 }
340 else
341 {
342 constructor += " = { ";
343 }
Jamie Madill8daaba12014-06-13 10:04:33 -0400344 }
345 else
346 {
347 constructor += " return " + TypeString(ctorType) + "(";
348 }
349
350 if (ctorType.isMatrix() && ctorParameters.size() == 1)
351 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500352 int rows = ctorType.getRows();
353 int cols = ctorType.getCols();
Jamie Madill8daaba12014-06-13 10:04:33 -0400354 const TType &parameter = ctorParameters[0];
355
356 if (parameter.isScalar())
357 {
Jamie Madillcf3af0b2014-08-01 17:22:16 -0400358 for (int col = 0; col < cols; col++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400359 {
Jamie Madillcf3af0b2014-08-01 17:22:16 -0400360 for (int row = 0; row < rows; row++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400361 {
362 constructor += TString((row == col) ? "x0" : "0.0");
363
364 if (row < rows - 1 || col < cols - 1)
365 {
366 constructor += ", ";
367 }
368 }
369 }
370 }
371 else if (parameter.isMatrix())
372 {
Jamie Madillf4e39bf2014-08-01 17:22:17 -0400373 for (int col = 0; col < cols; col++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400374 {
Jamie Madillf4e39bf2014-08-01 17:22:17 -0400375 for (int row = 0; row < rows; row++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400376 {
377 if (row < parameter.getRows() && col < parameter.getCols())
378 {
Jamie Madillf4e39bf2014-08-01 17:22:17 -0400379 constructor += TString("x0") + "[" + str(col) + "][" + str(row) + "]";
Jamie Madill8daaba12014-06-13 10:04:33 -0400380 }
381 else
382 {
383 constructor += TString((row == col) ? "1.0" : "0.0");
384 }
385
386 if (row < rows - 1 || col < cols - 1)
387 {
388 constructor += ", ";
389 }
390 }
391 }
392 }
393 else
394 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500395 ASSERT(rows == 2 && cols == 2 && parameter.isVector() &&
396 parameter.getNominalSize() == 4);
Jamie Madill8daaba12014-06-13 10:04:33 -0400397
398 constructor += "x0";
399 }
400 }
401 else
402 {
Olli Etuaho96963162016-03-21 11:54:33 +0200403 size_t remainingComponents = 0;
404 if (ctorType.getStruct())
405 {
406 remainingComponents = ctorParameters.size();
407 }
408 else
409 {
410 remainingComponents = ctorType.getObjectSize();
411 }
Jamie Madill8daaba12014-06-13 10:04:33 -0400412 size_t parameterIndex = 0;
413
414 while (remainingComponents > 0)
415 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500416 const TType &parameter = ctorParameters[parameterIndex];
Jamie Madill8daaba12014-06-13 10:04:33 -0400417 const size_t parameterSize = parameter.getObjectSize();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500418 bool moreParameters = parameterIndex + 1 < ctorParameters.size();
Jamie Madill8daaba12014-06-13 10:04:33 -0400419
420 constructor += "x" + str(parameterIndex);
421
422 if (ctorType.getStruct())
423 {
Olli Etuaho96963162016-03-21 11:54:33 +0200424 ASSERT(remainingComponents == 1 || moreParameters);
Jamie Madill8daaba12014-06-13 10:04:33 -0400425
Olli Etuaho96963162016-03-21 11:54:33 +0200426 --remainingComponents;
Jamie Madill8daaba12014-06-13 10:04:33 -0400427 }
428 else if (parameter.isScalar())
429 {
430 remainingComponents -= parameter.getObjectSize();
431 }
432 else if (parameter.isVector())
433 {
434 if (remainingComponents == parameterSize || moreParameters)
435 {
436 ASSERT(parameterSize <= remainingComponents);
437 remainingComponents -= parameterSize;
438 }
439 else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize()))
440 {
441 switch (remainingComponents)
442 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500443 case 1:
444 constructor += ".x";
445 break;
446 case 2:
447 constructor += ".xy";
448 break;
449 case 3:
450 constructor += ".xyz";
451 break;
452 case 4:
453 constructor += ".xyzw";
454 break;
455 default:
456 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400457 }
458
459 remainingComponents = 0;
460 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500461 else
462 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400463 }
464 else if (parameter.isMatrix())
465 {
466 int column = 0;
467 while (remainingComponents > 0 && column < parameter.getCols())
468 {
469 constructor += "[" + str(column) + "]";
470
471 if (remainingComponents < static_cast<size_t>(parameter.getRows()))
472 {
473 switch (remainingComponents)
474 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500475 case 1:
476 constructor += ".x";
477 break;
478 case 2:
479 constructor += ".xy";
480 break;
481 case 3:
482 constructor += ".xyz";
483 break;
484 default:
485 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400486 }
487
488 remainingComponents = 0;
489 }
490 else
491 {
492 remainingComponents -= parameter.getRows();
493
494 if (remainingComponents > 0)
495 {
496 constructor += ", x" + str(parameterIndex);
497 }
498 }
499
500 column++;
501 }
502 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500503 else
504 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400505
506 if (moreParameters)
507 {
508 parameterIndex++;
509 }
510
511 if (remainingComponents)
512 {
513 constructor += ", ";
514 }
515 }
516 }
517
518 if (ctorType.getStruct())
519 {
Olli Etuaho96963162016-03-21 11:54:33 +0200520 if (!ctorParameters.empty())
521 {
522 constructor += "};\n";
523 }
524 constructor +=
525 " return structure;\n"
526 "}\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400527 }
528 else
529 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500530 constructor +=
531 ");\n"
532 "}\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400533 }
534
535 mConstructors.insert(constructor);
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200536
537 return constructorFunctionName;
Jamie Madill8daaba12014-06-13 10:04:33 -0400538}
539
540std::string StructureHLSL::structsHeader() const
541{
542 TInfoSinkBase out;
543
544 for (size_t structIndex = 0; structIndex < mStructDeclarations.size(); structIndex++)
545 {
546 out << mStructDeclarations[structIndex];
547 }
548
Jamie Madill961d5e92014-06-20 15:23:34 -0400549 for (Constructors::const_iterator constructor = mConstructors.begin();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500550 constructor != mConstructors.end(); constructor++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400551 {
552 out << *constructor;
553 }
554
555 return out.str();
556}
557
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500558void StructureHLSL::storeStd140ElementIndex(const TStructure &structure,
559 bool useHLSLRowMajorPacking)
Jamie Madill8daaba12014-06-13 10:04:33 -0400560{
Jamie Madill33a74bd2014-08-18 15:47:59 -0400561 Std140PaddingHelper padHelper = getPaddingHelper();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500562 const TFieldList &fields = structure.fields();
Jamie Madill8daaba12014-06-13 10:04:33 -0400563
Olli Etuahoc2157a02017-08-09 18:52:59 +0300564 for (const TField *field : fields)
Jamie Madill8daaba12014-06-13 10:04:33 -0400565 {
Olli Etuahoc2157a02017-08-09 18:52:59 +0300566 padHelper.prePadding(*field->type());
Jamie Madill8daaba12014-06-13 10:04:33 -0400567 }
568
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500569 // Add remaining element index to the global map, for use with nested structs in standard
570 // layouts
Jamie Madill8daaba12014-06-13 10:04:33 -0400571 const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking, true);
572 mStd140StructElementIndexes[structName] = padHelper.elementIndex();
573}
Olli Etuahoc2157a02017-08-09 18:52:59 +0300574
575} // namespace sh