ReactOS 0.4.17-dev-934-g091855f
hlsl_constant_ops.c
Go to the documentation of this file.
1/*
2 * HLSL constant value operations for constant folding
3 *
4 * Copyright 2022 Francisco Casas for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <math.h>
22
23#include "hlsl.h"
24
25static bool fold_abs(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
26 const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
27{
28 enum hlsl_base_type type = dst_type->e.numeric.type;
29 unsigned int k;
30
31 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
32
33 for (k = 0; k < dst_type->dimx; ++k)
34 {
35 switch (type)
36 {
37 case HLSL_TYPE_FLOAT:
38 case HLSL_TYPE_HALF:
39 dst->u[k].f = fabsf(src->value.u[k].f);
40 break;
41
43 dst->u[k].d = fabs(src->value.u[k].d);
44 break;
45
46 case HLSL_TYPE_INT:
47 /* C's abs(INT_MIN) is undefined, but HLSL evaluates this to INT_MIN */
48 if (src->value.u[k].i == INT_MIN)
49 dst->u[k].i = INT_MIN;
50 else
51 dst->u[k].i = abs(src->value.u[k].i);
52 break;
53
54 case HLSL_TYPE_UINT:
55 dst->u[k].u = src->value.u[k].u;
56 break;
57
58 default:
59 FIXME("Fold abs() for type %s.\n", debug_hlsl_type(ctx, dst_type));
60 return false;
61 }
62 }
63 return true;
64}
65
67{
68 if (isnan(x) || x <= 0)
69 return 0;
70
71 if (x >= 4294967296.0f)
72 return UINT32_MAX;
73
74 return x;
75}
76
77static int32_t float_to_int(float x)
78{
79 if (isnan(x))
80 return 0;
81
82 if (x <= -2147483648.0f)
83 return INT32_MIN;
84
85 if (x >= 2147483648.0f)
86 return INT32_MAX;
87
88 return x;
89}
90
92{
93 if (isnan(x) || x <= 0)
94 return 0;
95
96 if (x >= 4294967296.0)
97 return UINT32_MAX;
98
99 return x;
100}
101
102static int32_t double_to_int(double x)
103{
104 if (isnan(x))
105 return 0;
106
107 if (x <= -2147483648.0)
108 return INT32_MIN;
109
110 if (x >= 2147483648.0)
111 return INT32_MAX;
112
113 return x;
114}
115
116static bool fold_bit_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
117 const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
118{
119 enum hlsl_base_type type = dst_type->e.numeric.type;
120 unsigned int k;
121
122 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
123
124 for (k = 0; k < dst_type->dimx; ++k)
125 {
126 switch (type)
127 {
128 case HLSL_TYPE_INT:
129 case HLSL_TYPE_UINT:
130 case HLSL_TYPE_BOOL:
131 dst->u[k].u = ~src->value.u[k].u;
132 break;
133
134 default:
136 }
137 }
138
139 return true;
140}
141
142static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
143 const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
144{
145 unsigned int k;
146 uint32_t u;
147 int32_t i;
148 double d;
149 float f;
150
151 if (dst_type->dimx != src->node.data_type->dimx
152 || dst_type->dimy != src->node.data_type->dimy)
153 {
154 FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, src->node.data_type),
155 debug_hlsl_type(ctx, dst_type));
156 return false;
157 }
158
159 for (k = 0; k < dst_type->dimx; ++k)
160 {
161 switch (src->node.data_type->e.numeric.type)
162 {
163 case HLSL_TYPE_FLOAT:
164 case HLSL_TYPE_HALF:
165 u = float_to_uint(src->value.u[k].f);
166 i = float_to_int(src->value.u[k].f);
167 f = src->value.u[k].f;
168 d = src->value.u[k].f;
169 break;
170
171 case HLSL_TYPE_DOUBLE:
172 u = double_to_uint(src->value.u[k].d);
173 i = double_to_int(src->value.u[k].d);
174 f = src->value.u[k].d;
175 d = src->value.u[k].d;
176 break;
177
178 case HLSL_TYPE_INT:
179 u = src->value.u[k].i;
180 i = src->value.u[k].i;
181 f = src->value.u[k].i;
182 d = src->value.u[k].i;
183 break;
184
185 case HLSL_TYPE_UINT:
186 u = src->value.u[k].u;
187 i = src->value.u[k].u;
188 f = src->value.u[k].u;
189 d = src->value.u[k].u;
190 break;
191
192 case HLSL_TYPE_BOOL:
193 u = !!src->value.u[k].u;
194 i = !!src->value.u[k].u;
195 f = !!src->value.u[k].u;
196 d = !!src->value.u[k].u;
197 break;
198
199 default:
201 }
202
203 switch (dst_type->e.numeric.type)
204 {
205 case HLSL_TYPE_FLOAT:
206 case HLSL_TYPE_HALF:
207 dst->u[k].f = f;
208 break;
209
210 case HLSL_TYPE_DOUBLE:
211 dst->u[k].d = d;
212 break;
213
214 case HLSL_TYPE_INT:
215 dst->u[k].i = i;
216 break;
217
218 case HLSL_TYPE_UINT:
219 dst->u[k].u = u;
220 break;
221
222 case HLSL_TYPE_BOOL:
223 /* Casts to bool should have already been lowered. */
224 default:
226 }
227 }
228 return true;
229}
230
231static bool fold_ceil(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
232 const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
233{
234 enum hlsl_base_type type = dst_type->e.numeric.type;
235 unsigned int k;
236
237 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
238
239 for (k = 0; k < dst_type->dimx; ++k)
240 {
241 switch (type)
242 {
243 case HLSL_TYPE_FLOAT:
244 case HLSL_TYPE_HALF:
245 dst->u[k].f = ceilf(src->value.u[k].f);
246 break;
247
248 default:
249 FIXME("Fold 'ceil' for type %s.\n", debug_hlsl_type(ctx, dst_type));
250 return false;
251 }
252 }
253
254 return true;
255}
256
257static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
258 const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
259{
260 enum hlsl_base_type type = dst_type->e.numeric.type;
261 unsigned int k;
262
263 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
264
265 for (k = 0; k < dst_type->dimx; ++k)
266 {
267 switch (type)
268 {
269 case HLSL_TYPE_FLOAT:
270 case HLSL_TYPE_HALF:
271 dst->u[k].f = exp2f(src->value.u[k].f);
272 break;
273
274 default:
275 FIXME("Fold 'exp2' for type %s.\n", debug_hlsl_type(ctx, dst_type));
276 return false;
277 }
278 }
279
280 return true;
281}
282
283static bool fold_floor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
284 const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
285{
286 enum hlsl_base_type type = dst_type->e.numeric.type;
287 unsigned int k;
288
289 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
290
291 for (k = 0; k < dst_type->dimx; ++k)
292 {
293 switch (type)
294 {
295 case HLSL_TYPE_FLOAT:
296 case HLSL_TYPE_HALF:
297 dst->u[k].f = floorf(src->value.u[k].f);
298 break;
299
300 default:
301 FIXME("Fold 'floor' for type %s.\n", debug_hlsl_type(ctx, dst_type));
302 return false;
303 }
304 }
305
306 return true;
307}
308
309static bool fold_fract(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
310 const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
311{
312 enum hlsl_base_type type = dst_type->e.numeric.type;
313 unsigned int k;
314 float i;
315
316 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
317
318 for (k = 0; k < dst_type->dimx; ++k)
319 {
320 switch (type)
321 {
322 case HLSL_TYPE_FLOAT:
323 case HLSL_TYPE_HALF:
324 dst->u[k].f = modff(src->value.u[k].f, &i);
325 break;
326
327 default:
328 FIXME("Fold 'fract' for type %s.\n", debug_hlsl_type(ctx, dst_type));
329 return false;
330 }
331 }
332
333 return true;
334}
335
336static bool fold_log2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
337 const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
338{
339 enum hlsl_base_type type = dst_type->e.numeric.type;
340 unsigned int k;
341
342 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
343
344 for (k = 0; k < dst_type->dimx; ++k)
345 {
346 switch (type)
347 {
348 case HLSL_TYPE_FLOAT:
349 case HLSL_TYPE_HALF:
350 if (ctx->profile->major_version >= 4 && src->value.u[k].f < 0.0f)
351 {
353 "Indefinite logarithm result.");
354 }
355 dst->u[k].f = log2f(src->value.u[k].f);
356 if (ctx->profile->major_version < 4 && !isfinite(dst->u[k].f))
357 {
359 "Infinities and NaNs are not allowed by the shader model.");
360 }
361 break;
362
363 case HLSL_TYPE_DOUBLE:
364 if (src->value.u[k].d < 0.0)
365 {
367 "Indefinite logarithm result.");
368 }
369 dst->u[k].d = log2(src->value.u[k].d);
370 break;
371
372 default:
373 FIXME("Fold 'log2' for type %s.\n", debug_hlsl_type(ctx, dst_type));
374 return false;
375 }
376 }
377
378 return true;
379}
380
381static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
382 const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
383{
384 enum hlsl_base_type type = dst_type->e.numeric.type;
385 unsigned int k;
386
387 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
388
389 for (k = 0; k < dst_type->dimx; ++k)
390 {
391 switch (type)
392 {
393 case HLSL_TYPE_FLOAT:
394 case HLSL_TYPE_HALF:
395 dst->u[k].f = -src->value.u[k].f;
396 break;
397
398 case HLSL_TYPE_DOUBLE:
399 dst->u[k].d = -src->value.u[k].d;
400 break;
401
402 case HLSL_TYPE_INT:
403 case HLSL_TYPE_UINT:
404 dst->u[k].u = -src->value.u[k].u;
405 break;
406
407 default:
408 FIXME("Fold negation for type %s.\n", debug_hlsl_type(ctx, dst_type));
409 return false;
410 }
411 }
412 return true;
413}
414
415static bool fold_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
416 const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
417{
418 enum hlsl_base_type type = dst_type->e.numeric.type;
419 unsigned int k;
420
421 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
422
423 for (k = 0; k < dst_type->dimx; ++k)
424 {
425 switch (type)
426 {
427 case HLSL_TYPE_BOOL:
428 dst->u[k].u = ~src->value.u[k].u;
429 break;
430
431 default:
432 FIXME("Fold logic 'not' for type %s.\n", debug_hlsl_type(ctx, dst_type));
433 return false;
434 }
435 }
436 return true;
437}
438
439static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
440 const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
441{
442 enum hlsl_base_type type = dst_type->e.numeric.type;
443 unsigned int k;
444
445 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
446
447 for (k = 0; k < dst_type->dimx; ++k)
448 {
449 switch (type)
450 {
451 case HLSL_TYPE_FLOAT:
452 case HLSL_TYPE_HALF:
453 if (ctx->profile->major_version >= 4 && src->value.u[k].f == 0.0f)
454 {
456 "Floating point division by zero.");
457 }
458 dst->u[k].f = 1.0f / src->value.u[k].f;
459 if (ctx->profile->major_version < 4 && !isfinite(dst->u[k].f))
460 {
462 "Infinities and NaNs are not allowed by the shader model.");
463 }
464 break;
465
466 case HLSL_TYPE_DOUBLE:
467 if (src->value.u[k].d == 0.0)
468 {
470 "Floating point division by zero.");
471 }
472 dst->u[k].d = 1.0 / src->value.u[k].d;
473 break;
474
475 default:
476 FIXME("Fold 'rcp' for type %s.\n", debug_hlsl_type(ctx, dst_type));
477 return false;
478 }
479 }
480
481 return true;
482}
483
484static bool fold_rsq(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
485 const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
486{
487 enum hlsl_base_type type = dst_type->e.numeric.type;
488 unsigned int k;
489
490 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
491
492 for (k = 0; k < dst_type->dimx; ++k)
493 {
494 switch (type)
495 {
496 case HLSL_TYPE_FLOAT:
497 case HLSL_TYPE_HALF:
498 if (ctx->profile->major_version >= 4)
499 {
500 if (src->value.u[k].f < 0.0f)
502 "Imaginary square root result.");
503 else if (src->value.u[k].f == 0.0f)
505 "Floating point division by zero.");
506 }
507 dst->u[k].f = 1.0f / sqrtf(src->value.u[k].f);
508 if (ctx->profile->major_version < 4 && !isfinite(dst->u[k].f))
509 {
511 "Infinities and NaNs are not allowed by the shader model.");
512 }
513 break;
514
515 default:
516 FIXME("Fold 'rsq' for type %s.\n", debug_hlsl_type(ctx, dst_type));
517 return false;
518 }
519 }
520
521 return true;
522}
523
524static bool fold_sat(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
525 const struct hlsl_ir_constant *src)
526{
527 enum hlsl_base_type type = dst_type->e.numeric.type;
528 unsigned int k;
529
530 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
531
532 for (k = 0; k < dst_type->dimx; ++k)
533 {
534 switch (type)
535 {
536 case HLSL_TYPE_FLOAT:
537 case HLSL_TYPE_HALF:
538 dst->u[k].f = min(max(0.0f, src->value.u[k].f), 1.0f);
539 break;
540
541 default:
542 FIXME("Fold 'sat' for type %s.\n", debug_hlsl_type(ctx, dst_type));
543 return false;
544 }
545 }
546
547 return true;
548}
549
550static bool fold_sqrt(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
551 const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
552{
553 enum hlsl_base_type type = dst_type->e.numeric.type;
554 unsigned int k;
555
556 VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
557
558 for (k = 0; k < dst_type->dimx; ++k)
559 {
560 switch (type)
561 {
562 case HLSL_TYPE_FLOAT:
563 case HLSL_TYPE_HALF:
564 if (ctx->profile->major_version >= 4 && src->value.u[k].f < 0.0f)
565 {
567 "Imaginary square root result.");
568 }
569 dst->u[k].f = sqrtf(src->value.u[k].f);
570 if (ctx->profile->major_version < 4 && !isfinite(dst->u[k].f))
571 {
573 "Infinities and NaNs are not allowed by the shader model.");
574 }
575 break;
576
577 case HLSL_TYPE_DOUBLE:
578 if (src->value.u[k].d < 0.0)
579 {
581 "Imaginary square root result.");
582 }
583 dst->u[k].d = sqrt(src->value.u[k].d);
584 break;
585
586 default:
587 FIXME("Fold 'sqrt' for type %s.\n", debug_hlsl_type(ctx, dst_type));
588 return false;
589 }
590 }
591
592 return true;
593}
594
595static bool fold_add(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
596 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
597{
598 enum hlsl_base_type type = dst_type->e.numeric.type;
599 unsigned int k;
600
601 VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
602 VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
603
604 for (k = 0; k < dst_type->dimx; ++k)
605 {
606 switch (type)
607 {
608 case HLSL_TYPE_FLOAT:
609 case HLSL_TYPE_HALF:
610 dst->u[k].f = src1->value.u[k].f + src2->value.u[k].f;
611 break;
612
613 case HLSL_TYPE_DOUBLE:
614 dst->u[k].d = src1->value.u[k].d + src2->value.u[k].d;
615 break;
616
617 /* Handling HLSL_TYPE_INT through the unsigned field to avoid
618 * undefined behavior with signed integers in C. */
619 case HLSL_TYPE_INT:
620 case HLSL_TYPE_UINT:
621 dst->u[k].u = src1->value.u[k].u + src2->value.u[k].u;
622 break;
623
624 default:
625 FIXME("Fold addition for type %s.\n", debug_hlsl_type(ctx, dst_type));
626 return false;
627 }
628 }
629 return true;
630}
631
632static bool fold_and(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
633 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
634{
635 enum hlsl_base_type type = dst_type->e.numeric.type;
636 unsigned int k;
637
638 VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
639 VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
640
641 for (k = 0; k < dst_type->dimx; ++k)
642 {
643 switch (type)
644 {
645 case HLSL_TYPE_INT:
646 case HLSL_TYPE_UINT:
647 case HLSL_TYPE_BOOL:
648 dst->u[k].u = src1->value.u[k].u & src2->value.u[k].u;
649 break;
650
651 default:
652 FIXME("Fold bit/logic and for type %s.\n", debug_hlsl_type(ctx, dst_type));
653 return false;
654 }
655 }
656 return true;
657}
658
659static bool fold_or(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
660 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
661{
662 enum hlsl_base_type type = dst_type->e.numeric.type;
663 unsigned int k;
664
665 VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
666 VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
667
668 for (k = 0; k < dst_type->dimx; ++k)
669 {
670 switch (type)
671 {
672 case HLSL_TYPE_INT:
673 case HLSL_TYPE_UINT:
674 case HLSL_TYPE_BOOL:
675 dst->u[k].u = src1->value.u[k].u | src2->value.u[k].u;
676 break;
677
678 default:
679 FIXME("Fold bit/logic or for type %s.\n", debug_hlsl_type(ctx, dst_type));
680 return false;
681 }
682 }
683 return true;
684}
685
686static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
687 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
688{
689 enum hlsl_base_type type = dst_type->e.numeric.type;
690 unsigned int k;
691
692 VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
693 VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
694
695 for (k = 0; k < dst_type->dimx; ++k)
696 {
697 switch (type)
698 {
699 case HLSL_TYPE_INT:
700 case HLSL_TYPE_UINT:
701 dst->u[k].u = src1->value.u[k].u ^ src2->value.u[k].u;
702 break;
703
704 default:
705 FIXME("Fold bit xor for type %s.\n", debug_hlsl_type(ctx, dst_type));
706 return false;
707 }
708 }
709 return true;
710}
711
712static bool fold_dot(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
713 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
714{
715 enum hlsl_base_type type = dst_type->e.numeric.type;
716 unsigned int k;
717
718 VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
719 VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
720 VKD3D_ASSERT(src1->node.data_type->dimx == src2->node.data_type->dimx);
721
722 dst->u[0].f = 0.0f;
723 for (k = 0; k < src1->node.data_type->dimx; ++k)
724 {
725 switch (type)
726 {
727 case HLSL_TYPE_FLOAT:
728 case HLSL_TYPE_HALF:
729 dst->u[0].f += src1->value.u[k].f * src2->value.u[k].f;
730 break;
731 default:
732 FIXME("Fold 'dot' for type %s.\n", debug_hlsl_type(ctx, dst_type));
733 return false;
734 }
735 }
736
737 return true;
738}
739
740static bool fold_dp2add(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
741 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct hlsl_ir_constant *src3)
742{
743 enum hlsl_base_type type = dst_type->e.numeric.type;
744 unsigned int k;
745
746 VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
747 VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
748 VKD3D_ASSERT(type == src3->node.data_type->e.numeric.type);
749 VKD3D_ASSERT(src1->node.data_type->dimx == src2->node.data_type->dimx);
750 VKD3D_ASSERT(src3->node.data_type->dimx == 1);
751
752 dst->u[0].f = src3->value.u[0].f;
753 for (k = 0; k < src1->node.data_type->dimx; ++k)
754 {
755 switch (type)
756 {
757 case HLSL_TYPE_FLOAT:
758 case HLSL_TYPE_HALF:
759 dst->u[0].f += src1->value.u[k].f * src2->value.u[k].f;
760 break;
761 default:
762 FIXME("Fold 'dp2add' for type %s.\n", debug_hlsl_type(ctx, dst_type));
763 return false;
764 }
765 }
766
767 return true;
768}
769
770static bool fold_div(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
771 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2,
772 const struct vkd3d_shader_location *loc)
773{
774 enum hlsl_base_type type = dst_type->e.numeric.type;
775 unsigned int k;
776
777 VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
778 VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
779
780 for (k = 0; k < dst_type->dimx; ++k)
781 {
782 switch (type)
783 {
784 case HLSL_TYPE_FLOAT:
785 case HLSL_TYPE_HALF:
786 if (ctx->profile->major_version >= 4 && src2->value.u[k].f == 0)
787 {
789 "Floating point division by zero.");
790 }
791 dst->u[k].f = src1->value.u[k].f / src2->value.u[k].f;
792 if (ctx->profile->major_version < 4 && !isfinite(dst->u[k].f))
793 {
795 "Infinities and NaNs are not allowed by the shader model.");
796 }
797 break;
798
799 case HLSL_TYPE_DOUBLE:
800 if (src2->value.u[k].d == 0)
801 {
803 "Floating point division by zero.");
804 }
805 dst->u[k].d = src1->value.u[k].d / src2->value.u[k].d;
806 break;
807
808 case HLSL_TYPE_INT:
809 if (src2->value.u[k].i == 0)
810 {
812 "Division by zero.");
813 return false;
814 }
815 if (src1->value.u[k].i == INT_MIN && src2->value.u[k].i == -1)
816 dst->u[k].i = INT_MIN;
817 else
818 dst->u[k].i = src1->value.u[k].i / src2->value.u[k].i;
819 break;
820
821 case HLSL_TYPE_UINT:
822 if (src2->value.u[k].u == 0)
823 {
825 "Division by zero.");
826 return false;
827 }
828 dst->u[k].u = src1->value.u[k].u / src2->value.u[k].u;
829 break;
830
831 default:
832 FIXME("Fold division for type %s.\n", debug_hlsl_type(ctx, dst_type));
833 return false;
834 }
835 }
836 return true;
837}
838
839static bool fold_equal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
840 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
841{
842 unsigned int k;
843
844 VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
845 VKD3D_ASSERT(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type);
846
847 for (k = 0; k < dst_type->dimx; ++k)
848 {
849 switch (src1->node.data_type->e.numeric.type)
850 {
851 case HLSL_TYPE_FLOAT:
852 case HLSL_TYPE_HALF:
853 dst->u[k].u = src1->value.u[k].f == src2->value.u[k].f;
854 break;
855
856 case HLSL_TYPE_DOUBLE:
857 dst->u[k].u = src1->value.u[k].d == src2->value.u[k].d;
858 break;
859
860 case HLSL_TYPE_INT:
861 case HLSL_TYPE_UINT:
862 case HLSL_TYPE_BOOL:
863 dst->u[k].u = src1->value.u[k].u == src2->value.u[k].u;
864 break;
865
866 default:
868 }
869
870 dst->u[k].u *= ~0u;
871 }
872 return true;
873}
874
875static bool fold_gequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
876 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
877{
878 unsigned int k;
879
880 VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
881 VKD3D_ASSERT(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type);
882
883 for (k = 0; k < dst_type->dimx; ++k)
884 {
885 switch (src1->node.data_type->e.numeric.type)
886 {
887 case HLSL_TYPE_FLOAT:
888 case HLSL_TYPE_HALF:
889 dst->u[k].u = src1->value.u[k].f >= src2->value.u[k].f;
890 break;
891
892 case HLSL_TYPE_DOUBLE:
893 dst->u[k].u = src1->value.u[k].d >= src2->value.u[k].d;
894 break;
895
896 case HLSL_TYPE_INT:
897 dst->u[k].u = src1->value.u[k].i >= src2->value.u[k].i;
898 break;
899
900 case HLSL_TYPE_UINT:
901 case HLSL_TYPE_BOOL:
902 dst->u[k].u = src1->value.u[k].u >= src2->value.u[k].u;
903 break;
904
905 default:
907 }
908
909 dst->u[k].u *= ~0u;
910 }
911 return true;
912}
913
914static bool fold_less(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
915 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
916{
917 unsigned int k;
918
919 VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
920 VKD3D_ASSERT(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type);
921
922 for (k = 0; k < dst_type->dimx; ++k)
923 {
924 switch (src1->node.data_type->e.numeric.type)
925 {
926 case HLSL_TYPE_FLOAT:
927 case HLSL_TYPE_HALF:
928 dst->u[k].u = src1->value.u[k].f < src2->value.u[k].f;
929 break;
930
931 case HLSL_TYPE_DOUBLE:
932 dst->u[k].u = src1->value.u[k].d < src2->value.u[k].d;
933 break;
934
935 case HLSL_TYPE_INT:
936 dst->u[k].u = src1->value.u[k].i < src2->value.u[k].i;
937 break;
938
939 case HLSL_TYPE_UINT:
940 case HLSL_TYPE_BOOL:
941 dst->u[k].u = src1->value.u[k].u < src2->value.u[k].u;
942 break;
943
944 default:
946 }
947
948 dst->u[k].u *= ~0u;
949 }
950 return true;
951}
952
953static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
954 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
955{
956 unsigned int k;
957
958 VKD3D_ASSERT(dst_type->e.numeric.type == src1->node.data_type->e.numeric.type);
959 VKD3D_ASSERT(src2->node.data_type->e.numeric.type == HLSL_TYPE_INT);
960
961 for (k = 0; k < dst_type->dimx; ++k)
962 {
963 unsigned int shift = src2->value.u[k].u % 32;
964
965 switch (src1->node.data_type->e.numeric.type)
966 {
967 case HLSL_TYPE_INT:
968 dst->u[k].i = src1->value.u[k].i << shift;
969 break;
970
971 case HLSL_TYPE_UINT:
972 dst->u[k].u = src1->value.u[k].u << shift;
973 break;
974
975 default:
977 }
978 }
979
980 return true;
981}
982
983static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
984 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
985{
986 enum hlsl_base_type type = dst_type->e.numeric.type;
987 unsigned int k;
988
989 VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
990 VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
991
992 for (k = 0; k < dst_type->dimx; ++k)
993 {
994 switch (type)
995 {
996 case HLSL_TYPE_FLOAT:
997 case HLSL_TYPE_HALF:
998 dst->u[k].f = fmaxf(src1->value.u[k].f, src2->value.u[k].f);
999 break;
1000
1001 case HLSL_TYPE_DOUBLE:
1002 dst->u[k].d = fmax(src1->value.u[k].d, src2->value.u[k].d);
1003 break;
1004
1005 case HLSL_TYPE_INT:
1006 dst->u[k].i = max(src1->value.u[k].i, src2->value.u[k].i);
1007 break;
1008
1009 case HLSL_TYPE_UINT:
1010 dst->u[k].u = max(src1->value.u[k].u, src2->value.u[k].u);
1011 break;
1012
1013 default:
1014 FIXME("Fold max for type %s.\n", debug_hlsl_type(ctx, dst_type));
1015 return false;
1016 }
1017 }
1018 return true;
1019}
1020
1021static bool fold_min(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
1022 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
1023{
1024 enum hlsl_base_type type = dst_type->e.numeric.type;
1025 unsigned int k;
1026
1027 VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
1028 VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
1029
1030 for (k = 0; k < dst_type->dimx; ++k)
1031 {
1032 switch (type)
1033 {
1034 case HLSL_TYPE_FLOAT:
1035 case HLSL_TYPE_HALF:
1036 dst->u[k].f = fminf(src1->value.u[k].f, src2->value.u[k].f);
1037 break;
1038
1039 case HLSL_TYPE_DOUBLE:
1040 dst->u[k].d = fmin(src1->value.u[k].d, src2->value.u[k].d);
1041 break;
1042
1043 case HLSL_TYPE_INT:
1044 dst->u[k].i = min(src1->value.u[k].i, src2->value.u[k].i);
1045 break;
1046
1047 case HLSL_TYPE_UINT:
1048 dst->u[k].u = min(src1->value.u[k].u, src2->value.u[k].u);
1049 break;
1050
1051 default:
1052 FIXME("Fold min for type %s.\n", debug_hlsl_type(ctx, dst_type));
1053 return false;
1054 }
1055 }
1056 return true;
1057}
1058
1059static bool fold_mod(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
1060 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2,
1061 const struct vkd3d_shader_location *loc)
1062{
1063 enum hlsl_base_type type = dst_type->e.numeric.type;
1064 unsigned int k;
1065
1066 VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
1067 VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
1068
1069 for (k = 0; k < dst_type->dimx; ++k)
1070 {
1071 switch (type)
1072 {
1073 case HLSL_TYPE_INT:
1074 if (src2->value.u[k].i == 0)
1075 {
1076 hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO, "Division by zero.");
1077 return false;
1078 }
1079 if (src1->value.u[k].i == INT_MIN && src2->value.u[k].i == -1)
1080 dst->u[k].i = 0;
1081 else
1082 dst->u[k].i = src1->value.u[k].i % src2->value.u[k].i;
1083 break;
1084
1085 case HLSL_TYPE_UINT:
1086 if (src2->value.u[k].u == 0)
1087 {
1088 hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO, "Division by zero.");
1089 return false;
1090 }
1091 dst->u[k].u = src1->value.u[k].u % src2->value.u[k].u;
1092 break;
1093
1094 default:
1095 FIXME("Fold modulus for type %s.\n", debug_hlsl_type(ctx, dst_type));
1096 return false;
1097 }
1098 }
1099 return true;
1100}
1101
1102static bool fold_mul(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
1103 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
1104{
1105 enum hlsl_base_type type = dst_type->e.numeric.type;
1106 unsigned int k;
1107
1108 VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
1109 VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
1110
1111 for (k = 0; k < dst_type->dimx; ++k)
1112 {
1113 switch (type)
1114 {
1115 case HLSL_TYPE_FLOAT:
1116 case HLSL_TYPE_HALF:
1117 dst->u[k].f = src1->value.u[k].f * src2->value.u[k].f;
1118 break;
1119
1120 case HLSL_TYPE_DOUBLE:
1121 dst->u[k].d = src1->value.u[k].d * src2->value.u[k].d;
1122 break;
1123
1124 case HLSL_TYPE_INT:
1125 case HLSL_TYPE_UINT:
1126 dst->u[k].u = src1->value.u[k].u * src2->value.u[k].u;
1127 break;
1128
1129 default:
1130 FIXME("Fold multiplication for type %s.\n", debug_hlsl_type(ctx, dst_type));
1131 return false;
1132 }
1133 }
1134 return true;
1135}
1136
1137static bool fold_nequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
1138 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
1139{
1140 unsigned int k;
1141
1142 VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
1143 VKD3D_ASSERT(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type);
1144
1145 for (k = 0; k < dst_type->dimx; ++k)
1146 {
1147 switch (src1->node.data_type->e.numeric.type)
1148 {
1149 case HLSL_TYPE_FLOAT:
1150 case HLSL_TYPE_HALF:
1151 dst->u[k].u = src1->value.u[k].f != src2->value.u[k].f;
1152 break;
1153
1154 case HLSL_TYPE_DOUBLE:
1155 dst->u[k].u = src1->value.u[k].d != src2->value.u[k].d;
1156 break;
1157
1158 case HLSL_TYPE_INT:
1159 case HLSL_TYPE_UINT:
1160 case HLSL_TYPE_BOOL:
1161 dst->u[k].u = src1->value.u[k].u != src2->value.u[k].u;
1162 break;
1163
1164 default:
1166 }
1167
1168 dst->u[k].u *= ~0u;
1169 }
1170 return true;
1171}
1172
1173static bool fold_ternary(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
1174 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct hlsl_ir_constant *src3)
1175{
1176 unsigned int k;
1177
1178 VKD3D_ASSERT(dst_type->e.numeric.type == src2->node.data_type->e.numeric.type);
1179 VKD3D_ASSERT(dst_type->e.numeric.type == src3->node.data_type->e.numeric.type);
1180 VKD3D_ASSERT(src1->node.data_type->e.numeric.type == HLSL_TYPE_BOOL);
1181
1182 for (k = 0; k < dst_type->dimx; ++k)
1183 dst->u[k] = src1->value.u[k].u ? src2->value.u[k] : src3->value.u[k];
1184
1185 return true;
1186}
1187
1188static bool fold_rshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
1189 const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
1190{
1191 unsigned int k;
1192
1193 VKD3D_ASSERT(dst_type->e.numeric.type == src1->node.data_type->e.numeric.type);
1194 VKD3D_ASSERT(src2->node.data_type->e.numeric.type == HLSL_TYPE_INT);
1195
1196 for (k = 0; k < dst_type->dimx; ++k)
1197 {
1198 unsigned int shift = src2->value.u[k].u % 32;
1199
1200 switch (src1->node.data_type->e.numeric.type)
1201 {
1202 case HLSL_TYPE_INT:
1203 dst->u[k].i = src1->value.u[k].i >> shift;
1204 break;
1205
1206 case HLSL_TYPE_UINT:
1207 dst->u[k].u = src1->value.u[k].u >> shift;
1208 break;
1209
1210 default:
1212 }
1213 }
1214
1215 return true;
1216}
1217
1218bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
1219{
1220 struct hlsl_ir_constant *arg1, *arg2 = NULL, *arg3 = NULL;
1221 struct hlsl_constant_value res = {0};
1222 struct hlsl_ir_node *res_node;
1223 struct hlsl_ir_expr *expr;
1224 unsigned int i;
1225 bool success;
1226
1227 if (instr->type != HLSL_IR_EXPR)
1228 return false;
1229 expr = hlsl_ir_expr(instr);
1230 if (!expr->operands[0].node)
1231 return false;
1232
1233 if (instr->data_type->class > HLSL_CLASS_VECTOR)
1234 return false;
1235
1236 for (i = 0; i < ARRAY_SIZE(expr->operands); ++i)
1237 {
1238 if (expr->operands[i].node)
1239 {
1240 if (expr->operands[i].node->type != HLSL_IR_CONSTANT)
1241 return false;
1242 VKD3D_ASSERT(expr->operands[i].node->data_type->class <= HLSL_CLASS_VECTOR);
1243 }
1244 }
1245 arg1 = hlsl_ir_constant(expr->operands[0].node);
1246 if (expr->operands[1].node)
1247 arg2 = hlsl_ir_constant(expr->operands[1].node);
1248 if (expr->operands[2].node)
1249 arg3 = hlsl_ir_constant(expr->operands[2].node);
1250
1251 switch (expr->op)
1252 {
1253 case HLSL_OP1_ABS:
1254 success = fold_abs(ctx, &res, instr->data_type, arg1);
1255 break;
1256
1257 case HLSL_OP1_BIT_NOT:
1258 success = fold_bit_not(ctx, &res, instr->data_type, arg1);
1259 break;
1260
1261 case HLSL_OP1_CAST:
1262 success = fold_cast(ctx, &res, instr->data_type, arg1);
1263 break;
1264
1265 case HLSL_OP1_CEIL:
1266 success = fold_ceil(ctx, &res, instr->data_type, arg1);
1267 break;
1268
1269 case HLSL_OP1_EXP2:
1270 success = fold_exp2(ctx, &res, instr->data_type, arg1);
1271 break;
1272
1273 case HLSL_OP1_FLOOR:
1274 success = fold_floor(ctx, &res, instr->data_type, arg1);
1275 break;
1276
1277 case HLSL_OP1_FRACT:
1278 success = fold_fract(ctx, &res, instr->data_type, arg1);
1279 break;
1280
1281 case HLSL_OP1_LOG2:
1282 success = fold_log2(ctx, &res, instr->data_type, arg1, &instr->loc);
1283 break;
1284
1285 case HLSL_OP1_NEG:
1286 success = fold_neg(ctx, &res, instr->data_type, arg1);
1287 break;
1288
1289 case HLSL_OP1_LOGIC_NOT:
1290 success = fold_not(ctx, &res, instr->data_type, arg1);
1291 break;
1292
1293 case HLSL_OP1_RCP:
1294 success = fold_rcp(ctx, &res, instr->data_type, arg1, &instr->loc);
1295 break;
1296
1297 case HLSL_OP1_RSQ:
1298 success = fold_rsq(ctx, &res, instr->data_type, arg1, &instr->loc);
1299 break;
1300
1301 case HLSL_OP1_SAT:
1302 success = fold_sat(ctx, &res, instr->data_type, arg1);
1303 break;
1304
1305 case HLSL_OP1_SQRT:
1306 success = fold_sqrt(ctx, &res, instr->data_type, arg1, &instr->loc);
1307 break;
1308
1309 case HLSL_OP2_ADD:
1310 success = fold_add(ctx, &res, instr->data_type, arg1, arg2);
1311 break;
1312
1313 case HLSL_OP2_BIT_AND:
1314 case HLSL_OP2_LOGIC_AND:
1315 success = fold_and(ctx, &res, instr->data_type, arg1, arg2);
1316 break;
1317
1318 case HLSL_OP2_BIT_OR:
1319 case HLSL_OP2_LOGIC_OR:
1320 success = fold_or(ctx, &res, instr->data_type, arg1, arg2);
1321 break;
1322
1323 case HLSL_OP2_BIT_XOR:
1324 success = fold_bit_xor(ctx, &res, instr->data_type, arg1, arg2);
1325 break;
1326
1327 case HLSL_OP2_DOT:
1328 success = fold_dot(ctx, &res, instr->data_type, arg1, arg2);
1329 break;
1330
1331 case HLSL_OP2_DIV:
1332 success = fold_div(ctx, &res, instr->data_type, arg1, arg2, &instr->loc);
1333 break;
1334
1335 case HLSL_OP2_EQUAL:
1336 success = fold_equal(ctx, &res, instr->data_type, arg1, arg2);
1337 break;
1338
1339 case HLSL_OP2_GEQUAL:
1340 success = fold_gequal(ctx, &res, instr->data_type, arg1, arg2);
1341 break;
1342
1343 case HLSL_OP2_LESS:
1344 success = fold_less(ctx, &res, instr->data_type, arg1, arg2);
1345 break;
1346
1347 case HLSL_OP2_LSHIFT:
1348 success = fold_lshift(ctx, &res, instr->data_type, arg1, arg2);
1349 break;
1350
1351 case HLSL_OP2_MAX:
1352 success = fold_max(ctx, &res, instr->data_type, arg1, arg2);
1353 break;
1354
1355 case HLSL_OP2_MIN:
1356 success = fold_min(ctx, &res, instr->data_type, arg1, arg2);
1357 break;
1358
1359 case HLSL_OP2_MOD:
1360 success = fold_mod(ctx, &res, instr->data_type, arg1, arg2, &instr->loc);
1361 break;
1362
1363 case HLSL_OP2_MUL:
1364 success = fold_mul(ctx, &res, instr->data_type, arg1, arg2);
1365 break;
1366
1367 case HLSL_OP2_NEQUAL:
1368 success = fold_nequal(ctx, &res, instr->data_type, arg1, arg2);
1369 break;
1370
1371 case HLSL_OP2_RSHIFT:
1372 success = fold_rshift(ctx, &res, instr->data_type, arg1, arg2);
1373 break;
1374
1375 case HLSL_OP3_DP2ADD:
1376 success = fold_dp2add(ctx, &res, instr->data_type, arg1, arg2, arg3);
1377 break;
1378
1379 case HLSL_OP3_TERNARY:
1381 break;
1382
1383 default:
1384 FIXME("Fold \"%s\" expression.\n", debug_hlsl_expr_op(expr->op));
1385 success = false;
1386 break;
1387 }
1388
1389 if (success)
1390 {
1391 if (!(res_node = hlsl_new_constant(ctx, instr->data_type, &res, &instr->loc)))
1392 return false;
1393 list_add_before(&expr->node.entry, &res_node->entry);
1394 hlsl_replace_node(&expr->node, res_node);
1395 }
1396 return success;
1397}
1398
1399static bool constant_is_zero(struct hlsl_ir_constant *const_arg)
1400{
1401 struct hlsl_type *data_type = const_arg->node.data_type;
1402 unsigned int k;
1403
1404 for (k = 0; k < data_type->dimx; ++k)
1405 {
1406 switch (data_type->e.numeric.type)
1407 {
1408 case HLSL_TYPE_FLOAT:
1409 case HLSL_TYPE_HALF:
1410 if (const_arg->value.u[k].f != 0.0f)
1411 return false;
1412 break;
1413
1414 case HLSL_TYPE_DOUBLE:
1415 if (const_arg->value.u[k].d != 0.0)
1416 return false;
1417 break;
1418
1419 case HLSL_TYPE_UINT:
1420 case HLSL_TYPE_INT:
1421 case HLSL_TYPE_BOOL:
1422 if (const_arg->value.u[k].u != 0)
1423 return false;
1424 break;
1425
1426 default:
1427 return false;
1428 }
1429 }
1430 return true;
1431}
1432
1433static bool constant_is_one(struct hlsl_ir_constant *const_arg)
1434{
1435 struct hlsl_type *data_type = const_arg->node.data_type;
1436 unsigned int k;
1437
1438 for (k = 0; k < data_type->dimx; ++k)
1439 {
1440 switch (data_type->e.numeric.type)
1441 {
1442 case HLSL_TYPE_FLOAT:
1443 case HLSL_TYPE_HALF:
1444 if (const_arg->value.u[k].f != 1.0f)
1445 return false;
1446 break;
1447
1448 case HLSL_TYPE_DOUBLE:
1449 if (const_arg->value.u[k].d != 1.0)
1450 return false;
1451 break;
1452
1453 case HLSL_TYPE_UINT:
1454 case HLSL_TYPE_INT:
1455 if (const_arg->value.u[k].u != 1)
1456 return false;
1457 break;
1458
1459 case HLSL_TYPE_BOOL:
1460 if (const_arg->value.u[k].u != ~0)
1461 return false;
1462 break;
1463
1464 default:
1465 return false;
1466 }
1467 }
1468 return true;
1469}
1470
1472{
1473 struct hlsl_ir_constant *const_arg = NULL;
1474 struct hlsl_ir_node *mut_arg = NULL;
1475 struct hlsl_ir_node *res_node;
1476 struct hlsl_ir_expr *expr;
1477 unsigned int i;
1478
1479 if (instr->type != HLSL_IR_EXPR)
1480 return false;
1481 expr = hlsl_ir_expr(instr);
1482
1483 if (instr->data_type->class > HLSL_CLASS_VECTOR)
1484 return false;
1485
1486 /* Verify that the expression has two operands. */
1487 for (i = 0; i < ARRAY_SIZE(expr->operands); ++i)
1488 {
1489 if (!!expr->operands[i].node != (i < 2))
1490 return false;
1491 }
1492
1493 if (expr->operands[0].node->type == HLSL_IR_CONSTANT)
1494 {
1495 const_arg = hlsl_ir_constant(expr->operands[0].node);
1496 mut_arg = expr->operands[1].node;
1497 }
1498 else if (expr->operands[1].node->type == HLSL_IR_CONSTANT)
1499 {
1500 mut_arg = expr->operands[0].node;
1501 const_arg = hlsl_ir_constant(expr->operands[1].node);
1502 }
1503 else
1504 {
1505 return false;
1506 }
1507
1508 res_node = NULL;
1509 switch (expr->op)
1510 {
1511 case HLSL_OP2_ADD:
1512 if (constant_is_zero(const_arg))
1513 res_node = mut_arg;
1514 break;
1515
1516 case HLSL_OP2_MUL:
1517 if (constant_is_one(const_arg))
1518 res_node = mut_arg;
1519 break;
1520
1521 case HLSL_OP2_LOGIC_AND:
1522 if (constant_is_zero(const_arg))
1523 res_node = &const_arg->node;
1524 else if (constant_is_one(const_arg))
1525 res_node = mut_arg;
1526 break;
1527
1528 case HLSL_OP2_LOGIC_OR:
1529 if (constant_is_zero(const_arg))
1530 res_node = mut_arg;
1531 else if (constant_is_one(const_arg))
1532 res_node = &const_arg->node;
1533 break;
1534
1535 default:
1536 break;
1537 }
1538
1539 if (res_node)
1540 {
1541 hlsl_replace_node(&expr->node, res_node);
1542 return true;
1543 }
1544 return false;
1545}
1546
1548{
1549 struct hlsl_constant_value value;
1550 struct hlsl_ir_swizzle *swizzle;
1551 struct hlsl_ir_constant *src;
1552 struct hlsl_ir_node *dst;
1553 unsigned int i;
1554
1555 if (instr->type != HLSL_IR_SWIZZLE)
1556 return false;
1557 swizzle = hlsl_ir_swizzle(instr);
1558 if (swizzle->val.node->type != HLSL_IR_CONSTANT)
1559 return false;
1560 src = hlsl_ir_constant(swizzle->val.node);
1561
1562 for (i = 0; i < swizzle->node.data_type->dimx; ++i)
1563 value.u[i] = src->value.u[hlsl_swizzle_get_component(swizzle->swizzle, i)];
1564
1565 if (!(dst = hlsl_new_constant(ctx, instr->data_type, &value, &instr->loc)))
1566 return false;
1567
1568 list_add_before(&swizzle->node.entry, &dst->entry);
1569 hlsl_replace_node(&swizzle->node, dst);
1570 return true;
1571}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define NULL
Definition: types.h:112
INT32 int32_t
Definition: types.h:71
UINT32 uint32_t
Definition: types.h:75
#define INT_MIN
Definition: limits.h:25
#define isfinite(x)
Definition: math.h:363
#define isnan(x)
Definition: math.h:360
_ACRTIMP double __cdecl sqrt(double)
Definition: sqrt.c:5
_ACRTIMP double __cdecl fabs(double)
_ACRTIMP double __cdecl log2(double)
Definition: stubs.c:62
_ACRTIMP double __cdecl fmin(double, double)
_ACRTIMP double __cdecl fmax(double, double)
_ACRTIMP float __cdecl fmaxf(float, float)
_ACRTIMP float __cdecl fabsf(float)
_ACRTIMP float __cdecl log2f(float)
Definition: stubs.c:68
_ACRTIMP float __cdecl modff(float, float *)
Definition: modff.c:30
_ACRTIMP float __cdecl exp2f(float)
Definition: mathf.c:69
_ACRTIMP float __cdecl fminf(float, float)
#define INT32_MAX
Definition: stdint.h:80
#define INT32_MIN
Definition: stdint.h:75
#define UINT32_MAX
Definition: stdint.h:85
#define abs(i)
Definition: fconv.c:206
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLuint GLenum swizzle
Definition: glext.h:9511
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg3
Definition: glext.h:9515
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
GLfloat f
Definition: glext.h:7540
GLenum GLenum dst
Definition: glext.h:6340
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
enum wined3d_data_type data_type
Definition: glsl_shader.c:71
struct hlsl_ir_node * hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *type, const struct hlsl_constant_value *value, const struct vkd3d_shader_location *loc)
Definition: hlsl.c:1521
const char * debug_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type)
Definition: hlsl.c:2889
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, enum vkd3d_shader_error error, const char *fmt,...)
Definition: hlsl.c:35
void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, enum vkd3d_shader_error error, const char *fmt,...)
Definition: hlsl.c:48
void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new)
Definition: hlsl.c:3626
const char * debug_hlsl_expr_op(enum hlsl_ir_expr_op op)
Definition: hlsl.c:3176
@ HLSL_CLASS_VECTOR
Definition: hlsl.h:84
@ HLSL_IR_SWIZZLE
Definition: hlsl.h:327
@ HLSL_IR_CONSTANT
Definition: hlsl.h:316
@ HLSL_IR_EXPR
Definition: hlsl.h:317
hlsl_base_type
Definition: hlsl.h:114
@ HLSL_TYPE_HALF
Definition: hlsl.h:116
@ HLSL_TYPE_BOOL
Definition: hlsl.h:120
@ HLSL_TYPE_UINT
Definition: hlsl.h:119
@ HLSL_TYPE_INT
Definition: hlsl.h:118
@ HLSL_TYPE_FLOAT
Definition: hlsl.h:115
@ HLSL_TYPE_DOUBLE
Definition: hlsl.h:117
@ HLSL_OP2_LESS
Definition: hlsl.h:727
@ HLSL_OP2_LOGIC_AND
Definition: hlsl.h:728
@ HLSL_OP2_LOGIC_OR
Definition: hlsl.h:729
@ HLSL_OP1_NEG
Definition: hlsl.h:705
@ HLSL_OP2_DIV
Definition: hlsl.h:723
@ HLSL_OP2_LSHIFT
Definition: hlsl.h:730
@ HLSL_OP2_ADD
Definition: hlsl.h:718
@ HLSL_OP1_SAT
Definition: hlsl.h:711
@ HLSL_OP2_NEQUAL
Definition: hlsl.h:735
@ HLSL_OP2_MIN
Definition: hlsl.h:732
@ HLSL_OP1_BIT_NOT
Definition: hlsl.h:687
@ HLSL_OP1_ABS
Definition: hlsl.h:686
@ HLSL_OP1_CEIL
Definition: hlsl.h:689
@ HLSL_OP2_MAX
Definition: hlsl.h:731
@ HLSL_OP1_FRACT
Definition: hlsl.h:702
@ HLSL_OP2_BIT_XOR
Definition: hlsl.h:721
@ HLSL_OP2_BIT_AND
Definition: hlsl.h:719
@ HLSL_OP2_MOD
Definition: hlsl.h:733
@ HLSL_OP2_RSHIFT
Definition: hlsl.h:736
@ HLSL_OP1_FLOOR
Definition: hlsl.h:701
@ HLSL_OP2_MUL
Definition: hlsl.h:734
@ HLSL_OP2_GEQUAL
Definition: hlsl.h:726
@ HLSL_OP2_EQUAL
Definition: hlsl.h:725
@ HLSL_OP1_RCP
Definition: hlsl.h:707
@ HLSL_OP3_TERNARY
Definition: hlsl.h:746
@ HLSL_OP1_LOG2
Definition: hlsl.h:703
@ HLSL_OP1_EXP2
Definition: hlsl.h:698
@ HLSL_OP3_DP2ADD
Definition: hlsl.h:742
@ HLSL_OP1_LOGIC_NOT
Definition: hlsl.h:704
@ HLSL_OP1_RSQ
Definition: hlsl.h:710
@ HLSL_OP1_SQRT
Definition: hlsl.h:715
@ HLSL_OP2_DOT
Definition: hlsl.h:724
@ HLSL_OP2_BIT_OR
Definition: hlsl.h:720
@ HLSL_OP1_CAST
Definition: hlsl.h:688
static unsigned int hlsl_swizzle_get_component(uint32_t swizzle, unsigned int idx)
Definition: hlsl.h:68
static bool fold_rsq(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
static bool fold_equal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_nequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_floor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
static bool fold_rshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_ceil(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
static bool constant_is_one(struct hlsl_ir_constant *const_arg)
static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_sqrt(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
static bool fold_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
static bool constant_is_zero(struct hlsl_ir_constant *const_arg)
static bool fold_fract(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
static int32_t float_to_int(float x)
static bool fold_mod(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct vkd3d_shader_location *loc)
static bool fold_min(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_sat(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
static int32_t double_to_int(double x)
bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
static bool fold_ternary(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct hlsl_ir_constant *src3)
static bool fold_dp2add(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct hlsl_ir_constant *src3)
static bool fold_gequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_less(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_bit_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_mul(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_div(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct vkd3d_shader_location *loc)
bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
static bool fold_log2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
static uint32_t float_to_uint(float x)
static bool fold_dot(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
static bool fold_and(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_or(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static bool fold_add(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
static uint32_t double_to_uint(double x)
static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
static bool fold_abs(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
#define d
Definition: ke_i.h:81
#define f
Definition: ke_i.h:83
#define shift
Definition: input.c:3280
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
#define ceilf(x)
Definition: mymath.h:62
#define floorf(x)
Definition: mymath.h:65
#define sqrtf(x)
Definition: mymath.h:59
__WINE_SERVER_LIST_INLINE void list_add_before(struct list *elem, struct list *to_add)
Definition: list.h:89
Definition: http.c:7252
char * value
Definition: wpp.c:53
Definition: query.h:86
int type
Definition: query.h:87
struct hlsl_ir_node node
Definition: hlsl.h:877
struct hlsl_ir_constant::hlsl_constant_value value
struct list entry
Definition: hlsl.h:341
enum hlsl_ir_node_type type
Definition: hlsl.h:345
struct hlsl_type * data_type
Definition: hlsl.h:349
struct vkd3d_shader_location loc
Definition: hlsl.h:355
unsigned int dimx
Definition: hlsl.h:187
struct hlsl_type::@5997::@5998 numeric
union hlsl_type::@5997 e
unsigned int dimy
Definition: hlsl.h:188
#define max(a, b)
Definition: svc.c:63
Definition: pdh_main.c:64
#define vkd3d_unreachable()
Definition: vkd3d_common.h:119
#define VKD3D_ASSERT(cond)
Definition: vkd3d_common.h:49
@ VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO
@ VKD3D_SHADER_ERROR_HLSL_NON_FINITE_RESULT
@ VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT
@ VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO
@ VKD3D_SHADER_WARNING_HLSL_NON_FINITE_RESULT
#define success(from, fromstr, to, tostr)