blob: 0a4e0666e863ea7f006f71f46ff7b163169ed329 [file] [log] [blame]
Jamie Madill033dae62014-06-18 12:56:28 -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// UtilsHLSL.cpp:
7// Utility methods for GLSL to HLSL translation.
8//
9
10#include "compiler/translator/UtilsHLSL.h"
Olli Etuahof5cfc8d2015-08-06 16:36:39 +030011#include "compiler/translator/IntermNode.h"
Jamie Madill8daaba12014-06-13 10:04:33 -040012#include "compiler/translator/StructureHLSL.h"
Jamie Madill033dae62014-06-18 12:56:28 -040013#include "compiler/translator/SymbolTable.h"
14
15namespace sh
16{
17
Olli Etuaho9b4e8622015-12-22 15:53:22 +020018TString SamplerString(const TBasicType type)
Jamie Madill033dae62014-06-18 12:56:28 -040019{
Olli Etuaho9b4e8622015-12-22 15:53:22 +020020 if (IsShadowSampler(type))
Jamie Madill033dae62014-06-18 12:56:28 -040021 {
22 return "SamplerComparisonState";
23 }
24 else
25 {
26 return "SamplerState";
27 }
28}
29
Olli Etuaho9b4e8622015-12-22 15:53:22 +020030TString SamplerString(HLSLTextureSamplerGroup type)
Jamie Madill033dae62014-06-18 12:56:28 -040031{
Olli Etuaho9b4e8622015-12-22 15:53:22 +020032 if (type >= HLSL_COMPARISON_SAMPLER_GROUP_BEGIN && type <= HLSL_COMPARISON_SAMPLER_GROUP_END)
Jamie Madill033dae62014-06-18 12:56:28 -040033 {
Olli Etuaho9b4e8622015-12-22 15:53:22 +020034 return "SamplerComparisonState";
35 }
36 else
37 {
38 return "SamplerState";
39 }
40}
41
42HLSLTextureSamplerGroup TextureGroup(const TBasicType type)
43{
44 switch (type)
45 {
46 case EbtSampler2D:
47 return HLSL_TEXTURE_2D;
48 case EbtSamplerCube:
49 return HLSL_TEXTURE_CUBE;
50 case EbtSamplerExternalOES:
51 return HLSL_TEXTURE_2D;
52 case EbtSampler2DArray:
53 return HLSL_TEXTURE_2D_ARRAY;
54 case EbtSampler3D:
55 return HLSL_TEXTURE_3D;
56 case EbtISampler2D:
57 return HLSL_TEXTURE_2D_INT4;
58 case EbtISampler3D:
59 return HLSL_TEXTURE_3D_INT4;
60 case EbtISamplerCube:
61 return HLSL_TEXTURE_2D_ARRAY_INT4;
62 case EbtISampler2DArray:
63 return HLSL_TEXTURE_2D_ARRAY_INT4;
64 case EbtUSampler2D:
65 return HLSL_TEXTURE_2D_UINT4;
66 case EbtUSampler3D:
67 return HLSL_TEXTURE_3D_UINT4;
68 case EbtUSamplerCube:
69 return HLSL_TEXTURE_2D_ARRAY_UINT4;
70 case EbtUSampler2DArray:
71 return HLSL_TEXTURE_2D_ARRAY_UINT4;
72 case EbtSampler2DShadow:
73 return HLSL_TEXTURE_2D_COMPARISON;
74 case EbtSamplerCubeShadow:
75 return HLSL_TEXTURE_CUBE_COMPARISON;
76 case EbtSampler2DArrayShadow:
77 return HLSL_TEXTURE_2D_ARRAY_COMPARISON;
78 default:
79 UNREACHABLE();
80 }
81 return HLSL_TEXTURE_UNKNOWN;
82}
83
84TString TextureString(const HLSLTextureSamplerGroup type)
85{
86 switch (type)
87 {
88 case HLSL_TEXTURE_2D:
89 return "Texture2D";
90 case HLSL_TEXTURE_CUBE:
91 return "TextureCube";
92 case HLSL_TEXTURE_2D_ARRAY:
93 return "Texture2DArray";
94 case HLSL_TEXTURE_3D:
95 return "Texture3D";
96 case HLSL_TEXTURE_2D_INT4:
97 return "Texture2D<int4>";
98 case HLSL_TEXTURE_3D_INT4:
99 return "Texture3D<int4>";
100 case HLSL_TEXTURE_2D_ARRAY_INT4:
101 return "Texture2DArray<int4>";
102 case HLSL_TEXTURE_2D_UINT4:
103 return "Texture2D<uint4>";
104 case HLSL_TEXTURE_3D_UINT4:
105 return "Texture3D<uint4>";
106 case HLSL_TEXTURE_2D_ARRAY_UINT4:
107 return "Texture2DArray<uint4>";
108 case HLSL_TEXTURE_2D_COMPARISON:
109 return "Texture2D";
110 case HLSL_TEXTURE_CUBE_COMPARISON:
111 return "TextureCube";
112 case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
113 return "Texture2DArray";
114 default:
115 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400116 }
117
118 return "<unknown texture type>";
119}
120
Olli Etuaho9b4e8622015-12-22 15:53:22 +0200121TString TextureString(const TBasicType type)
122{
123 return TextureString(TextureGroup(type));
124}
125
126TString TextureGroupSuffix(const HLSLTextureSamplerGroup type)
127{
128 switch (type)
129 {
130 case HLSL_TEXTURE_2D:
131 return "2D";
132 case HLSL_TEXTURE_CUBE:
133 return "Cube";
134 case HLSL_TEXTURE_2D_ARRAY:
135 return "2DArray";
136 case HLSL_TEXTURE_3D:
137 return "3D";
138 case HLSL_TEXTURE_2D_INT4:
139 return "2D_int4_";
140 case HLSL_TEXTURE_3D_INT4:
141 return "3D_int4_";
142 case HLSL_TEXTURE_2D_ARRAY_INT4:
143 return "2DArray_int4_";
144 case HLSL_TEXTURE_2D_UINT4:
145 return "2D_uint4_";
146 case HLSL_TEXTURE_3D_UINT4:
147 return "3D_uint4_";
148 case HLSL_TEXTURE_2D_ARRAY_UINT4:
149 return "2DArray_uint4_";
150 case HLSL_TEXTURE_2D_COMPARISON:
151 return "2D_comparison";
152 case HLSL_TEXTURE_CUBE_COMPARISON:
153 return "Cube_comparison";
154 case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
155 return "2DArray_comparison";
156 default:
157 UNREACHABLE();
158 }
159
160 return "<unknown texture type>";
161}
162
163TString TextureGroupSuffix(const TBasicType type)
164{
165 return TextureGroupSuffix(TextureGroup(type));
166}
167
168TString TextureTypeSuffix(const TBasicType type)
169{
170 switch (type)
171 {
172 case EbtISamplerCube:
173 return "Cube_int4_";
174 case EbtUSamplerCube:
175 return "Cube_uint4_";
Geoff Lang28a97ee2016-09-22 13:01:26 -0400176 case EbtSamplerExternalOES:
177 return "_External";
Olli Etuaho9b4e8622015-12-22 15:53:22 +0200178 default:
179 // All other types are identified by their group suffix
180 return TextureGroupSuffix(type);
181 }
182}
183
Olli Etuaho96963162016-03-21 11:54:33 +0200184TString DecorateUniform(const TName &name, const TType &type)
Jamie Madill033dae62014-06-18 12:56:28 -0400185{
Olli Etuaho96963162016-03-21 11:54:33 +0200186 return DecorateIfNeeded(name);
Jamie Madill033dae62014-06-18 12:56:28 -0400187}
188
189TString DecorateField(const TString &string, const TStructure &structure)
190{
191 if (structure.name().compare(0, 3, "gl_") != 0)
192 {
193 return Decorate(string);
194 }
195
196 return string;
197}
198
199TString DecoratePrivate(const TString &privateText)
200{
201 return "dx_" + privateText;
202}
203
204TString Decorate(const TString &string)
205{
Jamie Madilld5512cd2014-07-10 17:50:08 -0400206 if (string.compare(0, 3, "gl_") != 0)
Jamie Madill033dae62014-06-18 12:56:28 -0400207 {
208 return "_" + string;
209 }
210
211 return string;
212}
213
Olli Etuahof5cfc8d2015-08-06 16:36:39 +0300214TString DecorateIfNeeded(const TName &name)
215{
216 if (name.isInternal())
217 {
218 return name.getString();
219 }
220 else
221 {
222 return Decorate(name.getString());
223 }
224}
225
Olli Etuaho59f9a642015-08-06 20:38:26 +0300226TString DecorateFunctionIfNeeded(const TName &name)
227{
228 if (name.isInternal())
229 {
230 return TFunction::unmangleName(name.getString());
231 }
232 else
233 {
234 return Decorate(TFunction::unmangleName(name.getString()));
235 }
236}
237
Jamie Madill033dae62014-06-18 12:56:28 -0400238TString TypeString(const TType &type)
239{
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500240 const TStructure *structure = type.getStruct();
Jamie Madill033dae62014-06-18 12:56:28 -0400241 if (structure)
242 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500243 const TString &typeName = structure->name();
Jamie Madill033dae62014-06-18 12:56:28 -0400244 if (typeName != "")
245 {
246 return StructNameString(*structure);
247 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500248 else // Nameless structure, define in place
Jamie Madill033dae62014-06-18 12:56:28 -0400249 {
Jamie Madill8daaba12014-06-13 10:04:33 -0400250 return StructureHLSL::defineNameless(*structure);
Jamie Madill033dae62014-06-18 12:56:28 -0400251 }
252 }
253 else if (type.isMatrix())
254 {
255 int cols = type.getCols();
256 int rows = type.getRows();
257 return "float" + str(cols) + "x" + str(rows);
258 }
259 else
260 {
261 switch (type.getBasicType())
262 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500263 case EbtFloat:
264 switch (type.getNominalSize())
265 {
266 case 1:
267 return "float";
268 case 2:
269 return "float2";
270 case 3:
271 return "float3";
272 case 4:
273 return "float4";
274 }
275 case EbtInt:
276 switch (type.getNominalSize())
277 {
278 case 1:
279 return "int";
280 case 2:
281 return "int2";
282 case 3:
283 return "int3";
284 case 4:
285 return "int4";
286 }
287 case EbtUInt:
288 switch (type.getNominalSize())
289 {
290 case 1:
291 return "uint";
292 case 2:
293 return "uint2";
294 case 3:
295 return "uint3";
296 case 4:
297 return "uint4";
298 }
299 case EbtBool:
300 switch (type.getNominalSize())
301 {
302 case 1:
303 return "bool";
304 case 2:
305 return "bool2";
306 case 3:
307 return "bool3";
308 case 4:
309 return "bool4";
310 }
311 case EbtVoid:
312 return "void";
313 case EbtSampler2D:
314 case EbtISampler2D:
315 case EbtUSampler2D:
316 case EbtSampler2DArray:
317 case EbtISampler2DArray:
318 case EbtUSampler2DArray:
319 return "sampler2D";
320 case EbtSamplerCube:
321 case EbtISamplerCube:
322 case EbtUSamplerCube:
323 return "samplerCUBE";
324 case EbtSamplerExternalOES:
325 return "sampler2D";
326 default:
327 break;
Jamie Madill033dae62014-06-18 12:56:28 -0400328 }
329 }
330
331 UNREACHABLE();
332 return "<unknown type>";
333}
334
335TString StructNameString(const TStructure &structure)
336{
337 if (structure.name().empty())
338 {
339 return "";
340 }
341
Jamie Madill9b820842015-02-12 10:40:10 -0500342 // For structures at global scope we use a consistent
343 // translation so that we can link between shader stages.
344 if (structure.atGlobalScope())
345 {
346 return Decorate(structure.name());
347 }
348
Jamie Madill8daaba12014-06-13 10:04:33 -0400349 return "ss" + str(structure.uniqueId()) + "_" + structure.name();
Jamie Madill033dae62014-06-18 12:56:28 -0400350}
351
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500352TString QualifiedStructNameString(const TStructure &structure,
353 bool useHLSLRowMajorPacking,
Jamie Madill033dae62014-06-18 12:56:28 -0400354 bool useStd140Packing)
355{
356 if (structure.name() == "")
357 {
358 return "";
359 }
360
361 TString prefix = "";
362
363 // Structs packed with row-major matrices in HLSL are prefixed with "rm"
364 // GLSL column-major maps to HLSL row-major, and the converse is true
365
366 if (useStd140Packing)
367 {
Jamie Madill8daaba12014-06-13 10:04:33 -0400368 prefix += "std_";
Jamie Madill033dae62014-06-18 12:56:28 -0400369 }
370
371 if (useHLSLRowMajorPacking)
372 {
Jamie Madill8daaba12014-06-13 10:04:33 -0400373 prefix += "rm_";
Jamie Madill033dae62014-06-18 12:56:28 -0400374 }
375
376 return prefix + StructNameString(structure);
377}
378
379TString InterpolationString(TQualifier qualifier)
380{
381 switch (qualifier)
382 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500383 case EvqVaryingIn:
384 return "";
385 case EvqFragmentIn:
386 return "";
387 case EvqSmoothIn:
388 return "linear";
389 case EvqFlatIn:
390 return "nointerpolation";
391 case EvqCentroidIn:
392 return "centroid";
393 case EvqVaryingOut:
394 return "";
395 case EvqVertexOut:
396 return "";
397 case EvqSmoothOut:
398 return "linear";
399 case EvqFlatOut:
400 return "nointerpolation";
401 case EvqCentroidOut:
402 return "centroid";
403 default:
404 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400405 }
406
407 return "";
408}
409
410TString QualifierString(TQualifier qualifier)
411{
412 switch (qualifier)
413 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500414 case EvqIn:
415 return "in";
416 case EvqOut:
417 return "inout"; // 'out' results in an HLSL error if not all fields are written, for
418 // GLSL it's undefined
419 case EvqInOut:
420 return "inout";
421 case EvqConstReadOnly:
422 return "const";
423 default:
424 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400425 }
426
427 return "";
428}
429
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200430TString DisambiguateFunctionName(const TIntermSequence *parameters)
431{
432 TString disambiguatingString;
433 for (auto parameter : *parameters)
434 {
435 const TType &paramType = parameter->getAsTyped()->getType();
436 // Disambiguation is needed for float2x2 and float4 parameters. These are the only parameter
437 // types that HLSL thinks are identical. float2x3 and float3x2 are different types, for
438 // example. Other parameter types are not added to function names to avoid making function
439 // names longer.
440 if (paramType.getObjectSize() == 4 && paramType.getBasicType() == EbtFloat)
441 {
442 disambiguatingString += "_" + TypeString(paramType);
443 }
444 }
445 return disambiguatingString;
Jamie Madill033dae62014-06-18 12:56:28 -0400446}
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200447
448} // namespace sh