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