|
@@ -1,25 +1,28 @@
|
|
|
-
|
|
|
// Compatibility renames. These are exposed with the "godot_" prefix
|
|
|
// to work around two distinct Adreno bugs:
|
|
|
// 1. Some Adreno devices expose ES310 functions in ES300 shaders.
|
|
|
// Internally, we must use the "godot_" prefix, but user shaders
|
|
|
// will be mapped automatically.
|
|
|
// 2. Adreno 3XX devices have poor implementations of the other packing
|
|
|
-// functions, so we just use our own everywhere to keep it simple.
|
|
|
+// functions, so we just use our own there to keep it simple.
|
|
|
|
|
|
+#ifdef USE_HALF2FLOAT
|
|
|
// Floating point pack/unpack functions are part of the GLSL ES 300 specification used by web and mobile.
|
|
|
+// It appears to be safe to expose these on mobile, but when running through ANGLE this appears to break.
|
|
|
uint float2half(uint f) {
|
|
|
- uint b = f + uint(0x00001000);
|
|
|
- uint e = (b & uint(0x7F800000)) >> 23;
|
|
|
- uint m = b & uint(0x007FFFFF);
|
|
|
- return (b & uint(0x80000000)) >> uint(16) | uint(e > uint(112)) * ((((e - uint(112)) << uint(10)) & uint(0x7C00)) | m >> uint(13)) | (uint(e < uint(113)) & uint(e > uint(101))) * ((((uint(0x007FF000) + m) >> (uint(125) - e)) + uint(1)) >> uint(1)) | uint(e > uint(143)) * uint(0x7FFF);
|
|
|
+ uint e = f & uint(0x7f800000);
|
|
|
+ if (e <= uint(0x38000000)) {
|
|
|
+ return uint(0);
|
|
|
+ } else {
|
|
|
+ return ((f >> uint(16)) & uint(0x8000)) |
|
|
|
+ (((e - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) |
|
|
|
+ ((f >> uint(13)) & uint(0x03ff));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
uint half2float(uint h) {
|
|
|
- uint e = (h & uint(0x7C00)) >> uint(10);
|
|
|
- uint m = (h & uint(0x03FF)) << uint(13);
|
|
|
- uint v = m >> uint(23);
|
|
|
- return (h & uint(0x8000)) << uint(16) | uint(e != uint(0)) * ((e + uint(112)) << uint(23) | m) | (uint(e == uint(0)) & uint(m != uint(0))) * ((v - uint(37)) << uint(23) | ((m << (uint(150) - v)) & uint(0x007FE000)));
|
|
|
+ uint h_e = h & uint(0x7c00);
|
|
|
+ return ((h & uint(0x8000)) << uint(16)) | uint((h_e >> uint(10)) != uint(0)) * (((h_e + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13)));
|
|
|
}
|
|
|
|
|
|
uint godot_packHalf2x16(vec2 v) {
|
|
@@ -50,6 +53,17 @@ vec2 godot_unpackSnorm2x16(uint p) {
|
|
|
return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0));
|
|
|
}
|
|
|
|
|
|
+#define packHalf2x16 godot_packHalf2x16
|
|
|
+#define unpackHalf2x16 godot_unpackHalf2x16
|
|
|
+#define packUnorm2x16 godot_packUnorm2x16
|
|
|
+#define unpackUnorm2x16 godot_unpackUnorm2x16
|
|
|
+#define packSnorm2x16 godot_packSnorm2x16
|
|
|
+#define unpackSnorm2x16 godot_unpackSnorm2x16
|
|
|
+
|
|
|
+#endif // USE_HALF2FLOAT
|
|
|
+
|
|
|
+// Always expose these as they are ES310 functions and not available in ES300 or GLSL 330.
|
|
|
+
|
|
|
uint godot_packUnorm4x8(vec4 v) {
|
|
|
uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0));
|
|
|
return uv.x | (uv.y << uint(8)) | (uv.z << uint(16)) | (uv.w << uint(24));
|
|
@@ -73,9 +87,3 @@ vec4 godot_unpackSnorm4x8(uint p) {
|
|
|
#define unpackUnorm4x8 godot_unpackUnorm4x8
|
|
|
#define packSnorm4x8 godot_packSnorm4x8
|
|
|
#define unpackSnorm4x8 godot_unpackSnorm4x8
|
|
|
-#define packHalf2x16 godot_packHalf2x16
|
|
|
-#define unpackHalf2x16 godot_unpackHalf2x16
|
|
|
-#define packUnorm2x16 godot_packUnorm2x16
|
|
|
-#define unpackUnorm2x16 godot_unpackUnorm2x16
|
|
|
-#define packSnorm2x16 godot_packSnorm2x16
|
|
|
-#define unpackSnorm2x16 godot_unpackSnorm2x16
|