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