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