From: Paul Gofman pgofman@codeweavers.com
--- dlls/d2d1/tests/d2d1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index f971d6dfe7d..1cded691d6c 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -15855,7 +15855,7 @@ static void test_no_target(BOOL d3d11)
START_TEST(d2d1) { - HMODULE d2d1_dll = GetModuleHandleA("d2d1.dll"); + HMODULE d2d1_dll = LoadLibraryA("d2d1.dll"); unsigned int argc, i; char **argv;
From: Paul Gofman pgofman@codeweavers.com
--- dlls/d2d1/d2d1.spec | 1 + dlls/d2d1/factory.c | 21 +++++++++++++++ dlls/d2d1/tests/d2d1.c | 61 ++++++++++++++++++++++++++++++++++++++++++ include/d2d1_1.idl | 1 + 4 files changed, 84 insertions(+)
diff --git a/dlls/d2d1/d2d1.spec b/dlls/d2d1/d2d1.spec index 3fa85a93bae..b44d7114044 100644 --- a/dlls/d2d1/d2d1.spec +++ b/dlls/d2d1/d2d1.spec @@ -9,3 +9,4 @@ @ stdcall D2D1SinCos(float ptr ptr) @ stdcall D2D1Tan(float) @ stdcall D2D1Vec3Length(float float float) +@ stdcall D2D1ComputeMaximumScaleFactor(ptr) diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 1294d8c8fa3..0261c78f783 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -1511,6 +1511,27 @@ float WINAPI D2D1Vec3Length(float x, float y, float z) return sqrtf(x * x + y * y + z * z); }
+float WINAPI D2D1ComputeMaximumScaleFactor(const D2D1_MATRIX_3X2_F *mat) +{ + const float (*m)[2] = mat->m; + float a1, a2, c, e; + + TRACE("mat %p stub.\n", mat); + + /* 2x2 matrix, _31 and _32 are ignored. */ + a1 = m[0][0] * m[0][0] + m[1][0] * m[1][0]; + a2 = m[0][1] * m[0][1] + m[1][1] * m[1][1]; + c = m[0][0] * m[0][1] + m[1][0] * m[1][1]; + + /* Maximum scale factor equals to the maximum of the singular values s1, s2 of the matrix M + * s_i^2 = e_i where e_i (e1, e2) are eugenvalues of (transpose(M) * M) + * e1 + e2 = trace(transpose(M) * M) = a1 + a2 + * e1 * e2 = det(transpose(M) * M) = a1 * a2 - c ^ 2. */ + + e = a1 + a2 + sqrtf((a1 - a2) * (a1 - a2) + 4 * c * c); + return sqrtf(0.5f * e); +} + /* See IEC 61966-2-1:1999; also described in the EXT_texture_sRGB OpenGL * extension, among others. */ static float srgb_transfer_function(float x) diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 1cded691d6c..d3c37c1a879 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -297,6 +297,7 @@ static HRESULT (WINAPI *pD2D1CreateDevice)(IDXGIDevice *dxgi_device, static void (WINAPI *pD2D1SinCos)(float angle, float *s, float *c); static float (WINAPI *pD2D1Tan)(float angle); static float (WINAPI *pD2D1Vec3Length)(float x, float y, float z); +static float (WINAPI *pD2D1ComputeMaximumScaleFactor)(const D2D1_MATRIX_3X2_F *mat); static D2D1_COLOR_F (WINAPI *pD2D1ConvertColorSpace)(D2D1_COLOR_SPACE src_colour_space, D2D1_COLOR_SPACE dst_colour_space, const D2D1_COLOR_F *colour);
@@ -10689,6 +10690,52 @@ static void test_math(BOOL d3d11) {1.0f, 2.0f, 3.0f, 3.74165750f}, };
+ static const struct + { + D2D1_MATRIX_3X2_F mat; + float res; + } + scale_factor_tests[] = + { + { + .mat = {.m = + {{0.0f, 0.0f}, + {0.0f, 0.0f}, + {0.0f, 0.0f}, + }}, + 0.0f, + }, + { + .mat = {.m = + {{-3.0f, 0.0f}, + { 0.0f, 2.0f}, + { 2.0f, 1.0f}, + }}, + 3.0f, + }, + { + .mat = {.m = + {{-3.0f, 1.0f}, + { 2.0f, 2.0f}, + }}, + 3.62258267f, + }, + { + .mat = {.m = + {{1.0f, -1.0f}, + {1.0f, 1.0f}, + }}, + 1.41421354f, + }, + { + .mat = {.m = + {{0.0f, 1.0f}, + {2.0f, 0.0f}, + }}, + 2.0f, + }, + }; + if (!pD2D1SinCos || !pD2D1Tan || !pD2D1Vec3Length) { win_skip("D2D1SinCos/D2D1Tan/D2D1Vec3Length not available, skipping test.\n"); @@ -10717,6 +10764,19 @@ static void test_math(BOOL d3d11) ok(compare_float(l, l_data[i].l, 0), "Test %u: Got unexpected length %.8e, expected %.8e.\n", i, l, l_data[i].l); } + + if (!pD2D1ComputeMaximumScaleFactor) + { + win_skip(" D2D1ComputeMaximumScaleFactor not available, skipping test.\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(scale_factor_tests); ++i) + { + s = pD2D1ComputeMaximumScaleFactor(&scale_factor_tests[i].mat); + ok(compare_float(s, scale_factor_tests[i].res, 1), + "Test %u: Got unexpected factor %.8e, expected %.8e.\n", i, s, scale_factor_tests[i].res); + } }
static void test_colour_space(BOOL d3d11) @@ -15864,6 +15924,7 @@ START_TEST(d2d1) pD2D1Tan = (void *)GetProcAddress(d2d1_dll, "D2D1Tan"); pD2D1Vec3Length = (void *)GetProcAddress(d2d1_dll, "D2D1Vec3Length"); pD2D1ConvertColorSpace = (void *)GetProcAddress(d2d1_dll, "D2D1ConvertColorSpace"); + pD2D1ComputeMaximumScaleFactor = (void *)GetProcAddress(d2d1_dll, "D2D1ComputeMaximumScaleFactor");
use_mt = !getenv("WINETEST_NO_MT_D3D"); /* Some host drivers (MacOS, Mesa radeonsi) never unmap memory even when diff --git a/include/d2d1_1.idl b/include/d2d1_1.idl index 5560f24a38e..8e3cbb8a656 100644 --- a/include/d2d1_1.idl +++ b/include/d2d1_1.idl @@ -979,5 +979,6 @@ interface ID2D1Multithread : IUnknown [local] void __stdcall D2D1SinCos(float angle, float *s, float *c); [local] float __stdcall D2D1Tan(float angle); [local] float __stdcall D2D1Vec3Length(float x, float y, float z); +[local] float __stdcall D2D1ComputeMaximumScaleFactor(const D2D1_MATRIX_3X2_F *mat); [local] D2D1_COLOR_F __stdcall D2D1ConvertColorSpace(D2D1_COLOR_SPACE src_colour_space, D2D1_COLOR_SPACE dst_colour_space, const D2D1_COLOR_F *colour);
Asteroids game hits the auto-stub at start. However, this function is by far not enough to make that work really, it is using much more of unimplemented bits.
The first patch fixes the present math tests. Since no function is imported from d2d1.dll it is not getting loaded at the process during test process load and GetModuleHandleA("d2d1.dll") always returns NULL.
Nikolay Sivov (@nsivov) commented about dlls/d2d1/factory.c:
return sqrtf(x * x + y * y + z * z);
}
+float WINAPI D2D1ComputeMaximumScaleFactor(const D2D1_MATRIX_3X2_F *mat) +{
- const float (*m)[2] = mat->m;
- float a1, a2, c, e;
- TRACE("mat %p stub.\n", mat);
Not a stub.
Nikolay Sivov (@nsivov) commented about dlls/d2d1/factory.c:
return sqrtf(x * x + y * y + z * z);
}
+float WINAPI D2D1ComputeMaximumScaleFactor(const D2D1_MATRIX_3X2_F *mat)
A few cosmetic things. Please move this after D2D1InvertMatrix() so that all matrix functions are in the same place. Then for consistency, existing functions use "matrix" for argument name, let's do the same.
Nikolay Sivov (@nsivov) commented about dlls/d2d1/factory.c:
- float a1, a2, c, e;
- TRACE("mat %p stub.\n", mat);
- /* 2x2 matrix, _31 and _32 are ignored. */
- a1 = m[0][0] * m[0][0] + m[1][0] * m[1][0];
- a2 = m[0][1] * m[0][1] + m[1][1] * m[1][1];
- c = m[0][0] * m[0][1] + m[1][0] * m[1][1];
- /* Maximum scale factor equals to the maximum of the singular values s1, s2 of the matrix M
- s_i^2 = e_i where e_i (e1, e2) are eugenvalues of (transpose(M) * M)
- e1 + e2 = trace(transpose(M) * M) = a1 + a2
- e1 * e2 = det(transpose(M) * M) = a1 * a2 - c ^ 2. */
- e = a1 + a2 + sqrtf((a1 - a2) * (a1 - a2) + 4 * c * c);
- return sqrtf(0.5f * e);
If there is an online page for this algebra, that matches this specific function, please link in a MR comment so it could be referred to later.
Nikolay Sivov (@nsivov) commented about include/d2d1_1.idl:
[local] void __stdcall D2D1SinCos(float angle, float *s, float *c); [local] float __stdcall D2D1Tan(float angle); [local] float __stdcall D2D1Vec3Length(float x, float y, float z); +[local] float __stdcall D2D1ComputeMaximumScaleFactor(const D2D1_MATRIX_3X2_F *mat);
In SDK 10.0.26100.0 this prototype is in d2d1_2.h.