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