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