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