| 83 | } |
| 84 | |
| 85 | std::string finalize_preamble() const |
| 86 | { |
| 87 | std::string preamble; |
| 88 | |
| 89 | #define IMPLEMENT_INTRINSIC_FALLBACK_ASINT(n) \ |
| 90 | "int" #n " __asint(float" #n " v) {" \ |
| 91 | "float" #n " e = 0;" \ |
| 92 | "float" #n " f = frexp(v, e) * 2 - 1;" /* frexp does not include sign bit in HLSL, so can use as is */ \ |
| 93 | "float" #n " m = ldexp(f, 23);" \ |
| 94 | "return (v == 0) ? 0 : (v < 0 ? 2147483648 : 0) + (" /* Zero (does not handle negative zero) */ \ |
| 95 | /* isnan(v) ? 2147483647 : */ /* NaN */ \ |
| 96 | /* isinf(v) ? 2139095040 : */ /* Infinity */ \ |
| 97 | "ldexp(e + 126, 23) + m);" \ |
| 98 | "}" |
| 99 | #define IMPLEMENT_INTRINSIC_FALLBACK_ASUINT(n) \ |
| 100 | "int" #n " __asuint(float" #n " v) { return __asint(v); }" |
| 101 | #define IMPLEMENT_INTRINSIC_FALLBACK_ASFLOAT(n) \ |
| 102 | "float" #n " __asfloat(int" #n " v) {" \ |
| 103 | "float" #n " m = v % exp2(23);" \ |
| 104 | "float" #n " f = ldexp(m, -23);" \ |
| 105 | "float" #n " e = floor(ldexp(v, -23) % 256);" \ |
| 106 | "return (v > 2147483647 ? -1 : 1) * (" \ |
| 107 | /* e == 0 ? ldexp(f, -126) : */ /* Denormalized */ \ |
| 108 | /* e == 255 ? (m == 0 ? 1.#INF : -1.#IND) : */ /* Infinity and NaN */ \ |
| 109 | "ldexp(1 + f, e - 127));" \ |
| 110 | "}" |
| 111 | |
| 112 | // See https://graphics.stanford.edu/%7Eseander/bithacks.html#CountBitsSetParallel |
| 113 | #define IMPLEMENT_INTRINSIC_FALLBACK_COUNTBITS(n) \ |
| 114 | "uint" #n " __countbits(uint" #n " v) {" \ |
| 115 | "v = v - ((v >> 1) & 0x55555555);" \ |
| 116 | "v = (v & 0x33333333) + ((v >> 2) & 0x33333333);" \ |
| 117 | "v = (v + (v >> 4)) & 0x0F0F0F0F;" \ |
| 118 | "v *= 0x01010101;" \ |
| 119 | "return v >> 24;" \ |
| 120 | "}" |
| 121 | #define IMPLEMENT_INTRINSIC_FALLBACK_COUNTBITS_LOOP(n) \ |
| 122 | "uint" #n " __countbits(uint" #n " v) {" \ |
| 123 | "uint" #n " c = 0;" \ |
| 124 | "while (any(v > 0)) {" \ |
| 125 | "c += v % 2;" \ |
| 126 | "v /= 2;" \ |
| 127 | "}" \ |
| 128 | "return c;" \ |
| 129 | "}" |
| 130 | |
| 131 | // See https://graphics.stanford.edu/%7Eseander/bithacks.html#ReverseParallel |
| 132 | #define IMPLEMENT_INTRINSIC_FALLBACK_REVERSEBITS(n) \ |
| 133 | "uint" #n " __reversebits(uint" #n " v) {" \ |
| 134 | "v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);" \ |
| 135 | "v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);" \ |
| 136 | "v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);" \ |
| 137 | "v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);" \ |
| 138 | "return (v >> 16) | (v << 16);" \ |
| 139 | "}" |
| 140 | #define IMPLEMENT_INTRINSIC_FALLBACK_REVERSEBITS_LOOP(n) \ |
| 141 | "uint" #n " __reversebits(uint" #n " v) {" \ |
| 142 | "uint" #n " r = 0;" \ |
no test coverage detected