blob: 57c7c759c86d4b47049c31ec5e2098146ddb7a40 [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 {
251 mStructNames.insert(name);
252
253 // Add element index
254 storeStd140ElementIndex(*structure, false);
255 storeStd140ElementIndex(*structure, true);
256
257 const TString &structString = defineQualified(*structure, false, false);
258
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500259 if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) ==
260 mStructDeclarations.end())
Jamie Madill8daaba12014-06-13 10:04:33 -0400261 {
262 // Add row-major packed struct for interface blocks
263 TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500264 defineQualified(*structure, true, false) +
265 "#pragma pack_matrix(column_major)\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400266
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500267 TString std140String = defineQualified(*structure, false, true);
Jamie Madill8daaba12014-06-13 10:04:33 -0400268 TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500269 defineQualified(*structure, true, true) +
270 "#pragma pack_matrix(column_major)\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400271
272 mStructDeclarations.push_back(structString);
273 mStructDeclarations.push_back(rowMajorString);
274 mStructDeclarations.push_back(std140String);
275 mStructDeclarations.push_back(std140RowMajorString);
276 }
277
278 const TFieldList &fields = structure->fields();
Olli Etuaho96963162016-03-21 11:54:33 +0200279 for (const TField *field : fields)
Jamie Madill8daaba12014-06-13 10:04:33 -0400280 {
Olli Etuaho96963162016-03-21 11:54:33 +0200281 const TType *fieldType = field->type();
282 if (!IsSampler(fieldType->getBasicType()))
283 {
284 ctorParameters.push_back(*fieldType);
285 }
Jamie Madill8daaba12014-06-13 10:04:33 -0400286 }
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200287 constructorFunctionName = TString(name);
Jamie Madill8daaba12014-06-13 10:04:33 -0400288 }
289 else if (parameters)
290 {
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200291 for (auto parameter : *parameters)
Jamie Madill8daaba12014-06-13 10:04:33 -0400292 {
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200293 const TType &paramType = parameter->getAsTyped()->getType();
294 ctorParameters.push_back(paramType);
Jamie Madill8daaba12014-06-13 10:04:33 -0400295 }
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200296 constructorFunctionName = TString(name) + DisambiguateFunctionName(parameters);
Jamie Madill8daaba12014-06-13 10:04:33 -0400297 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500298 else
299 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400300
301 TString constructor;
302
303 if (ctorType.getStruct())
304 {
305 constructor += name + " " + name + "_ctor(";
306 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500307 else // Built-in type
Jamie Madill8daaba12014-06-13 10:04:33 -0400308 {
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200309 constructor += TypeString(ctorType) + " " + constructorFunctionName + "(";
Jamie Madill8daaba12014-06-13 10:04:33 -0400310 }
311
312 for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++)
313 {
Austin Kinross3ae64652015-01-26 15:51:39 -0800314 const TType &paramType = ctorParameters[parameter];
Jamie Madill8daaba12014-06-13 10:04:33 -0400315
Austin Kinross3ae64652015-01-26 15:51:39 -0800316 constructor += TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType);
Jamie Madill8daaba12014-06-13 10:04:33 -0400317
318 if (parameter < ctorParameters.size() - 1)
319 {
320 constructor += ", ";
321 }
322 }
323
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500324 constructor +=
325 ")\n"
326 "{\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400327
328 if (ctorType.getStruct())
329 {
Olli Etuaho96963162016-03-21 11:54:33 +0200330 constructor += " " + name + " structure";
331 if (ctorParameters.empty())
332 {
333 constructor += ";\n";
334 }
335 else
336 {
337 constructor += " = { ";
338 }
Jamie Madill8daaba12014-06-13 10:04:33 -0400339 }
340 else
341 {
342 constructor += " return " + TypeString(ctorType) + "(";
343 }
344
345 if (ctorType.isMatrix() && ctorParameters.size() == 1)
346 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500347 int rows = ctorType.getRows();
348 int cols = ctorType.getCols();
Jamie Madill8daaba12014-06-13 10:04:33 -0400349 const TType &parameter = ctorParameters[0];
350
351 if (parameter.isScalar())
352 {
Jamie Madillcf3af0b2014-08-01 17:22:16 -0400353 for (int col = 0; col < cols; col++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400354 {
Jamie Madillcf3af0b2014-08-01 17:22:16 -0400355 for (int row = 0; row < rows; row++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400356 {
357 constructor += TString((row == col) ? "x0" : "0.0");
358
359 if (row < rows - 1 || col < cols - 1)
360 {
361 constructor += ", ";
362 }
363 }
364 }
365 }
366 else if (parameter.isMatrix())
367 {
Jamie Madillf4e39bf2014-08-01 17:22:17 -0400368 for (int col = 0; col < cols; col++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400369 {
Jamie Madillf4e39bf2014-08-01 17:22:17 -0400370 for (int row = 0; row < rows; row++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400371 {
372 if (row < parameter.getRows() && col < parameter.getCols())
373 {
Jamie Madillf4e39bf2014-08-01 17:22:17 -0400374 constructor += TString("x0") + "[" + str(col) + "][" + str(row) + "]";
Jamie Madill8daaba12014-06-13 10:04:33 -0400375 }
376 else
377 {
378 constructor += TString((row == col) ? "1.0" : "0.0");
379 }
380
381 if (row < rows - 1 || col < cols - 1)
382 {
383 constructor += ", ";
384 }
385 }
386 }
387 }
388 else
389 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500390 ASSERT(rows == 2 && cols == 2 && parameter.isVector() &&
391 parameter.getNominalSize() == 4);
Jamie Madill8daaba12014-06-13 10:04:33 -0400392
393 constructor += "x0";
394 }
395 }
396 else
397 {
Olli Etuaho96963162016-03-21 11:54:33 +0200398 size_t remainingComponents = 0;
399 if (ctorType.getStruct())
400 {
401 remainingComponents = ctorParameters.size();
402 }
403 else
404 {
405 remainingComponents = ctorType.getObjectSize();
406 }
Jamie Madill8daaba12014-06-13 10:04:33 -0400407 size_t parameterIndex = 0;
408
409 while (remainingComponents > 0)
410 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500411 const TType &parameter = ctorParameters[parameterIndex];
Jamie Madill8daaba12014-06-13 10:04:33 -0400412 const size_t parameterSize = parameter.getObjectSize();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500413 bool moreParameters = parameterIndex + 1 < ctorParameters.size();
Jamie Madill8daaba12014-06-13 10:04:33 -0400414
415 constructor += "x" + str(parameterIndex);
416
417 if (ctorType.getStruct())
418 {
Olli Etuaho96963162016-03-21 11:54:33 +0200419 ASSERT(remainingComponents == 1 || moreParameters);
Jamie Madill8daaba12014-06-13 10:04:33 -0400420
Olli Etuaho96963162016-03-21 11:54:33 +0200421 --remainingComponents;
Jamie Madill8daaba12014-06-13 10:04:33 -0400422 }
423 else if (parameter.isScalar())
424 {
425 remainingComponents -= parameter.getObjectSize();
426 }
427 else if (parameter.isVector())
428 {
429 if (remainingComponents == parameterSize || moreParameters)
430 {
431 ASSERT(parameterSize <= remainingComponents);
432 remainingComponents -= parameterSize;
433 }
434 else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize()))
435 {
436 switch (remainingComponents)
437 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500438 case 1:
439 constructor += ".x";
440 break;
441 case 2:
442 constructor += ".xy";
443 break;
444 case 3:
445 constructor += ".xyz";
446 break;
447 case 4:
448 constructor += ".xyzw";
449 break;
450 default:
451 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400452 }
453
454 remainingComponents = 0;
455 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500456 else
457 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400458 }
459 else if (parameter.isMatrix())
460 {
461 int column = 0;
462 while (remainingComponents > 0 && column < parameter.getCols())
463 {
464 constructor += "[" + str(column) + "]";
465
466 if (remainingComponents < static_cast<size_t>(parameter.getRows()))
467 {
468 switch (remainingComponents)
469 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500470 case 1:
471 constructor += ".x";
472 break;
473 case 2:
474 constructor += ".xy";
475 break;
476 case 3:
477 constructor += ".xyz";
478 break;
479 default:
480 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400481 }
482
483 remainingComponents = 0;
484 }
485 else
486 {
487 remainingComponents -= parameter.getRows();
488
489 if (remainingComponents > 0)
490 {
491 constructor += ", x" + str(parameterIndex);
492 }
493 }
494
495 column++;
496 }
497 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500498 else
499 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400500
501 if (moreParameters)
502 {
503 parameterIndex++;
504 }
505
506 if (remainingComponents)
507 {
508 constructor += ", ";
509 }
510 }
511 }
512
513 if (ctorType.getStruct())
514 {
Olli Etuaho96963162016-03-21 11:54:33 +0200515 if (!ctorParameters.empty())
516 {
517 constructor += "};\n";
518 }
519 constructor +=
520 " return structure;\n"
521 "}\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400522 }
523 else
524 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500525 constructor +=
526 ");\n"
527 "}\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400528 }
529
530 mConstructors.insert(constructor);
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200531
532 return constructorFunctionName;
Jamie Madill8daaba12014-06-13 10:04:33 -0400533}
534
535std::string StructureHLSL::structsHeader() const
536{
537 TInfoSinkBase out;
538
539 for (size_t structIndex = 0; structIndex < mStructDeclarations.size(); structIndex++)
540 {
541 out << mStructDeclarations[structIndex];
542 }
543
Jamie Madill961d5e92014-06-20 15:23:34 -0400544 for (Constructors::const_iterator constructor = mConstructors.begin();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500545 constructor != mConstructors.end(); constructor++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400546 {
547 out << *constructor;
548 }
549
550 return out.str();
551}
552
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500553void StructureHLSL::storeStd140ElementIndex(const TStructure &structure,
554 bool useHLSLRowMajorPacking)
Jamie Madill8daaba12014-06-13 10:04:33 -0400555{
Jamie Madill33a74bd2014-08-18 15:47:59 -0400556 Std140PaddingHelper padHelper = getPaddingHelper();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500557 const TFieldList &fields = structure.fields();
Jamie Madill8daaba12014-06-13 10:04:33 -0400558
559 for (unsigned int i = 0; i < fields.size(); i++)
560 {
561 padHelper.prePadding(*fields[i]->type());
562 }
563
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500564 // Add remaining element index to the global map, for use with nested structs in standard
565 // layouts
Jamie Madill8daaba12014-06-13 10:04:33 -0400566 const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking, true);
567 mStd140StructElementIndexes[structName] = padHelper.elementIndex();
568}
Jamie Madill9e5317f2014-06-20 14:56:37 -0400569}