1 //
2 // Copyright 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"
11 #include "compiler/translator/IntermNode.h"
12 #include "compiler/translator/StructureHLSL.h"
13 #include "compiler/translator/SymbolTable.h"
14 #include "compiler/translator/util.h"
15 
16 namespace sh
17 {
18 
19 namespace
20 {
21 
DisambiguateFunctionNameForParameterType(const TType & paramType,TString * disambiguatingStringOut)22 void DisambiguateFunctionNameForParameterType(const TType &paramType,
23                                               TString *disambiguatingStringOut)
24 {
25     // Parameter types are only added to function names if they are ambiguous according to the
26     // native HLSL compiler. Other parameter types are not added to function names to avoid
27     // making function names longer.
28     if (paramType.getObjectSize() == 4 && paramType.getBasicType() == EbtFloat)
29     {
30         // Disambiguation is needed for float2x2 and float4 parameters. These are the only
31         // built-in types that HLSL thinks are identical. float2x3 and float3x2 are different
32         // types, for example.
33         *disambiguatingStringOut += "_" + TypeString(paramType);
34     }
35     else if (paramType.getBasicType() == EbtStruct)
36     {
37         // Disambiguation is needed for struct parameters, since HLSL thinks that structs with
38         // the same fields but a different name are identical.
39         ASSERT(paramType.getStruct()->symbolType() != SymbolType::Empty);
40         *disambiguatingStringOut += "_" + TypeString(paramType);
41     }
42 }
43 
44 }  // anonymous namespace
45 
SamplerString(const TBasicType type)46 const char *SamplerString(const TBasicType type)
47 {
48     if (IsShadowSampler(type))
49     {
50         return "SamplerComparisonState";
51     }
52     else
53     {
54         return "SamplerState";
55     }
56 }
57 
SamplerString(HLSLTextureGroup type)58 const char *SamplerString(HLSLTextureGroup type)
59 {
60     if (type >= HLSL_COMPARISON_SAMPLER_GROUP_BEGIN && type <= HLSL_COMPARISON_SAMPLER_GROUP_END)
61     {
62         return "SamplerComparisonState";
63     }
64     else
65     {
66         return "SamplerState";
67     }
68 }
69 
TextureGroup(const TBasicType type,TLayoutImageInternalFormat imageInternalFormat)70 HLSLTextureGroup TextureGroup(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
71 
72 {
73     switch (type)
74     {
75         case EbtSampler2D:
76         case EbtSamplerVideoWEBGL:
77             return HLSL_TEXTURE_2D;
78         case EbtSamplerCube:
79             return HLSL_TEXTURE_CUBE;
80         case EbtSamplerExternalOES:
81             return HLSL_TEXTURE_2D;
82         case EbtSampler2DArray:
83             return HLSL_TEXTURE_2D_ARRAY;
84         case EbtSampler3D:
85             return HLSL_TEXTURE_3D;
86         case EbtSampler2DMS:
87             return HLSL_TEXTURE_2D_MS;
88         case EbtSampler2DMSArray:
89             return HLSL_TEXTURE_2D_MS_ARRAY;
90         case EbtISampler2D:
91             return HLSL_TEXTURE_2D_INT4;
92         case EbtISampler3D:
93             return HLSL_TEXTURE_3D_INT4;
94         case EbtISamplerCube:
95             return HLSL_TEXTURE_2D_ARRAY_INT4;
96         case EbtISampler2DArray:
97             return HLSL_TEXTURE_2D_ARRAY_INT4;
98         case EbtISampler2DMS:
99             return HLSL_TEXTURE_2D_MS_INT4;
100         case EbtISampler2DMSArray:
101             return HLSL_TEXTURE_2D_MS_ARRAY_INT4;
102         case EbtUSampler2D:
103             return HLSL_TEXTURE_2D_UINT4;
104         case EbtUSampler3D:
105             return HLSL_TEXTURE_3D_UINT4;
106         case EbtUSamplerCube:
107             return HLSL_TEXTURE_2D_ARRAY_UINT4;
108         case EbtUSampler2DArray:
109             return HLSL_TEXTURE_2D_ARRAY_UINT4;
110         case EbtUSampler2DMS:
111             return HLSL_TEXTURE_2D_MS_UINT4;
112         case EbtUSampler2DMSArray:
113             return HLSL_TEXTURE_2D_MS_ARRAY_UINT4;
114         case EbtSampler2DShadow:
115             return HLSL_TEXTURE_2D_COMPARISON;
116         case EbtSamplerCubeShadow:
117             return HLSL_TEXTURE_CUBE_COMPARISON;
118         case EbtSampler2DArrayShadow:
119             return HLSL_TEXTURE_2D_ARRAY_COMPARISON;
120         case EbtImage2D:
121         {
122             switch (imageInternalFormat)
123             {
124                 case EiifRGBA32F:
125                 case EiifRGBA16F:
126                 case EiifR32F:
127                     return HLSL_TEXTURE_2D;
128                 case EiifRGBA8:
129                     return HLSL_TEXTURE_2D_UNORM;
130                 case EiifRGBA8_SNORM:
131                     return HLSL_TEXTURE_2D_SNORM;
132                 default:
133                     UNREACHABLE();
134 #if !UNREACHABLE_IS_NORETURN
135                     return HLSL_TEXTURE_UNKNOWN;
136 #endif
137             }
138         }
139         case EbtIImage2D:
140         {
141             switch (imageInternalFormat)
142             {
143                 case EiifRGBA32I:
144                 case EiifRGBA16I:
145                 case EiifRGBA8I:
146                 case EiifR32I:
147                     return HLSL_TEXTURE_2D_INT4;
148                 default:
149                     UNREACHABLE();
150 #if !UNREACHABLE_IS_NORETURN
151                     return HLSL_TEXTURE_UNKNOWN;
152 #endif
153             }
154         }
155         case EbtUImage2D:
156         {
157             switch (imageInternalFormat)
158             {
159 
160                 case EiifRGBA32UI:
161                 case EiifRGBA16UI:
162                 case EiifRGBA8UI:
163                 case EiifR32UI:
164                     return HLSL_TEXTURE_2D_UINT4;
165                 default:
166                     UNREACHABLE();
167 #if !UNREACHABLE_IS_NORETURN
168                     return HLSL_TEXTURE_UNKNOWN;
169 #endif
170             }
171         }
172         case EbtImage3D:
173         {
174             switch (imageInternalFormat)
175             {
176                 case EiifRGBA32F:
177                 case EiifRGBA16F:
178                 case EiifR32F:
179                     return HLSL_TEXTURE_3D;
180                 case EiifRGBA8:
181                     return HLSL_TEXTURE_3D_UNORM;
182                 case EiifRGBA8_SNORM:
183                     return HLSL_TEXTURE_3D_SNORM;
184                 default:
185                     UNREACHABLE();
186 #if !UNREACHABLE_IS_NORETURN
187                     return HLSL_TEXTURE_UNKNOWN;
188 #endif
189             }
190         }
191         case EbtIImage3D:
192         {
193             switch (imageInternalFormat)
194             {
195                 case EiifRGBA32I:
196                 case EiifRGBA16I:
197                 case EiifRGBA8I:
198                 case EiifR32I:
199                     return HLSL_TEXTURE_3D_INT4;
200                 default:
201                     UNREACHABLE();
202 #if !UNREACHABLE_IS_NORETURN
203                     return HLSL_TEXTURE_UNKNOWN;
204 #endif
205             }
206         }
207         case EbtUImage3D:
208         {
209             switch (imageInternalFormat)
210             {
211                 case EiifRGBA32UI:
212                 case EiifRGBA16UI:
213                 case EiifRGBA8UI:
214                 case EiifR32UI:
215                     return HLSL_TEXTURE_3D_UINT4;
216                 default:
217                     UNREACHABLE();
218 #if !UNREACHABLE_IS_NORETURN
219                     return HLSL_TEXTURE_UNKNOWN;
220 #endif
221             }
222         }
223         case EbtImage2DArray:
224         case EbtImageCube:
225         {
226             switch (imageInternalFormat)
227             {
228                 case EiifRGBA32F:
229                 case EiifRGBA16F:
230                 case EiifR32F:
231                     return HLSL_TEXTURE_2D_ARRAY;
232                 case EiifRGBA8:
233                     return HLSL_TEXTURE_2D_ARRAY_UNORN;
234                 case EiifRGBA8_SNORM:
235                     return HLSL_TEXTURE_2D_ARRAY_SNORM;
236                 default:
237                     UNREACHABLE();
238 #if !UNREACHABLE_IS_NORETURN
239                     return HLSL_TEXTURE_UNKNOWN;
240 #endif
241             }
242         }
243         case EbtIImage2DArray:
244         case EbtIImageCube:
245         {
246             switch (imageInternalFormat)
247             {
248                 case EiifRGBA32I:
249                 case EiifRGBA16I:
250                 case EiifRGBA8I:
251                 case EiifR32I:
252                     return HLSL_TEXTURE_2D_ARRAY_INT4;
253                 default:
254                     UNREACHABLE();
255 #if !UNREACHABLE_IS_NORETURN
256                     return HLSL_TEXTURE_UNKNOWN;
257 #endif
258             }
259         }
260         case EbtUImage2DArray:
261         case EbtUImageCube:
262         {
263             switch (imageInternalFormat)
264             {
265                 case EiifRGBA32UI:
266                 case EiifRGBA16UI:
267                 case EiifRGBA8UI:
268                 case EiifR32UI:
269                     return HLSL_TEXTURE_2D_ARRAY_UINT4;
270                 default:
271                     UNREACHABLE();
272 #if !UNREACHABLE_IS_NORETURN
273                     return HLSL_TEXTURE_UNKNOWN;
274 #endif
275             }
276         }
277         default:
278             UNREACHABLE();
279 #if !UNREACHABLE_IS_NORETURN
280             return HLSL_TEXTURE_UNKNOWN;
281 #endif
282     }
283 }
284 
TextureString(const HLSLTextureGroup textureGroup)285 const char *TextureString(const HLSLTextureGroup textureGroup)
286 {
287     switch (textureGroup)
288     {
289         case HLSL_TEXTURE_2D:
290             return "Texture2D<float4>";
291         case HLSL_TEXTURE_CUBE:
292             return "TextureCube<float4>";
293         case HLSL_TEXTURE_2D_ARRAY:
294             return "Texture2DArray<float4>";
295         case HLSL_TEXTURE_3D:
296             return "Texture3D<float4>";
297         case HLSL_TEXTURE_2D_UNORM:
298             return "Texture2D<unorm float4>";
299         case HLSL_TEXTURE_CUBE_UNORM:
300             return "TextureCube<unorm float4>";
301         case HLSL_TEXTURE_2D_ARRAY_UNORN:
302             return "Texture2DArray<unorm float4>";
303         case HLSL_TEXTURE_3D_UNORM:
304             return "Texture3D<unorm float4>";
305         case HLSL_TEXTURE_2D_SNORM:
306             return "Texture2D<snorm float4>";
307         case HLSL_TEXTURE_CUBE_SNORM:
308             return "TextureCube<snorm float4>";
309         case HLSL_TEXTURE_2D_ARRAY_SNORM:
310             return "Texture2DArray<snorm float4>";
311         case HLSL_TEXTURE_3D_SNORM:
312             return "Texture3D<snorm float4>";
313         case HLSL_TEXTURE_2D_MS:
314             return "Texture2DMS<float4>";
315         case HLSL_TEXTURE_2D_MS_ARRAY:
316             return "Texture2DMSArray<float4>";
317         case HLSL_TEXTURE_2D_INT4:
318             return "Texture2D<int4>";
319         case HLSL_TEXTURE_3D_INT4:
320             return "Texture3D<int4>";
321         case HLSL_TEXTURE_2D_ARRAY_INT4:
322             return "Texture2DArray<int4>";
323         case HLSL_TEXTURE_2D_MS_INT4:
324             return "Texture2DMS<int4>";
325         case HLSL_TEXTURE_2D_MS_ARRAY_INT4:
326             return "Texture2DMSArray<int4>";
327         case HLSL_TEXTURE_2D_UINT4:
328             return "Texture2D<uint4>";
329         case HLSL_TEXTURE_3D_UINT4:
330             return "Texture3D<uint4>";
331         case HLSL_TEXTURE_2D_ARRAY_UINT4:
332             return "Texture2DArray<uint4>";
333         case HLSL_TEXTURE_2D_MS_UINT4:
334             return "Texture2DMS<uint4>";
335         case HLSL_TEXTURE_2D_MS_ARRAY_UINT4:
336             return "Texture2DMSArray<uint4>";
337         case HLSL_TEXTURE_2D_COMPARISON:
338             return "Texture2D";
339         case HLSL_TEXTURE_CUBE_COMPARISON:
340             return "TextureCube";
341         case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
342             return "Texture2DArray";
343         default:
344             UNREACHABLE();
345     }
346 
347     return "<unknown read texture type>";
348 }
349 
TextureString(const TBasicType type,TLayoutImageInternalFormat imageInternalFormat)350 const char *TextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
351 {
352     return TextureString(TextureGroup(type, imageInternalFormat));
353 }
354 
TextureGroupSuffix(const HLSLTextureGroup type)355 const char *TextureGroupSuffix(const HLSLTextureGroup type)
356 {
357     switch (type)
358     {
359         case HLSL_TEXTURE_2D:
360             return "2D";
361         case HLSL_TEXTURE_CUBE:
362             return "Cube";
363         case HLSL_TEXTURE_2D_ARRAY:
364             return "2DArray";
365         case HLSL_TEXTURE_3D:
366             return "3D";
367         case HLSL_TEXTURE_2D_UNORM:
368             return "2D_unorm_float4_";
369         case HLSL_TEXTURE_CUBE_UNORM:
370             return "Cube_unorm_float4_";
371         case HLSL_TEXTURE_2D_ARRAY_UNORN:
372             return "2DArray_unorm_float4_";
373         case HLSL_TEXTURE_3D_UNORM:
374             return "3D_unorm_float4_";
375         case HLSL_TEXTURE_2D_SNORM:
376             return "2D_snorm_float4_";
377         case HLSL_TEXTURE_CUBE_SNORM:
378             return "Cube_snorm_float4_";
379         case HLSL_TEXTURE_2D_ARRAY_SNORM:
380             return "2DArray_snorm_float4_";
381         case HLSL_TEXTURE_3D_SNORM:
382             return "3D_snorm_float4_";
383         case HLSL_TEXTURE_2D_MS:
384             return "2DMS";
385         case HLSL_TEXTURE_2D_MS_ARRAY:
386             return "2DMSArray";
387         case HLSL_TEXTURE_2D_INT4:
388             return "2D_int4_";
389         case HLSL_TEXTURE_3D_INT4:
390             return "3D_int4_";
391         case HLSL_TEXTURE_2D_ARRAY_INT4:
392             return "2DArray_int4_";
393         case HLSL_TEXTURE_2D_MS_INT4:
394             return "2DMS_int4_";
395         case HLSL_TEXTURE_2D_MS_ARRAY_INT4:
396             return "2DMSArray_int4_";
397         case HLSL_TEXTURE_2D_UINT4:
398             return "2D_uint4_";
399         case HLSL_TEXTURE_3D_UINT4:
400             return "3D_uint4_";
401         case HLSL_TEXTURE_2D_ARRAY_UINT4:
402             return "2DArray_uint4_";
403         case HLSL_TEXTURE_2D_MS_UINT4:
404             return "2DMS_uint4_";
405         case HLSL_TEXTURE_2D_MS_ARRAY_UINT4:
406             return "2DMSArray_uint4_";
407         case HLSL_TEXTURE_2D_COMPARISON:
408             return "2D_comparison";
409         case HLSL_TEXTURE_CUBE_COMPARISON:
410             return "Cube_comparison";
411         case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
412             return "2DArray_comparison";
413         default:
414             UNREACHABLE();
415     }
416 
417     return "<unknown texture type>";
418 }
419 
TextureGroupSuffix(const TBasicType type,TLayoutImageInternalFormat imageInternalFormat)420 const char *TextureGroupSuffix(const TBasicType type,
421                                TLayoutImageInternalFormat imageInternalFormat)
422 {
423     return TextureGroupSuffix(TextureGroup(type, imageInternalFormat));
424 }
425 
TextureTypeSuffix(const TBasicType type,TLayoutImageInternalFormat imageInternalFormat)426 const char *TextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
427 {
428     switch (type)
429     {
430         case EbtISamplerCube:
431             return "Cube_int4_";
432         case EbtUSamplerCube:
433             return "Cube_uint4_";
434         case EbtSamplerExternalOES:
435             return "_External";
436         case EbtImageCube:
437         {
438             switch (imageInternalFormat)
439             {
440                 case EiifRGBA32F:
441                 case EiifRGBA16F:
442                 case EiifR32F:
443                     return "Cube_float4_";
444                 case EiifRGBA8:
445                     return "Cube_unorm_float4_";
446                 case EiifRGBA8_SNORM:
447                     return "Cube_snorm_float4_";
448                 default:
449                     UNREACHABLE();
450             }
451 #if !UNREACHABLE_IS_NORETURN
452             break;
453 #endif
454         }
455         case EbtIImageCube:
456         {
457             switch (imageInternalFormat)
458             {
459                 case EiifRGBA32I:
460                 case EiifRGBA16I:
461                 case EiifRGBA8I:
462                 case EiifR32I:
463                     return "Cube_int4_";
464                 default:
465                     UNREACHABLE();
466             }
467 #if !UNREACHABLE_IS_NORETURN
468             break;
469 #endif
470         }
471         case EbtUImageCube:
472         {
473             switch (imageInternalFormat)
474             {
475                 case EiifRGBA32UI:
476                 case EiifRGBA16UI:
477                 case EiifRGBA8UI:
478                 case EiifR32UI:
479                     return "Cube_uint4_";
480                 default:
481                     UNREACHABLE();
482             }
483 #if !UNREACHABLE_IS_NORETURN
484             break;
485 #endif
486         }
487         default:
488             // All other types are identified by their group suffix
489             return TextureGroupSuffix(type, imageInternalFormat);
490     }
491 #if !UNREACHABLE_IS_NORETURN
492     UNREACHABLE();
493     return "_TTS_invalid_";
494 #endif
495 }
496 
RWTextureGroup(const TBasicType type,TLayoutImageInternalFormat imageInternalFormat)497 HLSLRWTextureGroup RWTextureGroup(const TBasicType type,
498                                   TLayoutImageInternalFormat imageInternalFormat)
499 
500 {
501     switch (type)
502     {
503         case EbtImage2D:
504         {
505             switch (imageInternalFormat)
506             {
507                 case EiifRGBA32F:
508                 case EiifRGBA16F:
509                 case EiifR32F:
510                     return HLSL_RWTEXTURE_2D_FLOAT4;
511                 case EiifRGBA8:
512                     return HLSL_RWTEXTURE_2D_UNORM;
513                 case EiifRGBA8_SNORM:
514                     return HLSL_RWTEXTURE_2D_SNORM;
515                 default:
516                     UNREACHABLE();
517             }
518 #if !UNREACHABLE_IS_NORETURN
519             break;
520 #endif
521         }
522         case EbtIImage2D:
523         {
524             switch (imageInternalFormat)
525             {
526                 case EiifRGBA32I:
527                 case EiifRGBA16I:
528                 case EiifRGBA8I:
529                 case EiifR32I:
530                     return HLSL_RWTEXTURE_2D_INT4;
531                 default:
532                     UNREACHABLE();
533             }
534 #if !UNREACHABLE_IS_NORETURN
535             break;
536 #endif
537         }
538         case EbtUImage2D:
539         {
540             switch (imageInternalFormat)
541             {
542 
543                 case EiifRGBA32UI:
544                 case EiifRGBA16UI:
545                 case EiifRGBA8UI:
546                 case EiifR32UI:
547                     return HLSL_RWTEXTURE_2D_UINT4;
548                 default:
549                     UNREACHABLE();
550             }
551 #if !UNREACHABLE_IS_NORETURN
552             break;
553 #endif
554         }
555         case EbtImage3D:
556         {
557             switch (imageInternalFormat)
558             {
559                 case EiifRGBA32F:
560                 case EiifRGBA16F:
561                 case EiifR32F:
562                     return HLSL_RWTEXTURE_3D_FLOAT4;
563                 case EiifRGBA8:
564                     return HLSL_RWTEXTURE_3D_UNORM;
565                 case EiifRGBA8_SNORM:
566                     return HLSL_RWTEXTURE_3D_SNORM;
567                 default:
568                     UNREACHABLE();
569             }
570 #if !UNREACHABLE_IS_NORETURN
571             break;
572 #endif
573         }
574         case EbtIImage3D:
575         {
576             switch (imageInternalFormat)
577             {
578                 case EiifRGBA32I:
579                 case EiifRGBA16I:
580                 case EiifRGBA8I:
581                 case EiifR32I:
582                     return HLSL_RWTEXTURE_3D_INT4;
583                 default:
584                     UNREACHABLE();
585             }
586 #if !UNREACHABLE_IS_NORETURN
587             break;
588 #endif
589         }
590         case EbtUImage3D:
591         {
592             switch (imageInternalFormat)
593             {
594                 case EiifRGBA32UI:
595                 case EiifRGBA16UI:
596                 case EiifRGBA8UI:
597                 case EiifR32UI:
598                     return HLSL_RWTEXTURE_3D_UINT4;
599                 default:
600                     UNREACHABLE();
601             }
602 #if !UNREACHABLE_IS_NORETURN
603             break;
604 #endif
605         }
606         case EbtImage2DArray:
607         case EbtImageCube:
608         {
609             switch (imageInternalFormat)
610             {
611                 case EiifRGBA32F:
612                 case EiifRGBA16F:
613                 case EiifR32F:
614                     return HLSL_RWTEXTURE_2D_ARRAY_FLOAT4;
615                 case EiifRGBA8:
616                     return HLSL_RWTEXTURE_2D_ARRAY_UNORN;
617                 case EiifRGBA8_SNORM:
618                     return HLSL_RWTEXTURE_2D_ARRAY_SNORM;
619                 default:
620                     UNREACHABLE();
621             }
622 #if !UNREACHABLE_IS_NORETURN
623             break;
624 #endif
625         }
626         case EbtIImage2DArray:
627         case EbtIImageCube:
628         {
629             switch (imageInternalFormat)
630             {
631                 case EiifRGBA32I:
632                 case EiifRGBA16I:
633                 case EiifRGBA8I:
634                 case EiifR32I:
635                     return HLSL_RWTEXTURE_2D_ARRAY_INT4;
636                 default:
637                     UNREACHABLE();
638             }
639 #if !UNREACHABLE_IS_NORETURN
640             break;
641 #endif
642         }
643         case EbtUImage2DArray:
644         case EbtUImageCube:
645         {
646             switch (imageInternalFormat)
647             {
648                 case EiifRGBA32UI:
649                 case EiifRGBA16UI:
650                 case EiifRGBA8UI:
651                 case EiifR32UI:
652                     return HLSL_RWTEXTURE_2D_ARRAY_UINT4;
653                 default:
654                     UNREACHABLE();
655             }
656 #if !UNREACHABLE_IS_NORETURN
657             break;
658 #endif
659         }
660         default:
661             UNREACHABLE();
662     }
663     return HLSL_RWTEXTURE_UNKNOWN;
664 }
665 
RWTextureString(const HLSLRWTextureGroup RWTextureGroup)666 const char *RWTextureString(const HLSLRWTextureGroup RWTextureGroup)
667 {
668     switch (RWTextureGroup)
669     {
670         case HLSL_RWTEXTURE_2D_FLOAT4:
671             return "RWTexture2D<float4>";
672         case HLSL_RWTEXTURE_2D_ARRAY_FLOAT4:
673             return "RWTexture2DArray<float4>";
674         case HLSL_RWTEXTURE_3D_FLOAT4:
675             return "RWTexture3D<float4>";
676         case HLSL_RWTEXTURE_2D_UNORM:
677             return "RWTexture2D<unorm float4>";
678         case HLSL_RWTEXTURE_2D_ARRAY_UNORN:
679             return "RWTexture2DArray<unorm float4>";
680         case HLSL_RWTEXTURE_3D_UNORM:
681             return "RWTexture3D<unorm float4>";
682         case HLSL_RWTEXTURE_2D_SNORM:
683             return "RWTexture2D<snorm float4>";
684         case HLSL_RWTEXTURE_2D_ARRAY_SNORM:
685             return "RWTexture2DArray<snorm float4>";
686         case HLSL_RWTEXTURE_3D_SNORM:
687             return "RWTexture3D<snorm float4>";
688         case HLSL_RWTEXTURE_2D_UINT4:
689             return "RWTexture2D<uint4>";
690         case HLSL_RWTEXTURE_2D_ARRAY_UINT4:
691             return "RWTexture2DArray<uint4>";
692         case HLSL_RWTEXTURE_3D_UINT4:
693             return "RWTexture3D<uint4>";
694         case HLSL_RWTEXTURE_2D_INT4:
695             return "RWTexture2D<int4>";
696         case HLSL_RWTEXTURE_2D_ARRAY_INT4:
697             return "RWTexture2DArray<int4>";
698         case HLSL_RWTEXTURE_3D_INT4:
699             return "RWTexture3D<int4>";
700         default:
701             UNREACHABLE();
702     }
703 
704     return "<unknown read and write texture type>";
705 }
706 
RWTextureString(const TBasicType type,TLayoutImageInternalFormat imageInternalFormat)707 const char *RWTextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
708 {
709     return RWTextureString(RWTextureGroup(type, imageInternalFormat));
710 }
711 
RWTextureGroupSuffix(const HLSLRWTextureGroup type)712 const char *RWTextureGroupSuffix(const HLSLRWTextureGroup type)
713 {
714     switch (type)
715     {
716         case HLSL_RWTEXTURE_2D_FLOAT4:
717             return "RW2D_float4_";
718         case HLSL_RWTEXTURE_2D_ARRAY_FLOAT4:
719             return "RW2DArray_float4_";
720         case HLSL_RWTEXTURE_3D_FLOAT4:
721             return "RW3D_float4_";
722         case HLSL_RWTEXTURE_2D_UNORM:
723             return "RW2D_unorm_float4_";
724         case HLSL_RWTEXTURE_2D_ARRAY_UNORN:
725             return "RW2DArray_unorm_float4_";
726         case HLSL_RWTEXTURE_3D_UNORM:
727             return "RW3D_unorm_float4_";
728         case HLSL_RWTEXTURE_2D_SNORM:
729             return "RW2D_snorm_float4_";
730         case HLSL_RWTEXTURE_2D_ARRAY_SNORM:
731             return "RW2DArray_snorm_float4_";
732         case HLSL_RWTEXTURE_3D_SNORM:
733             return "RW3D_snorm_float4_";
734         case HLSL_RWTEXTURE_2D_UINT4:
735             return "RW2D_uint4_";
736         case HLSL_RWTEXTURE_2D_ARRAY_UINT4:
737             return "RW2DArray_uint4_";
738         case HLSL_RWTEXTURE_3D_UINT4:
739             return "RW3D_uint4_";
740         case HLSL_RWTEXTURE_2D_INT4:
741             return "RW2D_int4_";
742         case HLSL_RWTEXTURE_2D_ARRAY_INT4:
743             return "RW2DArray_int4_";
744         case HLSL_RWTEXTURE_3D_INT4:
745             return "RW3D_int4_";
746         default:
747             UNREACHABLE();
748     }
749 
750     return "<unknown read and write resource>";
751 }
752 
RWTextureGroupSuffix(const TBasicType type,TLayoutImageInternalFormat imageInternalFormat)753 const char *RWTextureGroupSuffix(const TBasicType type,
754                                  TLayoutImageInternalFormat imageInternalFormat)
755 {
756     return RWTextureGroupSuffix(RWTextureGroup(type, imageInternalFormat));
757 }
758 
RWTextureTypeSuffix(const TBasicType type,TLayoutImageInternalFormat imageInternalFormat)759 const char *RWTextureTypeSuffix(const TBasicType type,
760                                 TLayoutImageInternalFormat imageInternalFormat)
761 {
762     switch (type)
763     {
764         case EbtImageCube:
765         {
766             switch (imageInternalFormat)
767             {
768                 case EiifRGBA32F:
769                 case EiifRGBA16F:
770                 case EiifR32F:
771                     return "RWCube_float4_";
772                 case EiifRGBA8:
773                     return "RWCube_unorm_float4_";
774                 case EiifRGBA8_SNORM:
775                     return "RWCube_unorm_float4_";
776                 default:
777                     UNREACHABLE();
778             }
779 #if !UNREACHABLE_IS_NORETURN
780             break;
781 #endif
782         }
783         case EbtIImageCube:
784         {
785             switch (imageInternalFormat)
786             {
787                 case EiifRGBA32I:
788                 case EiifRGBA16I:
789                 case EiifRGBA8I:
790                 case EiifR32I:
791                     return "RWCube_int4_";
792                 default:
793                     UNREACHABLE();
794             }
795 #if !UNREACHABLE_IS_NORETURN
796             break;
797 #endif
798         }
799         case EbtUImageCube:
800         {
801             switch (imageInternalFormat)
802             {
803                 case EiifRGBA32UI:
804                 case EiifRGBA16UI:
805                 case EiifRGBA8UI:
806                 case EiifR32UI:
807                     return "RWCube_uint4_";
808                 default:
809                     UNREACHABLE();
810             }
811 #if !UNREACHABLE_IS_NORETURN
812             break;
813 #endif
814         }
815         default:
816             // All other types are identified by their group suffix
817             return RWTextureGroupSuffix(type, imageInternalFormat);
818     }
819 #if !UNREACHABLE_IS_NORETURN
820     UNREACHABLE();
821     return "_RWTS_invalid_";
822 #endif
823 }
824 
DecorateField(const ImmutableString & string,const TStructure & structure)825 TString DecorateField(const ImmutableString &string, const TStructure &structure)
826 {
827     if (structure.symbolType() != SymbolType::BuiltIn)
828     {
829         return Decorate(string);
830     }
831 
832     return TString(string.data());
833 }
834 
DecoratePrivate(const ImmutableString & privateText)835 TString DecoratePrivate(const ImmutableString &privateText)
836 {
837     return "dx_" + TString(privateText.data());
838 }
839 
Decorate(const ImmutableString & string)840 TString Decorate(const ImmutableString &string)
841 {
842     if (!string.beginsWith("gl_"))
843     {
844         return "_" + TString(string.data());
845     }
846 
847     return TString(string.data());
848 }
849 
DecorateVariableIfNeeded(const TVariable & variable)850 TString DecorateVariableIfNeeded(const TVariable &variable)
851 {
852     if (variable.symbolType() == SymbolType::AngleInternal ||
853         variable.symbolType() == SymbolType::BuiltIn || variable.symbolType() == SymbolType::Empty)
854     {
855         // Besides handling internal variables, we generate names for nameless parameters here.
856         const ImmutableString &name = variable.name();
857         // The name should not have a prefix reserved for user-defined variables or functions.
858         ASSERT(!name.beginsWith("f_"));
859         ASSERT(!name.beginsWith("_"));
860         return TString(name.data());
861     }
862     // For user defined variables, combine variable name with unique id
863     // so variables of the same name in different scopes do not get overwritten.
864     else if (variable.symbolType() == SymbolType::UserDefined &&
865              variable.getType().getQualifier() == EvqTemporary)
866     {
867         return Decorate(variable.name()) + str(variable.uniqueId().get());
868     }
869     else
870     {
871         return Decorate(variable.name());
872     }
873 }
874 
DecorateFunctionIfNeeded(const TFunction * func)875 TString DecorateFunctionIfNeeded(const TFunction *func)
876 {
877     if (func->symbolType() == SymbolType::AngleInternal)
878     {
879         // The name should not have a prefix reserved for user-defined variables or functions.
880         ASSERT(!func->name().beginsWith("f_"));
881         ASSERT(!func->name().beginsWith("_"));
882         return TString(func->name().data());
883     }
884     ASSERT(!func->name().beginsWith("gl_"));
885     // Add an additional f prefix to functions so that they're always disambiguated from variables.
886     // This is necessary in the corner case where a variable declaration hides a function that it
887     // uses in its initializer.
888     return "f_" + TString(func->name().data());
889 }
890 
TypeString(const TType & type)891 TString TypeString(const TType &type)
892 {
893     const TStructure *structure = type.getStruct();
894     if (structure)
895     {
896         if (structure->symbolType() != SymbolType::Empty)
897         {
898             return StructNameString(*structure);
899         }
900         else  // Nameless structure, define in place
901         {
902             return StructureHLSL::defineNameless(*structure);
903         }
904     }
905     else if (type.isMatrix())
906     {
907         int cols = type.getCols();
908         int rows = type.getRows();
909         return "float" + str(cols) + "x" + str(rows);
910     }
911     else
912     {
913         switch (type.getBasicType())
914         {
915             case EbtFloat:
916                 switch (type.getNominalSize())
917                 {
918                     case 1:
919                         return "float";
920                     case 2:
921                         return "float2";
922                     case 3:
923                         return "float3";
924                     case 4:
925                         return "float4";
926                 }
927             case EbtInt:
928                 switch (type.getNominalSize())
929                 {
930                     case 1:
931                         return "int";
932                     case 2:
933                         return "int2";
934                     case 3:
935                         return "int3";
936                     case 4:
937                         return "int4";
938                 }
939             case EbtUInt:
940                 switch (type.getNominalSize())
941                 {
942                     case 1:
943                         return "uint";
944                     case 2:
945                         return "uint2";
946                     case 3:
947                         return "uint3";
948                     case 4:
949                         return "uint4";
950                 }
951             case EbtBool:
952                 switch (type.getNominalSize())
953                 {
954                     case 1:
955                         return "bool";
956                     case 2:
957                         return "bool2";
958                     case 3:
959                         return "bool3";
960                     case 4:
961                         return "bool4";
962                 }
963             case EbtVoid:
964                 return "void";
965             case EbtSampler2D:
966             case EbtISampler2D:
967             case EbtUSampler2D:
968             case EbtSampler2DArray:
969             case EbtISampler2DArray:
970             case EbtUSampler2DArray:
971                 return "sampler2D";
972             case EbtSamplerCube:
973             case EbtISamplerCube:
974             case EbtUSamplerCube:
975                 return "samplerCUBE";
976             case EbtSamplerExternalOES:
977                 return "sampler2D";
978             case EbtSamplerVideoWEBGL:
979                 return "sampler2D";
980             case EbtAtomicCounter:
981                 // Multiple atomic_uints will be implemented as a single RWByteAddressBuffer
982                 return "RWByteAddressBuffer";
983             default:
984                 break;
985         }
986     }
987 
988     UNREACHABLE();
989     return "<unknown type>";
990 }
991 
StructNameString(const TStructure & structure)992 TString StructNameString(const TStructure &structure)
993 {
994     if (structure.symbolType() == SymbolType::Empty)
995     {
996         return "";
997     }
998 
999     // For structures at global scope we use a consistent
1000     // translation so that we can link between shader stages.
1001     if (structure.atGlobalScope())
1002     {
1003         return Decorate(structure.name());
1004     }
1005 
1006     return "ss" + str(structure.uniqueId().get()) + "_" + TString(structure.name().data());
1007 }
1008 
QualifiedStructNameString(const TStructure & structure,bool useHLSLRowMajorPacking,bool useStd140Packing,bool forcePadding)1009 TString QualifiedStructNameString(const TStructure &structure,
1010                                   bool useHLSLRowMajorPacking,
1011                                   bool useStd140Packing,
1012                                   bool forcePadding)
1013 {
1014     if (structure.symbolType() == SymbolType::Empty)
1015     {
1016         return "";
1017     }
1018 
1019     TString prefix = "";
1020 
1021     // Structs packed with row-major matrices in HLSL are prefixed with "rm"
1022     // GLSL column-major maps to HLSL row-major, and the converse is true
1023 
1024     if (useStd140Packing)
1025     {
1026         prefix += "std_";
1027     }
1028 
1029     if (useHLSLRowMajorPacking)
1030     {
1031         prefix += "rm_";
1032     }
1033 
1034     if (forcePadding)
1035     {
1036         prefix += "fp_";
1037     }
1038 
1039     return prefix + StructNameString(structure);
1040 }
1041 
InterpolationString(TQualifier qualifier)1042 const char *InterpolationString(TQualifier qualifier)
1043 {
1044     switch (qualifier)
1045     {
1046         case EvqVaryingIn:
1047             return "";
1048         case EvqFragmentIn:
1049             return "";
1050         case EvqSmoothIn:
1051             return "linear";
1052         case EvqFlatIn:
1053             return "nointerpolation";
1054         case EvqCentroidIn:
1055             return "centroid";
1056         case EvqVaryingOut:
1057             return "";
1058         case EvqVertexOut:
1059             return "";
1060         case EvqSmoothOut:
1061             return "linear";
1062         case EvqFlatOut:
1063             return "nointerpolation";
1064         case EvqCentroidOut:
1065             return "centroid";
1066         case EvqSampleIn:
1067             return "sample";
1068         default:
1069             UNREACHABLE();
1070     }
1071 
1072     return "";
1073 }
1074 
QualifierString(TQualifier qualifier)1075 const char *QualifierString(TQualifier qualifier)
1076 {
1077     switch (qualifier)
1078     {
1079         case EvqIn:
1080             return "in";
1081         case EvqOut:
1082             return "inout";  // 'out' results in an HLSL error if not all fields are written, for
1083                              // GLSL it's undefined
1084         case EvqInOut:
1085             return "inout";
1086         case EvqConstReadOnly:
1087             return "const";
1088         case EvqSampleOut:
1089             return "sample";
1090         default:
1091             UNREACHABLE();
1092     }
1093 
1094     return "";
1095 }
1096 
DisambiguateFunctionName(const TFunction * func)1097 TString DisambiguateFunctionName(const TFunction *func)
1098 {
1099     TString disambiguatingString;
1100     size_t paramCount = func->getParamCount();
1101     for (size_t i = 0; i < paramCount; ++i)
1102     {
1103         DisambiguateFunctionNameForParameterType(func->getParam(i)->getType(),
1104                                                  &disambiguatingString);
1105     }
1106     return disambiguatingString;
1107 }
1108 
DisambiguateFunctionName(const TIntermSequence * args)1109 TString DisambiguateFunctionName(const TIntermSequence *args)
1110 {
1111     TString disambiguatingString;
1112     for (TIntermNode *arg : *args)
1113     {
1114         ASSERT(arg->getAsTyped());
1115         DisambiguateFunctionNameForParameterType(arg->getAsTyped()->getType(),
1116                                                  &disambiguatingString);
1117     }
1118     return disambiguatingString;
1119 }
1120 
1121 }  // namespace sh
1122