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