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