blob: 61a9431cebb607a0e39fbfde651ea4747070ec60 [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:
Olli Etuahobd3cd502017-11-03 15:48:52 +02007// HLSL translation of GLSL constructors and structures.
Jamie Madill8daaba12014-06-13 10:04:33 -04008//
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
Olli Etuahobd3cd502017-11-03 15:48:52 +020020namespace
21{
22
23TString Define(const TStructure &structure,
24 bool useHLSLRowMajorPacking,
25 bool useStd140Packing,
26 Std140PaddingHelper *padHelper)
27{
28 const TFieldList &fields = structure.fields();
29 const bool isNameless = (structure.name() == "");
30 const TString &structName =
31 QualifiedStructNameString(structure, useHLSLRowMajorPacking, useStd140Packing);
32 const TString declareString = (isNameless ? "struct" : "struct " + structName);
33
34 TString string;
35 string += declareString +
36 "\n"
37 "{\n";
38
39 for (const TField *field : fields)
40 {
41 const TType &fieldType = *field->type();
42 if (!IsSampler(fieldType.getBasicType()))
43 {
44 const TStructure *fieldStruct = fieldType.getStruct();
45 const TString &fieldTypeString =
46 fieldStruct ? QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking,
47 useStd140Packing)
48 : TypeString(fieldType);
49
50 if (padHelper)
51 {
52 string += padHelper->prePaddingString(fieldType);
53 }
54
55 string += " " + fieldTypeString + " " + DecorateField(field->name(), structure) +
56 ArrayString(fieldType) + ";\n";
57
58 if (padHelper)
59 {
60 string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking);
61 }
62 }
63 }
64
65 // Nameless structs do not finish with a semicolon and newline, to leave room for an instance
66 // variable
67 string += (isNameless ? "} " : "};\n");
68
69 return string;
70}
71
72TString WriteParameterList(const std::vector<TType> &parameters)
73{
74 TString parameterList;
75 for (size_t parameter = 0u; parameter < parameters.size(); parameter++)
76 {
77 const TType &paramType = parameters[parameter];
78
79 parameterList += TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType);
80
81 if (parameter < parameters.size() - 1u)
82 {
83 parameterList += ", ";
84 }
85 }
86 return parameterList;
87}
88
89} // anonymous namespace
90
Jamie Madill33a74bd2014-08-18 15:47:59 -040091Std140PaddingHelper::Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
92 unsigned *uniqueCounter)
Jamie Madilld7b1ab52016-12-12 14:42:19 -050093 : mPaddingCounter(uniqueCounter), mElementIndex(0), mStructElementIndexes(&structElementIndexes)
94{
95}
Jamie Madill8daaba12014-06-13 10:04:33 -040096
Jamie Madill80d934b2015-02-19 10:16:12 -050097Std140PaddingHelper::Std140PaddingHelper(const Std140PaddingHelper &other)
98 : mPaddingCounter(other.mPaddingCounter),
99 mElementIndex(other.mElementIndex),
100 mStructElementIndexes(other.mStructElementIndexes)
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500101{
102}
Jamie Madill80d934b2015-02-19 10:16:12 -0500103
104Std140PaddingHelper &Std140PaddingHelper::operator=(const Std140PaddingHelper &other)
105{
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500106 mPaddingCounter = other.mPaddingCounter;
107 mElementIndex = other.mElementIndex;
Jamie Madill80d934b2015-02-19 10:16:12 -0500108 mStructElementIndexes = other.mStructElementIndexes;
109 return *this;
110}
111
Jamie Madill33a74bd2014-08-18 15:47:59 -0400112TString Std140PaddingHelper::next()
113{
114 unsigned value = (*mPaddingCounter)++;
115 return str(value);
116}
117
Jamie Madill8daaba12014-06-13 10:04:33 -0400118int Std140PaddingHelper::prePadding(const TType &type)
119{
120 if (type.getBasicType() == EbtStruct || type.isMatrix() || type.isArray())
121 {
122 // no padding needed, HLSL will align the field to a new register
123 mElementIndex = 0;
124 return 0;
125 }
126
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500127 const GLenum glType = GLVariableType(type);
Jamie Madillf2575982014-06-25 16:04:54 -0400128 const int numComponents = gl::VariableComponentCount(glType);
Jamie Madill8daaba12014-06-13 10:04:33 -0400129
130 if (numComponents >= 4)
131 {
132 // no padding needed, HLSL will align the field to a new register
133 mElementIndex = 0;
134 return 0;
135 }
136
137 if (mElementIndex + numComponents > 4)
138 {
139 // no padding needed, HLSL will align the field to a new register
140 mElementIndex = numComponents;
141 return 0;
142 }
143
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500144 const int alignment = numComponents == 3 ? 4 : numComponents;
Jamie Madill8daaba12014-06-13 10:04:33 -0400145 const int paddingOffset = (mElementIndex % alignment);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500146 const int paddingCount = (paddingOffset != 0 ? (alignment - paddingOffset) : 0);
Jamie Madill8daaba12014-06-13 10:04:33 -0400147
148 mElementIndex += paddingCount;
149 mElementIndex += numComponents;
150 mElementIndex %= 4;
151
152 return paddingCount;
153}
154
155TString Std140PaddingHelper::prePaddingString(const TType &type)
156{
157 int paddingCount = prePadding(type);
158
159 TString padding;
160
161 for (int paddingIndex = 0; paddingIndex < paddingCount; paddingIndex++)
162 {
Jamie Madill33a74bd2014-08-18 15:47:59 -0400163 padding += " float pad_" + next() + ";\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400164 }
165
166 return padding;
167}
168
169TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRowMajorPacking)
170{
171 if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct)
172 {
173 return "";
174 }
175
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500176 int numComponents = 0;
Olli Etuahobd3cd502017-11-03 15:48:52 +0200177 const TStructure *structure = type.getStruct();
Jamie Madill8daaba12014-06-13 10:04:33 -0400178
179 if (type.isMatrix())
180 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500181 // This method can also be called from structureString, which does not use layout
182 // qualifiers.
Jamie Madill8daaba12014-06-13 10:04:33 -0400183 // Thus, use the method parameter for determining the matrix packing.
184 //
185 // Note HLSL row major packing corresponds to GL API column-major, and vice-versa, since we
186 // wish to always transpose GL matrices to play well with HLSL's matrix array indexing.
187 //
188 const bool isRowMajorMatrix = !useHLSLRowMajorPacking;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500189 const GLenum glType = GLVariableType(type);
190 numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix);
Jamie Madill8daaba12014-06-13 10:04:33 -0400191 }
192 else if (structure)
193 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500194 const TString &structName =
195 QualifiedStructNameString(*structure, useHLSLRowMajorPacking, true);
Jamie Madill80d934b2015-02-19 10:16:12 -0500196 numComponents = mStructElementIndexes->find(structName)->second;
Jamie Madill8daaba12014-06-13 10:04:33 -0400197
198 if (numComponents == 0)
199 {
200 return "";
201 }
202 }
203 else
204 {
205 const GLenum glType = GLVariableType(type);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500206 numComponents = gl::VariableComponentCount(glType);
Jamie Madill8daaba12014-06-13 10:04:33 -0400207 }
208
209 TString padding;
210 for (int paddingOffset = numComponents; paddingOffset < 4; paddingOffset++)
211 {
Jamie Madill33a74bd2014-08-18 15:47:59 -0400212 padding += " float pad_" + next() + ";\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400213 }
214 return padding;
215}
216
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500217StructureHLSL::StructureHLSL() : mUniquePaddingCounter(0)
218{
219}
Jamie Madill8daaba12014-06-13 10:04:33 -0400220
Jamie Madill33a74bd2014-08-18 15:47:59 -0400221Std140PaddingHelper StructureHLSL::getPaddingHelper()
222{
223 return Std140PaddingHelper(mStd140StructElementIndexes, &mUniquePaddingCounter);
224}
225
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500226TString StructureHLSL::defineQualified(const TStructure &structure,
227 bool useHLSLRowMajorPacking,
228 bool useStd140Packing)
Jamie Madill8daaba12014-06-13 10:04:33 -0400229{
230 if (useStd140Packing)
231 {
Jamie Madill33a74bd2014-08-18 15:47:59 -0400232 Std140PaddingHelper padHelper = getPaddingHelper();
Olli Etuahobd3cd502017-11-03 15:48:52 +0200233 return Define(structure, useHLSLRowMajorPacking, useStd140Packing, &padHelper);
Jamie Madill8daaba12014-06-13 10:04:33 -0400234 }
235 else
236 {
Olli Etuahobd3cd502017-11-03 15:48:52 +0200237 return Define(structure, useHLSLRowMajorPacking, useStd140Packing, nullptr);
Jamie Madill8daaba12014-06-13 10:04:33 -0400238 }
239}
240
241TString StructureHLSL::defineNameless(const TStructure &structure)
242{
Olli Etuahobd3cd502017-11-03 15:48:52 +0200243 return Define(structure, false, false, nullptr);
Jamie Madill8daaba12014-06-13 10:04:33 -0400244}
245
Olli Etuahobd3cd502017-11-03 15:48:52 +0200246StructureHLSL::DefinedStructs::iterator StructureHLSL::defineVariants(const TStructure &structure,
247 const TString &name)
Jamie Madill8daaba12014-06-13 10:04:33 -0400248{
Olli Etuahobd3cd502017-11-03 15:48:52 +0200249 ASSERT(mDefinedStructs.find(name) == mDefinedStructs.end());
Jamie Madill8daaba12014-06-13 10:04:33 -0400250
Olli Etuahobd3cd502017-11-03 15:48:52 +0200251 for (const TField *field : structure.fields())
Jamie Madill8daaba12014-06-13 10:04:33 -0400252 {
Olli Etuahobd3cd502017-11-03 15:48:52 +0200253 const TType *fieldType = field->type();
254 if (fieldType->getBasicType() == EbtStruct)
Jamie Madill8daaba12014-06-13 10:04:33 -0400255 {
Olli Etuahobd3cd502017-11-03 15:48:52 +0200256 ensureStructDefined(*fieldType->getStruct());
Jamie Madill8daaba12014-06-13 10:04:33 -0400257 }
258 }
259
Olli Etuahobd3cd502017-11-03 15:48:52 +0200260 DefinedStructs::iterator addedStruct =
261 mDefinedStructs.insert(std::make_pair(name, new TStructProperties())).first;
262 // Add element index
263 storeStd140ElementIndex(structure, false);
264 storeStd140ElementIndex(structure, true);
Jamie Madill8daaba12014-06-13 10:04:33 -0400265
Olli Etuahobd3cd502017-11-03 15:48:52 +0200266 const TString &structString = defineQualified(structure, false, false);
267
268 ASSERT(std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) ==
269 mStructDeclarations.end());
270 // Add row-major packed struct for interface blocks
271 TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
272 defineQualified(structure, true, false) +
273 "#pragma pack_matrix(column_major)\n";
274
275 TString std140String = defineQualified(structure, false, true);
276 TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
277 defineQualified(structure, true, true) +
278 "#pragma pack_matrix(column_major)\n";
279
280 mStructDeclarations.push_back(structString);
281 mStructDeclarations.push_back(rowMajorString);
282 mStructDeclarations.push_back(std140String);
283 mStructDeclarations.push_back(std140RowMajorString);
284 return addedStruct;
Jamie Madill8daaba12014-06-13 10:04:33 -0400285}
286
Olli Etuahobd3cd502017-11-03 15:48:52 +0200287void StructureHLSL::ensureStructDefined(const TStructure &structure)
Jamie Madill8daaba12014-06-13 10:04:33 -0400288{
Olli Etuahobd3cd502017-11-03 15:48:52 +0200289 const TString name = StructNameString(structure);
290 if (name == "")
291 {
292 return; // Nameless structures are not defined
293 }
294 if (mDefinedStructs.find(name) == mDefinedStructs.end())
295 {
296 defineVariants(structure, name);
297 }
298}
299
300TString StructureHLSL::addStructConstructor(const TStructure &structure)
301{
302 const TString name = StructNameString(structure);
303
Jamie Madill8daaba12014-06-13 10:04:33 -0400304 if (name == "")
305 {
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200306 return TString(); // Nameless structures don't have constructors
Jamie Madill8daaba12014-06-13 10:04:33 -0400307 }
308
Olli Etuahobd3cd502017-11-03 15:48:52 +0200309 auto definedStruct = mDefinedStructs.find(name);
310 if (definedStruct == mDefinedStructs.end())
Jamie Madill8daaba12014-06-13 10:04:33 -0400311 {
Olli Etuahobd3cd502017-11-03 15:48:52 +0200312 definedStruct = defineVariants(structure, name);
Jamie Madill8daaba12014-06-13 10:04:33 -0400313 }
Olli Etuahobd3cd502017-11-03 15:48:52 +0200314 const TString constructorFunctionName = TString(name) + "_ctor";
315 TString *constructor = &definedStruct->second->constructor;
316 if (!constructor->empty())
317 {
318 return constructorFunctionName; // Already added
319 }
320 *constructor += name + " " + constructorFunctionName + "(";
321
322 std::vector<TType> ctorParameters;
323 const TFieldList &fields = structure.fields();
324 for (const TField *field : fields)
325 {
326 const TType *fieldType = field->type();
327 if (!IsSampler(fieldType->getBasicType()))
328 {
329 ctorParameters.push_back(*fieldType);
330 }
331 }
332 // Structs that have sampler members should not have constructor calls, and otherwise structs
333 // are guaranteed to be non-empty by the grammar. Structs can't contain empty declarations
334 // either.
335 ASSERT(!ctorParameters.empty());
336
337 *constructor += WriteParameterList(ctorParameters);
338
339 *constructor +=
340 ")\n"
341 "{\n"
342 " " +
343 name + " structure = { ";
344
345 for (size_t parameterIndex = 0u; parameterIndex < ctorParameters.size(); ++parameterIndex)
346 {
347 *constructor += "x" + str(parameterIndex);
348 if (parameterIndex < ctorParameters.size() - 1u)
349 {
350 *constructor += ", ";
351 }
352 }
353 *constructor +=
354 "};\n"
355 " return structure;\n"
356 "}\n";
357
358 return constructorFunctionName;
359}
360
361TString StructureHLSL::addBuiltInConstructor(const TType &type, const TIntermSequence *parameters)
362{
363 ASSERT(!type.isArray());
364 ASSERT(type.getStruct() == nullptr);
365 ASSERT(parameters);
Jamie Madill8daaba12014-06-13 10:04:33 -0400366
367 TType ctorType = type;
Jamie Madill8daaba12014-06-13 10:04:33 -0400368 ctorType.setPrecision(EbpHigh);
369 ctorType.setQualifier(EvqTemporary);
370
Olli Etuahobd3cd502017-11-03 15:48:52 +0200371 const TString constructorFunctionName =
372 TString(type.getBuiltInTypeNameString()) + "_ctor" + DisambiguateFunctionName(parameters);
373 TString constructor = TypeString(ctorType) + " " + constructorFunctionName + "(";
Jamie Madill8daaba12014-06-13 10:04:33 -0400374
Olli Etuahobd3cd502017-11-03 15:48:52 +0200375 std::vector<TType> ctorParameters;
376 for (auto parameter : *parameters)
Jamie Madill8daaba12014-06-13 10:04:33 -0400377 {
Olli Etuahobd3cd502017-11-03 15:48:52 +0200378 const TType &paramType = parameter->getAsTyped()->getType();
379 ASSERT(!paramType.isArray());
380 ctorParameters.push_back(paramType);
Jamie Madill8daaba12014-06-13 10:04:33 -0400381 }
Olli Etuahobd3cd502017-11-03 15:48:52 +0200382 constructor += WriteParameterList(ctorParameters);
Jamie Madill8daaba12014-06-13 10:04:33 -0400383
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500384 constructor +=
385 ")\n"
Olli Etuahobd3cd502017-11-03 15:48:52 +0200386 "{\n"
387 " return " +
388 TypeString(ctorType) + "(";
Jamie Madill8daaba12014-06-13 10:04:33 -0400389
390 if (ctorType.isMatrix() && ctorParameters.size() == 1)
391 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500392 int rows = ctorType.getRows();
393 int cols = ctorType.getCols();
Jamie Madill8daaba12014-06-13 10:04:33 -0400394 const TType &parameter = ctorParameters[0];
395
396 if (parameter.isScalar())
397 {
Jamie Madillcf3af0b2014-08-01 17:22:16 -0400398 for (int col = 0; col < cols; col++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400399 {
Jamie Madillcf3af0b2014-08-01 17:22:16 -0400400 for (int row = 0; row < rows; row++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400401 {
402 constructor += TString((row == col) ? "x0" : "0.0");
403
404 if (row < rows - 1 || col < cols - 1)
405 {
406 constructor += ", ";
407 }
408 }
409 }
410 }
411 else if (parameter.isMatrix())
412 {
Jamie Madillf4e39bf2014-08-01 17:22:17 -0400413 for (int col = 0; col < cols; col++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400414 {
Jamie Madillf4e39bf2014-08-01 17:22:17 -0400415 for (int row = 0; row < rows; row++)
Jamie Madill8daaba12014-06-13 10:04:33 -0400416 {
417 if (row < parameter.getRows() && col < parameter.getCols())
418 {
Jamie Madillf4e39bf2014-08-01 17:22:17 -0400419 constructor += TString("x0") + "[" + str(col) + "][" + str(row) + "]";
Jamie Madill8daaba12014-06-13 10:04:33 -0400420 }
421 else
422 {
423 constructor += TString((row == col) ? "1.0" : "0.0");
424 }
425
426 if (row < rows - 1 || col < cols - 1)
427 {
428 constructor += ", ";
429 }
430 }
431 }
432 }
433 else
434 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500435 ASSERT(rows == 2 && cols == 2 && parameter.isVector() &&
436 parameter.getNominalSize() == 4);
Jamie Madill8daaba12014-06-13 10:04:33 -0400437
438 constructor += "x0";
439 }
440 }
441 else
442 {
Olli Etuahobd3cd502017-11-03 15:48:52 +0200443 size_t remainingComponents = ctorType.getObjectSize();
Jamie Madill8daaba12014-06-13 10:04:33 -0400444 size_t parameterIndex = 0;
445
446 while (remainingComponents > 0)
447 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500448 const TType &parameter = ctorParameters[parameterIndex];
Jamie Madill8daaba12014-06-13 10:04:33 -0400449 const size_t parameterSize = parameter.getObjectSize();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500450 bool moreParameters = parameterIndex + 1 < ctorParameters.size();
Jamie Madill8daaba12014-06-13 10:04:33 -0400451
452 constructor += "x" + str(parameterIndex);
453
Olli Etuahobd3cd502017-11-03 15:48:52 +0200454 if (parameter.isScalar())
Jamie Madill8daaba12014-06-13 10:04:33 -0400455 {
456 remainingComponents -= parameter.getObjectSize();
457 }
458 else if (parameter.isVector())
459 {
460 if (remainingComponents == parameterSize || moreParameters)
461 {
462 ASSERT(parameterSize <= remainingComponents);
463 remainingComponents -= parameterSize;
464 }
465 else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize()))
466 {
467 switch (remainingComponents)
468 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500469 case 1:
470 constructor += ".x";
471 break;
472 case 2:
473 constructor += ".xy";
474 break;
475 case 3:
476 constructor += ".xyz";
477 break;
478 case 4:
479 constructor += ".xyzw";
480 break;
481 default:
482 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400483 }
484
485 remainingComponents = 0;
486 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500487 else
488 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400489 }
490 else if (parameter.isMatrix())
491 {
492 int column = 0;
493 while (remainingComponents > 0 && column < parameter.getCols())
494 {
495 constructor += "[" + str(column) + "]";
496
497 if (remainingComponents < static_cast<size_t>(parameter.getRows()))
498 {
499 switch (remainingComponents)
500 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500501 case 1:
502 constructor += ".x";
503 break;
504 case 2:
505 constructor += ".xy";
506 break;
507 case 3:
508 constructor += ".xyz";
509 break;
510 default:
511 UNREACHABLE();
Jamie Madill8daaba12014-06-13 10:04:33 -0400512 }
513
514 remainingComponents = 0;
515 }
516 else
517 {
518 remainingComponents -= parameter.getRows();
519
520 if (remainingComponents > 0)
521 {
522 constructor += ", x" + str(parameterIndex);
523 }
524 }
525
526 column++;
527 }
528 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500529 else
Olli Etuahobd3cd502017-11-03 15:48:52 +0200530 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500531 UNREACHABLE();
Olli Etuahobd3cd502017-11-03 15:48:52 +0200532 }
Jamie Madill8daaba12014-06-13 10:04:33 -0400533
534 if (moreParameters)
535 {
536 parameterIndex++;
537 }
538
539 if (remainingComponents)
540 {
541 constructor += ", ";
542 }
543 }
544 }
545
Olli Etuahobd3cd502017-11-03 15:48:52 +0200546 constructor +=
547 ");\n"
548 "}\n";
Jamie Madill8daaba12014-06-13 10:04:33 -0400549
Olli Etuahobd3cd502017-11-03 15:48:52 +0200550 mBuiltInConstructors.insert(constructor);
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200551
552 return constructorFunctionName;
Jamie Madill8daaba12014-06-13 10:04:33 -0400553}
554
555std::string StructureHLSL::structsHeader() const
556{
557 TInfoSinkBase out;
558
Olli Etuahobd3cd502017-11-03 15:48:52 +0200559 for (auto &declaration : mStructDeclarations)
Jamie Madill8daaba12014-06-13 10:04:33 -0400560 {
Olli Etuahobd3cd502017-11-03 15:48:52 +0200561 out << declaration;
Jamie Madill8daaba12014-06-13 10:04:33 -0400562 }
563
Olli Etuahobd3cd502017-11-03 15:48:52 +0200564 for (auto &structure : mDefinedStructs)
Jamie Madill8daaba12014-06-13 10:04:33 -0400565 {
Olli Etuahobd3cd502017-11-03 15:48:52 +0200566 out << structure.second->constructor;
567 }
568
569 for (auto &constructor : mBuiltInConstructors)
570 {
571 out << constructor;
Jamie Madill8daaba12014-06-13 10:04:33 -0400572 }
573
574 return out.str();
575}
576
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500577void StructureHLSL::storeStd140ElementIndex(const TStructure &structure,
578 bool useHLSLRowMajorPacking)
Jamie Madill8daaba12014-06-13 10:04:33 -0400579{
Jamie Madill33a74bd2014-08-18 15:47:59 -0400580 Std140PaddingHelper padHelper = getPaddingHelper();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500581 const TFieldList &fields = structure.fields();
Jamie Madill8daaba12014-06-13 10:04:33 -0400582
Olli Etuahoc2157a02017-08-09 18:52:59 +0300583 for (const TField *field : fields)
Jamie Madill8daaba12014-06-13 10:04:33 -0400584 {
Olli Etuahoc2157a02017-08-09 18:52:59 +0300585 padHelper.prePadding(*field->type());
Jamie Madill8daaba12014-06-13 10:04:33 -0400586 }
587
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500588 // Add remaining element index to the global map, for use with nested structs in standard
589 // layouts
Jamie Madill8daaba12014-06-13 10:04:33 -0400590 const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking, true);
591 mStd140StructElementIndexes[structName] = padHelper.elementIndex();
592}
Olli Etuahoc2157a02017-08-09 18:52:59 +0300593
594} // namespace sh