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