d3dx9: Implement D3DXFloat32To16Array and D3DXFloat16To32Array. (try 2)

Misha Koshelev misha680 at gmail.com
Tue Feb 22 16:59:08 CST 2011


2011/2/21 Rico Schüller <kgbricola at web.de>:
> Am 21.02.2011 20:19, schrieb Misha Koshelev:
>>
>> Thanks Rico.
>>
>> Still trying to investigate this further.
>>
>> Perhaps, if you have any more hints as to how you arrived at this
>> magical value, much appreciated.
>
> I got to this value by running the attached test patch applied after yours.
> You probably may
> modify the for loop. I've chosen the increment because of time/usage.
> You may try with 0xff or a lower value instead of 0xfff, but be warned
> running at 1 will take a
> while to see a failed test.
>
> You need a copy of native d3dx9_36.dll renamed to d3dx9_36_2.dll in the
> path. The test
> should show the difference between native and wine's implementation. I
> haven't run the test
> on windows, yet.
>>
>> Namely, at first my hunch was that this value (2.9806e-08 with the
>> following bitwise representation):
>> 0 01100110 00000000000010000000000
>> was simply being truncated to the smallest denormalized value
>> representable by a half precision float:
>> 0        000.00  00.0000.0001    6×10-8 (Smallest denormalized value)
>> but this is clearly not true for other values that are too small (they
>> are returned as 0.0f).
>
> I haven't had the time to investigate this completely, yet. But probably
> there are a couple of values
> produced by the patch which should give a hint to what bits are
> truncated/rounded.
>
> Cheers
> Rico
>

Thank you. I'm pretty stumped. I've gotten a little farther by making
the following changes to the rounding code (handling the special case
of mantissa = 2048 = 2^11 = maximal value; "overflow" from rounding).

    if (tmp - mantissa > 0.5f) mantissa++; /* round to nearest, away
from zero */
    if (mantissa == 2048)
    {
        mantissa = 1024;
        exp++;
    }

This seems to handle all the cases that are, to my understanding,
within the representable range (I may be somewhat incorrect, please
see attached test results, that include output of exp, unrounded
mantissa = tmp, and mantissa). Note, that _most_ of these results fall
in the case of fabs(in) > 65520, so I have commented out this line in
the test version of the converted (see attached patch).

Any hints appreciated.

Thank you
Misha
-------------- next part --------------
diff --git a/dlls/d3dx9_36/tests/math.c b/dlls/d3dx9_36/tests/math.c
index ca1c87d..b418126 100644
--- a/dlls/d3dx9_36/tests/math.c
+++ b/dlls/d3dx9_36/tests/math.c
@@ -2281,6 +2281,37 @@ static void test_D3DXFloat_Array(void)
         ok(relative_error(single, testdata[i].single_out_ver2) < admitted_error,
            "Got %f, expected %f for index %d.\n", single, testdata[i].single_out_ver2, i);
     }
+
+    {
+        HMODULE dll_handle = NULL;
+        D3DXFLOAT16 res, res2;
+        D3DXFLOAT16* (WINAPI * float32to16)(D3DXFLOAT16 *pout, CONST FLOAT *pin, UINT n);
+        union
+        {
+            float f;
+            DWORD d;
+        } x;
+
+        dll_handle = LoadLibraryA("d3dx9_36_2.dll");
+        if (!dll_handle) skip("init: Could not load d3dx9_36_2.dll.\n");
+
+        float32to16 = (void *)GetProcAddress(dll_handle, "D3DXFloat32To16Array");
+        if (!float32to16)
+        {
+            FreeLibrary(dll_handle);
+            skip("init: Could not get function pointer (D3DXFloat32To16Array).\n");
+        }
+
+        for (i = 0; i < 0xfffff000; i += 0xfff)
+        {
+            x.d = i;
+            float32to16(&res, &x.f, 1);
+            D3DXFloat32To16Array(&res2, &x.f, 1);
+
+            ok(res.value == res2.value, "Failed i=%#x f=%f (%#x!=%#x)\n", i, x.f, res.value, res2.value);
+        }
+        FreeLibrary(dll_handle);
+    }
 }
 
 START_TEST(math)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: make_math_ok_results
Type: application/octet-stream
Size: 255297 bytes
Desc: not available
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20110222/a99bbd2c/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch
Type: application/octet-stream
Size: 12254 bytes
Desc: not available
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20110222/a99bbd2c/attachment-0003.obj>


More information about the wine-devel mailing list