blob: 738a29cba6a09e52843b0c64ec38f2170a85fc07 [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;
Olli Etuaho92db39e2017-02-15 12:11:04 +000056 case EbtSampler2DMS:
57 return HLSL_TEXTURE_2D_MS;
Olli Etuaho9b4e8622015-12-22 15:53:22 +020058 case EbtISampler2D:
59 return HLSL_TEXTURE_2D_INT4;
60 case EbtISampler3D:
61 return HLSL_TEXTURE_3D_INT4;
62 case EbtISamplerCube:
63 return HLSL_TEXTURE_2D_ARRAY_INT4;
64 case EbtISampler2DArray:
65 return HLSL_TEXTURE_2D_ARRAY_INT4;
Olli Etuaho92db39e2017-02-15 12:11:04 +000066 case EbtISampler2DMS:
67 return HLSL_TEXTURE_2D_MS_INT4;
Olli Etuaho9b4e8622015-12-22 15:53:22 +020068 case EbtUSampler2D:
69 return HLSL_TEXTURE_2D_UINT4;
70 case EbtUSampler3D:
71 return HLSL_TEXTURE_3D_UINT4;
72 case EbtUSamplerCube:
73 return HLSL_TEXTURE_2D_ARRAY_UINT4;
74 case EbtUSampler2DArray:
75 return HLSL_TEXTURE_2D_ARRAY_UINT4;
Olli Etuaho92db39e2017-02-15 12:11:04 +000076 case EbtUSampler2DMS:
77 return HLSL_TEXTURE_2D_MS_UINT4;
Olli Etuaho9b4e8622015-12-22 15:53:22 +020078 case EbtSampler2DShadow:
79 return HLSL_TEXTURE_2D_COMPARISON;
80 case EbtSamplerCubeShadow:
81 return HLSL_TEXTURE_CUBE_COMPARISON;
82 case EbtSampler2DArrayShadow:
83 return HLSL_TEXTURE_2D_ARRAY_COMPARISON;
84 default:
85 UNREACHABLE();
86 }
87 return HLSL_TEXTURE_UNKNOWN;
88}
89
90TString TextureString(const HLSLTextureSamplerGroup type)
91{
92 switch (type)
93 {
94 case HLSL_TEXTURE_2D:
95 return "Texture2D";
96 case HLSL_TEXTURE_CUBE:
97 return "TextureCube";
98 case HLSL_TEXTURE_2D_ARRAY:
99 return "Texture2DArray";
100 case HLSL_TEXTURE_3D:
101 return "Texture3D";
Olli Etuaho92db39e2017-02-15 12:11:04 +0000102 case HLSL_TEXTURE_2D_MS:
103 return "Texture2DMS<float4>";
Olli Etuaho9b4e8622015-12-22 15:53:22 +0200104 case HLSL_TEXTURE_2D_INT4:
105 return "Texture2D<int4>";
106 case HLSL_TEXTURE_3D_INT4:
107 return "Texture3D<int4>";
108 case HLSL_TEXTURE_2D_ARRAY_INT4:
109 return "Texture2DArray<int4>";
Olli Etuaho92db39e2017-02-15 12:11:04 +0000110 case HLSL_TEXTURE_2D_MS_INT4:
111 return "Texture2DMS<int4>";
Olli Etuaho9b4e8622015-12-22 15:53:22 +0200112 case HLSL_TEXTURE_2D_UINT4:
113 return "Texture2D<uint4>";
114 case HLSL_TEXTURE_3D_UINT4:
115 return "Texture3D<uint4>";
116 case HLSL_TEXTURE_2D_ARRAY_UINT4:
117 return "Texture2DArray<uint4>";
Olli Etuaho92db39e2017-02-15 12:11:04 +0000118 case HLSL_TEXTURE_2D_MS_UINT4:
119 return "Texture2DMS<uint4>";
Olli Etuaho9b4e8622015-12-22 15:53:22 +0200120 case HLSL_TEXTURE_2D_COMPARISON:
121 return "Texture2D";
122 case HLSL_TEXTURE_CUBE_COMPARISON:
123 return "TextureCube";
124 case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
125 return "Texture2DArray";
126 default:
127 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400128 }
129
130 return "<unknown texture type>";
131}
132
Olli Etuaho9b4e8622015-12-22 15:53:22 +0200133TString TextureString(const TBasicType type)
134{
135 return TextureString(TextureGroup(type));
136}
137
138TString TextureGroupSuffix(const HLSLTextureSamplerGroup type)
139{
140 switch (type)
141 {
142 case HLSL_TEXTURE_2D:
143 return "2D";
144 case HLSL_TEXTURE_CUBE:
145 return "Cube";
146 case HLSL_TEXTURE_2D_ARRAY:
147 return "2DArray";
148 case HLSL_TEXTURE_3D:
149 return "3D";
Olli Etuaho92db39e2017-02-15 12:11:04 +0000150 case HLSL_TEXTURE_2D_MS:
151 return "2DMS";
Olli Etuaho9b4e8622015-12-22 15:53:22 +0200152 case HLSL_TEXTURE_2D_INT4:
153 return "2D_int4_";
154 case HLSL_TEXTURE_3D_INT4:
155 return "3D_int4_";
156 case HLSL_TEXTURE_2D_ARRAY_INT4:
157 return "2DArray_int4_";
Olli Etuaho92db39e2017-02-15 12:11:04 +0000158 case HLSL_TEXTURE_2D_MS_INT4:
159 return "2DMS_int4_";
Olli Etuaho9b4e8622015-12-22 15:53:22 +0200160 case HLSL_TEXTURE_2D_UINT4:
161 return "2D_uint4_";
162 case HLSL_TEXTURE_3D_UINT4:
163 return "3D_uint4_";
164 case HLSL_TEXTURE_2D_ARRAY_UINT4:
165 return "2DArray_uint4_";
Olli Etuaho92db39e2017-02-15 12:11:04 +0000166 case HLSL_TEXTURE_2D_MS_UINT4:
167 return "2DMS_uint4_";
Olli Etuaho9b4e8622015-12-22 15:53:22 +0200168 case HLSL_TEXTURE_2D_COMPARISON:
169 return "2D_comparison";
170 case HLSL_TEXTURE_CUBE_COMPARISON:
171 return "Cube_comparison";
172 case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
173 return "2DArray_comparison";
174 default:
175 UNREACHABLE();
176 }
177
178 return "<unknown texture type>";
179}
180
181TString TextureGroupSuffix(const TBasicType type)
182{
183 return TextureGroupSuffix(TextureGroup(type));
184}
185
186TString TextureTypeSuffix(const TBasicType type)
187{
188 switch (type)
189 {
190 case EbtISamplerCube:
191 return "Cube_int4_";
192 case EbtUSamplerCube:
193 return "Cube_uint4_";
Geoff Lang28a97ee2016-09-22 13:01:26 -0400194 case EbtSamplerExternalOES:
195 return "_External";
Olli Etuaho9b4e8622015-12-22 15:53:22 +0200196 default:
197 // All other types are identified by their group suffix
198 return TextureGroupSuffix(type);
199 }
200}
201
Jamie Madill033dae62014-06-18 12:56:28 -0400202TString DecorateField(const TString &string, const TStructure &structure)
203{
204 if (structure.name().compare(0, 3, "gl_") != 0)
205 {
206 return Decorate(string);
207 }
208
209 return string;
210}
211
212TString DecoratePrivate(const TString &privateText)
213{
214 return "dx_" + privateText;
215}
216
217TString Decorate(const TString &string)
218{
Jamie Madilld5512cd2014-07-10 17:50:08 -0400219 if (string.compare(0, 3, "gl_") != 0)
Jamie Madill033dae62014-06-18 12:56:28 -0400220 {
221 return "_" + string;
222 }
223
224 return string;
225}
226
Olli Etuahoff526f12017-06-30 12:26:54 +0300227TString DecorateVariableIfNeeded(const TName &name)
Olli Etuahof5cfc8d2015-08-06 16:36:39 +0300228{
229 if (name.isInternal())
230 {
Olli Etuahoff526f12017-06-30 12:26:54 +0300231 // The name should not have a prefix reserved for user-defined variables or functions.
232 ASSERT(name.getString().compare(0, 2, "f_") != 0);
233 ASSERT(name.getString().compare(0, 1, "_") != 0);
Olli Etuahof5cfc8d2015-08-06 16:36:39 +0300234 return name.getString();
235 }
236 else
237 {
238 return Decorate(name.getString());
239 }
240}
241
Olli Etuahoff526f12017-06-30 12:26:54 +0300242TString DecorateFunctionIfNeeded(const TName &name)
243{
244 if (name.isInternal())
245 {
246 // The name should not have a prefix reserved for user-defined variables or functions.
247 ASSERT(name.getString().compare(0, 2, "f_") != 0);
248 ASSERT(name.getString().compare(0, 1, "_") != 0);
249 return name.getString();
250 }
251 ASSERT(name.getString().compare(0, 3, "gl_") != 0);
252 // Add an additional f prefix to functions so that they're always disambiguated from variables.
253 // This is necessary in the corner case where a variable declaration hides a function that it
254 // uses in its initializer.
255 return "f_" + name.getString();
256}
257
Jamie Madill033dae62014-06-18 12:56:28 -0400258TString TypeString(const TType &type)
259{
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500260 const TStructure *structure = type.getStruct();
Jamie Madill033dae62014-06-18 12:56:28 -0400261 if (structure)
262 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500263 const TString &typeName = structure->name();
Jamie Madill033dae62014-06-18 12:56:28 -0400264 if (typeName != "")
265 {
266 return StructNameString(*structure);
267 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500268 else // Nameless structure, define in place
Jamie Madill033dae62014-06-18 12:56:28 -0400269 {
Jamie Madill8daaba12014-06-13 10:04:33 -0400270 return StructureHLSL::defineNameless(*structure);
Jamie Madill033dae62014-06-18 12:56:28 -0400271 }
272 }
273 else if (type.isMatrix())
274 {
275 int cols = type.getCols();
276 int rows = type.getRows();
277 return "float" + str(cols) + "x" + str(rows);
278 }
279 else
280 {
281 switch (type.getBasicType())
282 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500283 case EbtFloat:
284 switch (type.getNominalSize())
285 {
286 case 1:
287 return "float";
288 case 2:
289 return "float2";
290 case 3:
291 return "float3";
292 case 4:
293 return "float4";
294 }
295 case EbtInt:
296 switch (type.getNominalSize())
297 {
298 case 1:
299 return "int";
300 case 2:
301 return "int2";
302 case 3:
303 return "int3";
304 case 4:
305 return "int4";
306 }
307 case EbtUInt:
308 switch (type.getNominalSize())
309 {
310 case 1:
311 return "uint";
312 case 2:
313 return "uint2";
314 case 3:
315 return "uint3";
316 case 4:
317 return "uint4";
318 }
319 case EbtBool:
320 switch (type.getNominalSize())
321 {
322 case 1:
323 return "bool";
324 case 2:
325 return "bool2";
326 case 3:
327 return "bool3";
328 case 4:
329 return "bool4";
330 }
331 case EbtVoid:
332 return "void";
333 case EbtSampler2D:
334 case EbtISampler2D:
335 case EbtUSampler2D:
336 case EbtSampler2DArray:
337 case EbtISampler2DArray:
338 case EbtUSampler2DArray:
339 return "sampler2D";
340 case EbtSamplerCube:
341 case EbtISamplerCube:
342 case EbtUSamplerCube:
343 return "samplerCUBE";
344 case EbtSamplerExternalOES:
345 return "sampler2D";
jchen104cdac9e2017-05-08 11:01:20 +0800346 case EbtAtomicCounter:
347 return "atomic_uint";
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500348 default:
349 break;
Jamie Madill033dae62014-06-18 12:56:28 -0400350 }
351 }
352
353 UNREACHABLE();
354 return "<unknown type>";
355}
356
357TString StructNameString(const TStructure &structure)
358{
359 if (structure.name().empty())
360 {
361 return "";
362 }
363
Jamie Madill9b820842015-02-12 10:40:10 -0500364 // For structures at global scope we use a consistent
365 // translation so that we can link between shader stages.
366 if (structure.atGlobalScope())
367 {
368 return Decorate(structure.name());
369 }
370
Jamie Madill8daaba12014-06-13 10:04:33 -0400371 return "ss" + str(structure.uniqueId()) + "_" + structure.name();
Jamie Madill033dae62014-06-18 12:56:28 -0400372}
373
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500374TString QualifiedStructNameString(const TStructure &structure,
375 bool useHLSLRowMajorPacking,
Jamie Madill033dae62014-06-18 12:56:28 -0400376 bool useStd140Packing)
377{
378 if (structure.name() == "")
379 {
380 return "";
381 }
382
383 TString prefix = "";
384
385 // Structs packed with row-major matrices in HLSL are prefixed with "rm"
386 // GLSL column-major maps to HLSL row-major, and the converse is true
387
388 if (useStd140Packing)
389 {
Jamie Madill8daaba12014-06-13 10:04:33 -0400390 prefix += "std_";
Jamie Madill033dae62014-06-18 12:56:28 -0400391 }
392
393 if (useHLSLRowMajorPacking)
394 {
Jamie Madill8daaba12014-06-13 10:04:33 -0400395 prefix += "rm_";
Jamie Madill033dae62014-06-18 12:56:28 -0400396 }
397
398 return prefix + StructNameString(structure);
399}
400
401TString InterpolationString(TQualifier qualifier)
402{
403 switch (qualifier)
404 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500405 case EvqVaryingIn:
406 return "";
407 case EvqFragmentIn:
408 return "";
409 case EvqSmoothIn:
410 return "linear";
411 case EvqFlatIn:
412 return "nointerpolation";
413 case EvqCentroidIn:
414 return "centroid";
415 case EvqVaryingOut:
416 return "";
417 case EvqVertexOut:
418 return "";
419 case EvqSmoothOut:
420 return "linear";
421 case EvqFlatOut:
422 return "nointerpolation";
423 case EvqCentroidOut:
424 return "centroid";
425 default:
426 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400427 }
428
429 return "";
430}
431
432TString QualifierString(TQualifier qualifier)
433{
434 switch (qualifier)
435 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500436 case EvqIn:
437 return "in";
438 case EvqOut:
439 return "inout"; // 'out' results in an HLSL error if not all fields are written, for
440 // GLSL it's undefined
441 case EvqInOut:
442 return "inout";
443 case EvqConstReadOnly:
444 return "const";
445 default:
446 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400447 }
448
449 return "";
450}
451
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200452TString DisambiguateFunctionName(const TIntermSequence *parameters)
453{
454 TString disambiguatingString;
455 for (auto parameter : *parameters)
456 {
457 const TType &paramType = parameter->getAsTyped()->getType();
458 // Disambiguation is needed for float2x2 and float4 parameters. These are the only parameter
459 // types that HLSL thinks are identical. float2x3 and float3x2 are different types, for
460 // example. Other parameter types are not added to function names to avoid making function
461 // names longer.
462 if (paramType.getObjectSize() == 4 && paramType.getBasicType() == EbtFloat)
463 {
464 disambiguatingString += "_" + TypeString(paramType);
465 }
466 }
467 return disambiguatingString;
Jamie Madill033dae62014-06-18 12:56:28 -0400468}
Olli Etuahobe59c2f2016-03-07 11:32:34 +0200469
470} // namespace sh