Wine-devel
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
May 2020
- 79 participants
- 626 discussions
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ws2_32/tests/sock.c | 431 +++++++++++----------------------------
1 file changed, 115 insertions(+), 316 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index cd9a13937c..d9ceca98cc 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -3082,334 +3082,136 @@ static void test_WSAEnumNetworkEvents(void)
}
}
-static void test_WSAAddressToStringA(void)
+static void test_WSAAddressToString(void)
{
- SOCKET v6 = INVALID_SOCKET;
- INT ret;
- DWORD len;
- int GLE;
+ static struct
+ {
+ ULONG address;
+ USHORT port;
+ char output[32];
+ }
+ ipv4_tests[] =
+ {
+ { 0, 0, "0.0.0.0" },
+ { 0xffffffff, 0, "255.255.255.255" },
+ { 0, 0xffff, "0.0.0.0:65535" },
+ { 0xffffffff, 0xffff, "255.255.255.255:65535" },
+ };
+ static struct
+ {
+ USHORT address[8];
+ ULONG scope;
+ USHORT port;
+ char output[64];
+ }
+ ipv6_tests[] =
+ {
+ { { 0, 0, 0, 0, 0, 0, 0, 0x100 }, 0, 0, "::1" },
+ { { 0xab20, 0, 0, 0, 0, 0, 0, 0x100 }, 0, 0, "20ab::1" },
+ { { 0xab20, 0, 0, 0, 0, 0, 0, 0x120 }, 0, 0xfa81, "[20ab::2001]:33274" },
+ { { 0xab20, 0, 0, 0, 0, 0, 0, 0x120 }, 0x1234, 0xfa81, "[20ab::2001%4660]:33274" },
+ { { 0xab20, 0, 0, 0, 0, 0, 0, 0x120 }, 0x1234, 0, "20ab::2001%4660" },
+ };
SOCKADDR_IN sockaddr;
- CHAR address[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
-
- CHAR expect1[] = "0.0.0.0";
- CHAR expect2[] = "255.255.255.255";
- CHAR expect3[] = "0.0.0.0:65535";
- CHAR expect4[] = "255.255.255.255:65535";
-
SOCKADDR_IN6 sockaddr6;
- CHAR address6[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
-
- CHAR addr6_1[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
- CHAR addr6_2[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
- CHAR addr6_3[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01};
-
- CHAR expect6_1[] = "::1";
- CHAR expect6_2[] = "20ab::1";
- CHAR expect6_3[] = "[20ab::2001]:33274";
- CHAR expect6_3_2[] = "[20ab::2001%4660]:33274";
- CHAR expect6_3_3[] = "20ab::2001%4660";
-
- len = 0;
-
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = 0;
- sockaddr.sin_addr.s_addr = 0;
-
- ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
- GLE = WSAGetLastError();
- ok( (ret == SOCKET_ERROR && GLE == WSAEFAULT) || (ret == 0),
- "WSAAddressToStringA() failed unexpectedly: WSAGetLastError()=%d, ret=%d\n",
- GLE, ret );
-
- len = sizeof(address);
-
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = 0;
- sockaddr.sin_addr.s_addr = 0;
-
- ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
- ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
-
- ok( !strcmp( address, expect1 ), "Expected: %s, got: %s\n", expect1, address );
- ok( len == sizeof( expect1 ), "Got size %d\n", len);
-
- len = sizeof(address);
-
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = 0;
- sockaddr.sin_addr.s_addr = 0xffffffff;
-
- ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
- ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
-
- ok( !strcmp( address, expect2 ), "Expected: %s, got: %s\n", expect2, address );
-
- len = sizeof(address);
-
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = 0xffff;
- sockaddr.sin_addr.s_addr = 0;
-
- ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
- ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
-
- ok( !strcmp( address, expect3 ), "Expected: %s, got: %s\n", expect3, address );
-
- len = sizeof(address);
-
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = 0xffff;
- sockaddr.sin_addr.s_addr = 0xffffffff;
-
- ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
- ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
-
- ok( !strcmp( address, expect4 ), "Expected: %s, got: %s\n", expect4, address );
- ok( len == sizeof( expect4 ), "Got size %d\n", len);
-
- /*check to see it IPv6 is available */
- v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
- if (v6 == INVALID_SOCKET) {
- skip("Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n",
- WSAGetLastError(), WSAEAFNOSUPPORT);
- goto end;
- }
- /* Test a short IPv6 address */
- len = sizeof(address6);
-
- sockaddr6.sin6_family = AF_INET6;
- sockaddr6.sin6_port = 0x0000;
- sockaddr6.sin6_scope_id = 0;
- memcpy (sockaddr6.sin6_addr.s6_addr, addr6_1, sizeof(addr6_1));
-
- ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
- ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
- ok( !strcmp( address6, expect6_1 ), "Expected: %s, got: %s\n", expect6_1, address6 );
- ok( len == sizeof(expect6_1), "Got size %d\n", len);
-
- /* Test a longer IPv6 address */
- len = sizeof(address6);
-
- sockaddr6.sin6_family = AF_INET6;
- sockaddr6.sin6_port = 0x0000;
- sockaddr6.sin6_scope_id = 0;
- memcpy (sockaddr6.sin6_addr.s6_addr, addr6_2, sizeof(addr6_2));
-
- ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
- ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
- ok( !strcmp( address6, expect6_2 ), "Expected: %s, got: %s\n", expect6_2, address6 );
- ok( len == sizeof(expect6_2), "Got size %d\n", len);
-
- /* Test IPv6 address and port number */
- len = sizeof(address6);
-
- sockaddr6.sin6_family = AF_INET6;
- sockaddr6.sin6_port = 0xfa81;
- sockaddr6.sin6_scope_id = 0;
- memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
-
- ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
- ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
- ok( !strcmp( address6, expect6_3 ), "Expected: %s, got: %s\n", expect6_3, address6 );
- ok( len == sizeof(expect6_3), "Got size %d\n", len );
-
- /* Test IPv6 address, port number and scope_id */
- len = sizeof(address6);
-
- sockaddr6.sin6_family = AF_INET6;
- sockaddr6.sin6_port = 0xfa81;
- sockaddr6.sin6_scope_id = 0x1234;
- memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
-
- ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
- ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
- ok( !strcmp( address6, expect6_3_2 ), "Expected: %s, got: %s\n", expect6_3_2, address6 );
- ok( len == sizeof(expect6_3_2), "Got size %d\n", len );
-
- /* Test IPv6 address and scope_id */
- len = sizeof(address6);
-
- sockaddr6.sin6_family = AF_INET6;
- sockaddr6.sin6_port = 0x0000;
- sockaddr6.sin6_scope_id = 0x1234;
- memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
-
- ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
- ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() );
- ok( !strcmp( address6, expect6_3_3 ), "Expected: %s, got: %s\n", expect6_3_3, address6 );
- ok( len == sizeof(expect6_3_3), "Got size %d\n", len );
-
-end:
- if (v6 != INVALID_SOCKET)
- closesocket(v6);
-}
-
-static void test_WSAAddressToStringW(void)
-{
- SOCKET v6 = INVALID_SOCKET;
+ char output[64];
+ WCHAR outputW[64], expected_outputW[64];
+ SOCKET v6;
INT ret;
DWORD len;
- int GLE;
- SOCKADDR_IN sockaddr;
- WCHAR address[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
-
- WCHAR expect1[] = { '0','.','0','.','0','.','0', 0 };
- WCHAR expect2[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', 0 };
- WCHAR expect3[] = { '0','.','0','.','0','.','0', ':', '6', '5', '5', '3', '5', 0 };
- WCHAR expect4[] = { '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5', ':',
- '6', '5', '5', '3', '5', 0 };
-
- SOCKADDR_IN6 sockaddr6;
- WCHAR address6[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
-
- CHAR addr6_1[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
- CHAR addr6_2[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
- CHAR addr6_3[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01};
-
- WCHAR expect6_1[] = {':',':','1',0};
- WCHAR expect6_2[] = {'2','0','a','b',':',':','1',0};
- WCHAR expect6_3[] = {'[','2','0','a','b',':',':','2','0','0','1',']',':','3','3','2','7','4',0};
- WCHAR expect6_3_2[] = {'[','2','0','a','b',':',':','2','0','0','1','%','4','6','6','0',']',':','3','3','2','7','4',0};
- WCHAR expect6_3_3[] = {'2','0','a','b',':',':','2','0','0','1','%','6','5','5','3','4',0};
+ int i, j;
len = 0;
-
sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = 0;
sockaddr.sin_addr.s_addr = 0;
-
- ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
- GLE = WSAGetLastError();
- ok( (ret == SOCKET_ERROR && GLE == WSAEFAULT) || (ret == 0),
- "WSAAddressToStringW() failed unexpectedly: WSAGetLastError()=%d, ret=%d\n",
- GLE, ret );
-
- len = sizeof(address);
-
- sockaddr.sin_family = AF_INET;
sockaddr.sin_port = 0;
- sockaddr.sin_addr.s_addr = 0;
+ ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, output, &len );
+ ok( ret == SOCKET_ERROR, "WSAAddressToStringA() returned %d, expected SOCKET_ERROR\n", ret );
+ ok( WSAGetLastError() == WSAEFAULT, "WSAAddressToStringA() gave error %d, expected WSAEFAULT\n", WSAGetLastError() );
+ ok( len == 8, "WSAAddressToStringA() gave length %d, expected 8\n", len );
- ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
- ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
-
- ok( !lstrcmpW( address, expect1 ), "Expected different address string\n" );
- ok( len == ARRAY_SIZE(expect1), "Got size %d\n", len);
-
- len = sizeof(address);
-
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = 0;
- sockaddr.sin_addr.s_addr = 0xffffffff;
-
- ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
- ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
-
- ok( !lstrcmpW( address, expect2 ), "Expected different address string\n" );
-
- len = sizeof(address);
-
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = 0xffff;
- sockaddr.sin_addr.s_addr = 0;
-
- ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
- ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
-
- ok( !lstrcmpW( address, expect3 ), "Expected different address string\n" );
-
- len = sizeof(address);
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < ARRAY_SIZE(ipv4_tests); j++)
+ {
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_addr.s_addr = ipv4_tests[j].address;
+ sockaddr.sin_port = ipv4_tests[j].port;
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = 0xffff;
- sockaddr.sin_addr.s_addr = 0xffffffff;
+ if (i == 0)
+ {
+ len = sizeof(output);
+ memset(output, 0, len);
+ ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, output, &len );
+ ok( !ret, "ipv4_tests[%d] failed unexpectedly: %d\n", j, WSAGetLastError() );
+ ok( lstrcmpA( output, ipv4_tests[j].output ) == 0,
+ "ipv4_tests[%d]: got address %s, expected %s\n",
+ j, wine_dbgstr_a(output), wine_dbgstr_a(ipv4_tests[j].output) );
+ ok( len == lstrlenA(ipv4_tests[j].output) + 1,
+ "ipv4_tests[%d]: got length %d, expected %d\n",
+ j, len, lstrlenA(ipv4_tests[j].output) + 1 );
+ }
+ else
+ {
+ len = sizeof(outputW);
+ memset(outputW, 0, len);
+ ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, outputW, &len );
+ MultiByteToWideChar( CP_ACP, 0, ipv4_tests[j].output, -1,
+ expected_outputW, ARRAY_SIZE(expected_outputW) );
+ ok( !ret, "ipv4_tests[%d] failed unexpectedly: %d\n", j, WSAGetLastError() );
+ ok( lstrcmpW( outputW, expected_outputW ) == 0,
+ "ipv4_tests[%d]: got address %s, expected %s\n",
+ j, wine_dbgstr_w(outputW), wine_dbgstr_w(expected_outputW) );
+ ok( len == lstrlenW(expected_outputW) + 1,
+ "ipv4_tests[%d]: got length %d, expected %d\n",
+ j, len, lstrlenW(expected_outputW) + 1 );
+ }
+ }
- ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr, sizeof(sockaddr), NULL, address, &len );
- ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
+ /* check to see if IPv6 is available */
+ v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
+ if (v6 == INVALID_SOCKET) {
+ skip("Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n",
+ WSAGetLastError(), WSAEAFNOSUPPORT);
+ continue;
+ }
+ closesocket(v6);
- ok( !lstrcmpW( address, expect4 ), "Expected different address string\n" );
- ok( len == ARRAY_SIZE(expect4), "Got %d\n", len);
+ for (j = 0; j < ARRAY_SIZE(ipv6_tests); j++)
+ {
+ sockaddr6.sin6_family = AF_INET6;
+ sockaddr6.sin6_scope_id = ipv6_tests[j].scope;
+ sockaddr6.sin6_port = ipv6_tests[j].port;
+ memcpy( sockaddr6.sin6_addr.s6_addr, ipv6_tests[j].address, sizeof(ipv6_tests[j].address) );
- /*check to see it IPv6 is available */
- v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
- if (v6 == INVALID_SOCKET) {
- skip("Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n",
- WSAGetLastError(), WSAEAFNOSUPPORT);
- goto end;
+ if (i == 0)
+ {
+ len = sizeof(output);
+ ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, output, &len );
+ ok( !ret, "ipv6_tests[%d] failed unexpectedly: %d\n", j, WSAGetLastError() );
+ ok( lstrcmpA( output, ipv6_tests[j].output ) == 0,
+ "ipv6_tests[%d]: gave address %s, expected %s\n",
+ j, wine_dbgstr_a(output), wine_dbgstr_a(ipv6_tests[j].output) );
+ ok( len == lstrlenA(ipv6_tests[j].output) + 1,
+ "ipv6_tests[%d]: got length %d, expected %d\n",
+ j, len, lstrlenA(ipv6_tests[j].output) + 1 );
+ }
+ else
+ {
+ len = sizeof(outputW);
+ ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, outputW, &len );
+ MultiByteToWideChar( CP_ACP, 0, ipv6_tests[j].output, -1,
+ expected_outputW, ARRAY_SIZE(expected_outputW) );
+ ok( !ret, "ipv6_tests[%d] failed unexpectedly: %d\n", j, WSAGetLastError() );
+ ok( lstrcmpW( outputW, expected_outputW ) == 0,
+ "ipv6_tests[%d]: got address %s, expected %s\n",
+ j, wine_dbgstr_w(outputW), wine_dbgstr_w(expected_outputW) );
+ ok( len == lstrlenW(expected_outputW) + 1,
+ "ipv6_tests[%d]: got length %d, expected %d\n",
+ j, len, lstrlenW(expected_outputW) + 1 );
+ }
+ }
}
-
- /* Test a short IPv6 address */
- len = ARRAY_SIZE(address6);
-
- sockaddr6.sin6_family = AF_INET6;
- sockaddr6.sin6_port = 0x0000;
- sockaddr6.sin6_scope_id = 0;
- memcpy (sockaddr6.sin6_addr.s6_addr, addr6_1, sizeof(addr6_1));
-
- ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
- ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
- ok( !lstrcmpW( address6, expect6_1 ), "Wrong string returned\n" );
- ok( len == ARRAY_SIZE(expect6_1), "Got %d\n", len);
-
- /* Test a longer IPv6 address */
- len = ARRAY_SIZE(address6);
-
- sockaddr6.sin6_family = AF_INET6;
- sockaddr6.sin6_port = 0x0000;
- sockaddr6.sin6_scope_id = 0;
- memcpy (sockaddr6.sin6_addr.s6_addr, addr6_2, sizeof(addr6_2));
-
- ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
- ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
-
- ok( !lstrcmpW( address6, expect6_2 ), "Wrong string returned\n" );
- ok( len == ARRAY_SIZE(expect6_2), "Got %d\n", len);
-
- /* Test IPv6 address and port number */
- len = ARRAY_SIZE(address6);
-
- sockaddr6.sin6_family = AF_INET6;
- sockaddr6.sin6_port = 0xfa81;
- sockaddr6.sin6_scope_id = 0;
- memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
-
- ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
- ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
- ok( !lstrcmpW( address6, expect6_3 ),
- "Expected: %s, got: %s\n", wine_dbgstr_w(expect6_3), wine_dbgstr_w(address6) );
- ok( len == ARRAY_SIZE(expect6_3), "Got %d\n", len );
-
- /* Test IPv6 address, port number and scope_id */
- len = ARRAY_SIZE(address6);
-
- sockaddr6.sin6_family = AF_INET6;
- sockaddr6.sin6_port = 0xfa81;
- sockaddr6.sin6_scope_id = 0x1234;
- memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
-
- ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
- ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
- ok( !lstrcmpW( address6, expect6_3_2 ),
- "Expected: %s, got: %s\n", wine_dbgstr_w(expect6_3_2), wine_dbgstr_w(address6) );
- ok( len == ARRAY_SIZE(expect6_3_2), "Got %d\n", len );
-
- /* Test IPv6 address and scope_id */
- len = ARRAY_SIZE(address6);
-
- sockaddr6.sin6_family = AF_INET6;
- sockaddr6.sin6_port = 0x0000;
- sockaddr6.sin6_scope_id = 0xfffe;
- memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3));
-
- ret = WSAAddressToStringW( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len );
- ok( !ret, "WSAAddressToStringW() failed unexpectedly: %d\n", WSAGetLastError() );
- ok( !lstrcmpW( address6, expect6_3_3 ),
- "Expected: %s, got: %s\n", wine_dbgstr_w(expect6_3_3), wine_dbgstr_w(address6) );
- ok( len == ARRAY_SIZE(expect6_3_3), "Got %d\n", len );
-
-end:
- if (v6 != INVALID_SOCKET)
- closesocket(v6);
}
static void test_WSAStringToAddress(void)
@@ -11579,10 +11381,7 @@ START_TEST( sock )
test_WSASocket();
test_WSADuplicateSocket();
test_WSAEnumNetworkEvents();
-
- test_WSAAddressToStringA();
- test_WSAAddressToStringW();
-
+ test_WSAAddressToString();
test_WSAStringToAddress();
test_errors();
--
2.26.2
2
1
26 May '20
They seem to belong there.
As suggested by Alexandre Julliard.
Signed-off-by: Arkadiusz Hiler <arek(a)hiler.eu>
---
dlls/user32/input.c | 69 +++++++++++++++++++++++++++++++++++++++++++++
dlls/user32/misc.c | 69 ---------------------------------------------
2 files changed, 69 insertions(+), 69 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 2f8648f177..1dd43a36a1 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -45,6 +45,7 @@
#include "winerror.h"
#include "win.h"
#include "user_private.h"
+#include "dbt.h"
#include "wine/server.h"
#include "wine/debug.h"
#include "wine/unicode.h"
@@ -1298,3 +1299,71 @@ BOOL WINAPI EnableMouseInPointer(BOOL enable)
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
+
+static DWORD CALLBACK devnotify_window_callback(HANDLE handle, DWORD flags, DEV_BROADCAST_HDR *header)
+{
+ SendMessageTimeoutW(handle, WM_DEVICECHANGE, flags, (LPARAM)header, SMTO_ABORTIFHUNG, 2000, NULL);
+ return 0;
+}
+
+static DWORD CALLBACK devnotify_service_callback(HANDLE handle, DWORD flags, DEV_BROADCAST_HDR *header)
+{
+ FIXME("Support for service handles is not yet implemented!\n");
+ return 0;
+}
+
+struct device_notification_details
+{
+ DWORD (CALLBACK *cb)(HANDLE handle, DWORD flags, DEV_BROADCAST_HDR *header);
+ HANDLE handle;
+};
+
+extern HDEVNOTIFY WINAPI I_ScRegisterDeviceNotification( struct device_notification_details *details,
+ void *filter, DWORD flags );
+extern BOOL WINAPI I_ScUnregisterDeviceNotification( HDEVNOTIFY handle );
+
+/***********************************************************************
+ * RegisterDeviceNotificationA (USER32.@)
+ *
+ * See RegisterDeviceNotificationW.
+ */
+HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hRecipient, LPVOID pNotificationFilter, DWORD dwFlags)
+{
+ TRACE("(hwnd=%p, filter=%p,flags=0x%08x)\n",
+ hRecipient,pNotificationFilter,dwFlags);
+ if (pNotificationFilter)
+ FIXME("The notification filter will requires an A->W when filter support is implemented\n");
+ return RegisterDeviceNotificationW(hRecipient, pNotificationFilter, dwFlags);
+}
+
+/***********************************************************************
+ * RegisterDeviceNotificationW (USER32.@)
+ */
+HDEVNOTIFY WINAPI RegisterDeviceNotificationW( HANDLE handle, void *filter, DWORD flags )
+{
+ struct device_notification_details details;
+
+ TRACE("handle %p, filter %p, flags %#x\n", handle, filter, flags);
+
+ if (flags & ~(DEVICE_NOTIFY_SERVICE_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES))
+ FIXME("unhandled flags %#x\n", flags);
+
+ details.handle = handle;
+
+ if (flags & DEVICE_NOTIFY_SERVICE_HANDLE)
+ details.cb = devnotify_service_callback;
+ else
+ details.cb = devnotify_window_callback;
+
+ return I_ScRegisterDeviceNotification( &details, filter, 0 );
+}
+
+/***********************************************************************
+ * UnregisterDeviceNotification (USER32.@)
+ */
+BOOL WINAPI UnregisterDeviceNotification( HDEVNOTIFY handle )
+{
+ TRACE("%p\n", handle);
+
+ return I_ScUnregisterDeviceNotification( handle );
+}
diff --git a/dlls/user32/misc.c b/dlls/user32/misc.c
index 41909f9071..59b85baa58 100644
--- a/dlls/user32/misc.c
+++ b/dlls/user32/misc.c
@@ -31,7 +31,6 @@
#include "wingdi.h"
#include "controls.h"
#include "user_private.h"
-#include "dbt.h"
#include "wine/unicode.h"
#include "wine/debug.h"
@@ -279,74 +278,6 @@ DWORD WINAPI RegisterTasklist (DWORD x)
return TRUE;
}
-static DWORD CALLBACK devnotify_window_callback(HANDLE handle, DWORD flags, DEV_BROADCAST_HDR *header)
-{
- SendMessageTimeoutW(handle, WM_DEVICECHANGE, flags, (LPARAM)header, SMTO_ABORTIFHUNG, 2000, NULL);
- return 0;
-}
-
-static DWORD CALLBACK devnotify_service_callback(HANDLE handle, DWORD flags, DEV_BROADCAST_HDR *header)
-{
- FIXME("Support for service handles is not yet implemented!\n");
- return 0;
-}
-
-struct device_notification_details
-{
- DWORD (CALLBACK *cb)(HANDLE handle, DWORD flags, DEV_BROADCAST_HDR *header);
- HANDLE handle;
-};
-
-extern HDEVNOTIFY WINAPI I_ScRegisterDeviceNotification( struct device_notification_details *details,
- void *filter, DWORD flags );
-extern BOOL WINAPI I_ScUnregisterDeviceNotification( HDEVNOTIFY handle );
-
-/***********************************************************************
- * RegisterDeviceNotificationA (USER32.@)
- *
- * See RegisterDeviceNotificationW.
- */
-HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hRecipient, LPVOID pNotificationFilter, DWORD dwFlags)
-{
- TRACE("(hwnd=%p, filter=%p,flags=0x%08x)\n",
- hRecipient,pNotificationFilter,dwFlags);
- if (pNotificationFilter)
- FIXME("The notification filter will requires an A->W when filter support is implemented\n");
- return RegisterDeviceNotificationW(hRecipient, pNotificationFilter, dwFlags);
-}
-
-/***********************************************************************
- * RegisterDeviceNotificationW (USER32.@)
- */
-HDEVNOTIFY WINAPI RegisterDeviceNotificationW( HANDLE handle, void *filter, DWORD flags )
-{
- struct device_notification_details details;
-
- TRACE("handle %p, filter %p, flags %#x\n", handle, filter, flags);
-
- if (flags & ~(DEVICE_NOTIFY_SERVICE_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES))
- FIXME("unhandled flags %#x\n", flags);
-
- details.handle = handle;
-
- if (flags & DEVICE_NOTIFY_SERVICE_HANDLE)
- details.cb = devnotify_service_callback;
- else
- details.cb = devnotify_window_callback;
-
- return I_ScRegisterDeviceNotification( &details, filter, 0 );
-}
-
-/***********************************************************************
- * UnregisterDeviceNotification (USER32.@)
- */
-BOOL WINAPI UnregisterDeviceNotification( HDEVNOTIFY handle )
-{
- TRACE("%p\n", handle);
-
- return I_ScUnregisterDeviceNotification( handle );
-}
-
/***********************************************************************
* GetAppCompatFlags (USER32.@)
*/
--
2.26.2
2
2
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/bcrypt/bcrypt.spec | 1 +
dlls/bcrypt/bcrypt_main.c | 47 ++++++++++++++++++++++++++
dlls/bcrypt/tests/bcrypt.c | 68 ++++++++++++++++++++++++++++++++++++++
dlls/ncrypt/ncrypt.spec | 2 +-
include/bcrypt.h | 1 +
5 files changed, 118 insertions(+), 1 deletion(-)
diff --git a/dlls/bcrypt/bcrypt.spec b/dlls/bcrypt/bcrypt.spec
index 95bec876b9..90ab7b52fe 100644
--- a/dlls/bcrypt/bcrypt.spec
+++ b/dlls/bcrypt/bcrypt.spec
@@ -8,6 +8,7 @@
@ stdcall BCryptDecrypt(ptr ptr long ptr ptr long ptr long ptr long)
@ stub BCryptDeleteContext
@ stdcall BCryptDeriveKey(ptr wstr ptr ptr long ptr long)
+@ stdcall BCryptDeriveKeyCapi(ptr ptr ptr long long)
@ stdcall BCryptDeriveKeyPBKDF2(ptr ptr long ptr long int64 ptr long long)
@ stdcall BCryptDestroyHash(ptr)
@ stdcall BCryptDestroyKey(ptr)
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 5f0b9f1ca8..6311700880 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -1609,6 +1609,53 @@ NTSTATUS WINAPI BCryptSetProperty( BCRYPT_HANDLE handle, const WCHAR *prop, UCHA
}
}
+#define HMAC_PAD_LEN 64
+NTSTATUS WINAPI BCryptDeriveKeyCapi( BCRYPT_HASH_HANDLE handle, BCRYPT_ALG_HANDLE halg, UCHAR *key, ULONG keylen, ULONG flags )
+{
+ struct hash *hash = handle;
+ UCHAR buf[MAX_HASH_OUTPUT_BYTES * 2];
+ NTSTATUS status;
+ ULONG len;
+
+ TRACE( "%p, %p, %p, %u, %08x\n", handle, halg, key, keylen, flags );
+
+ if (!key || !keylen) return STATUS_INVALID_PARAMETER;
+ if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE;
+ if (keylen > builtin_algorithms[hash->alg_id].hash_length * 2) return STATUS_INVALID_PARAMETER;
+
+ if (halg)
+ {
+ FIXME( "algorithm handle not supported\n" );
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ len = builtin_algorithms[hash->alg_id].hash_length;
+ if ((status = BCryptFinishHash( handle, buf, len, 0 ))) return status;
+
+ if (len < keylen)
+ {
+ UCHAR pad1[HMAC_PAD_LEN], pad2[HMAC_PAD_LEN];
+ ULONG i;
+
+ for (i = 0; i < sizeof(pad1); i++)
+ {
+ pad1[i] = 0x36 ^ (i < len ? buf[i] : 0);
+ pad2[i] = 0x5c ^ (i < len ? buf[i] : 0);
+ }
+
+ if ((status = prepare_hash( hash )) ||
+ (status = BCryptHashData( handle, pad1, sizeof(pad1), 0 )) ||
+ (status = BCryptFinishHash( handle, buf, len, 0 ))) return status;
+
+ if ((status = prepare_hash( hash )) ||
+ (status = BCryptHashData( handle, pad2, sizeof(pad2), 0 )) ||
+ (status = BCryptFinishHash( handle, buf + len, len, 0 ))) return status;
+ }
+
+ memcpy( key, buf, keylen );
+ return STATUS_SUCCESS;
+}
+
static NTSTATUS pbkdf2( BCRYPT_HASH_HANDLE handle, UCHAR *pwd, ULONG pwd_len, UCHAR *salt, ULONG salt_len,
ULONGLONG iterations, ULONG i, UCHAR *dst, ULONG hash_len )
{
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
index f7404057fa..e64e78546d 100644
--- a/dlls/bcrypt/tests/bcrypt.c
+++ b/dlls/bcrypt/tests/bcrypt.c
@@ -32,6 +32,7 @@ static NTSTATUS (WINAPI *pBCryptCreateHash)(BCRYPT_ALG_HANDLE, BCRYPT_HASH_HANDL
ULONG, ULONG);
static NTSTATUS (WINAPI *pBCryptDecrypt)(BCRYPT_KEY_HANDLE, PUCHAR, ULONG, VOID *, PUCHAR, ULONG, PUCHAR, ULONG,
ULONG *, ULONG);
+static NTSTATUS (WINAPI *pBCryptDeriveKeyCapi)(BCRYPT_HASH_HANDLE, BCRYPT_ALG_HANDLE, UCHAR *, ULONG, ULONG);
static NTSTATUS (WINAPI *pBCryptDeriveKeyPBKDF2)(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, PUCHAR, ULONG, ULONGLONG,
PUCHAR, ULONG, ULONG);
static NTSTATUS (WINAPI *pBCryptDestroyHash)(BCRYPT_HASH_HANDLE);
@@ -2356,6 +2357,71 @@ static void test_aes_vector(void)
ok(!ret, "got %08x\n", ret);
}
+static void test_BcryptDeriveKeyCapi(void)
+{
+ static const UCHAR expect[] =
+ {0xda,0x39,0xa3,0xee,0x5e,0x6b,0x4b,0x0d,0x32,0x55,0xbf,0xef,0x95,0x60,0x18,0x90,0xaf,0xd8,0x07,0x09};
+ static const UCHAR expect2[] =
+ {0x9b,0x03,0x17,0x41,0xf4,0x75,0x11,0xac,0xff,0x22,0xee,0x40,0xbb,0xe8,0xf9,0x74,0x17,0x26,0xb6,0xf2,
+ 0xf8,0xc7,0x88,0x02,0x9a,0xdc,0x0d,0xd7,0x83,0x58,0xea,0x65,0x2e,0x8b,0x85,0xc6,0xdb,0xb7,0xed,0x1c};
+ BCRYPT_ALG_HANDLE alg;
+ BCRYPT_HASH_HANDLE hash;
+ UCHAR key[40];
+ NTSTATUS ret;
+
+ ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, NULL, 0);
+ ok(!ret, "got %08x\n", ret);
+
+ ret = pBCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
+ ok(!ret || broken(ret == STATUS_INVALID_PARAMETER) /* win2k8 */, "got %08x\n", ret);
+ if (ret == STATUS_INVALID_PARAMETER)
+ {
+ win_skip( "broken BCryptCreateHash\n" );
+ return;
+ }
+
+ ret = pBCryptDeriveKeyCapi(NULL, NULL, NULL, 0, 0);
+ ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
+
+ ret = pBCryptDeriveKeyCapi(hash, NULL, NULL, 0, 0);
+ ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
+
+ ret = pBCryptDeriveKeyCapi(hash, NULL, key, 0, 0);
+ ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
+
+ ret = pBCryptDeriveKeyCapi(hash, NULL, key, 41, 0);
+ ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
+
+ memset(key, 0, sizeof(key));
+ ret = pBCryptDeriveKeyCapi(hash, NULL, key, 20, 0);
+ ok(!ret, "got %08x\n", ret);
+ ok(!memcmp(key, expect, sizeof(expect) - 1), "wrong key data\n");
+
+ ret = pBCryptDeriveKeyCapi(hash, NULL, key, 20, 0);
+ todo_wine ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
+
+ ret = pBCryptHashData(hash, NULL, 0, 0);
+ todo_wine ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret);
+
+ ret = pBCryptDestroyHash(hash);
+ ok(!ret, "got %08x\n", ret);
+
+ ret = pBCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0);
+ ok(!ret, "got %08x\n", ret);
+
+ ret = pBCryptHashData(hash, (UCHAR *)"test", 4, 0);
+ ok(!ret, "got %08x\n", ret);
+
+ /* padding */
+ memset(key, 0, sizeof(key));
+ ret = pBCryptDeriveKeyCapi(hash, NULL, key, 40, 0);
+ ok(!ret, "got %08x\n", ret);
+ ok(!memcmp(key, expect2, sizeof(expect2) - 1), "wrong key data\n");
+
+ ret = pBCryptCloseAlgorithmProvider(alg, 0);
+ ok(!ret, "got %08x\n", ret);
+}
+
START_TEST(bcrypt)
{
HMODULE module;
@@ -2370,6 +2436,7 @@ START_TEST(bcrypt)
pBCryptCloseAlgorithmProvider = (void *)GetProcAddress(module, "BCryptCloseAlgorithmProvider");
pBCryptCreateHash = (void *)GetProcAddress(module, "BCryptCreateHash");
pBCryptDecrypt = (void *)GetProcAddress(module, "BCryptDecrypt");
+ pBCryptDeriveKeyCapi = (void *)GetProcAddress(module, "BCryptDeriveKeyCapi");
pBCryptDeriveKeyPBKDF2 = (void *)GetProcAddress(module, "BCryptDeriveKeyPBKDF2");
pBCryptDestroyHash = (void *)GetProcAddress(module, "BCryptDestroyHash");
pBCryptDestroyKey = (void *)GetProcAddress(module, "BCryptDestroyKey");
@@ -2418,6 +2485,7 @@ START_TEST(bcrypt)
test_BCryptSignHash();
test_BCryptEnumAlgorithms();
test_aes_vector();
+ test_BcryptDeriveKeyCapi();
FreeLibrary(module);
}
diff --git a/dlls/ncrypt/ncrypt.spec b/dlls/ncrypt/ncrypt.spec
index 3908cbfb91..2b5a4fca42 100644
--- a/dlls/ncrypt/ncrypt.spec
+++ b/dlls/ncrypt/ncrypt.spec
@@ -8,7 +8,7 @@
@ stdcall BCryptDecrypt(ptr ptr long ptr ptr long ptr long ptr long) bcrypt.BCryptDecrypt
@ stub BCryptDeleteContext
@ stdcall BCryptDeriveKey(ptr wstr ptr ptr long ptr long) bcrypt.BCryptDeriveKey
-@ stub BCryptDeriveKeyCapi
+@ stdcall BCryptDeriveKeyCapi(ptr ptr ptr long long) bcrypt.BCryptDeriveKeyCapi
@ stdcall BCryptDeriveKeyPBKDF2(ptr ptr long ptr long int64 ptr long long) bcrypt.BCryptDeriveKeyPBKDF2
@ stdcall BCryptDestroyHash(ptr) bcrypt.BCryptDestroyHash
@ stdcall BCryptDestroyKey(ptr) bcrypt.BCryptDestroyKey
diff --git a/include/bcrypt.h b/include/bcrypt.h
index 3dcab5f75a..62e6074f59 100644
--- a/include/bcrypt.h
+++ b/include/bcrypt.h
@@ -348,6 +348,7 @@ NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE, ULONG);
NTSTATUS WINAPI BCryptCreateHash(BCRYPT_ALG_HANDLE, BCRYPT_HASH_HANDLE *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG);
NTSTATUS WINAPI BCryptDecrypt(BCRYPT_KEY_HANDLE, PUCHAR, ULONG, VOID *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG *, ULONG);
NTSTATUS WINAPI BCryptDeriveKey(BCRYPT_SECRET_HANDLE, LPCWSTR, BCryptBufferDesc*, PUCHAR, ULONG, ULONG *, ULONG);
+NTSTATUS WINAPI BCryptDeriveKeyCapi(BCRYPT_HASH_HANDLE, BCRYPT_ALG_HANDLE, PUCHAR, ULONG, ULONG);
NTSTATUS WINAPI BCryptDeriveKeyPBKDF2(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, PUCHAR, ULONG, ULONGLONG, PUCHAR, ULONG, ULONG);
NTSTATUS WINAPI BCryptDestroyHash(BCRYPT_HASH_HANDLE);
NTSTATUS WINAPI BCryptDestroyKey(BCRYPT_KEY_HANDLE);
--
2.20.1
1
0
[PATCH 5/5] wined3d: Implement timestamp disjoint queries for the Vulkan adapter.
by Henri Verbeet 26 May '20
by Henri Verbeet 26 May '20
26 May '20
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/query.c | 40 +++++++++++++++++++++++++++++++++++++---
1 file changed, 37 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index 3b6f442f4a7..69fc5e7474c 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -1660,12 +1660,21 @@ static const struct wined3d_query_ops wined3d_query_timestamp_vk_ops =
.query_destroy = wined3d_query_vk_destroy,
};
+static const struct wined3d_query_ops wined3d_query_timestamp_disjoint_vk_ops =
+{
+ .query_poll = wined3d_timestamp_disjoint_query_ops_poll,
+ .query_issue = wined3d_timestamp_disjoint_query_ops_issue,
+ .query_destroy = wined3d_query_vk_destroy,
+};
+
HRESULT wined3d_query_vk_create(struct wined3d_device *device, enum wined3d_query_type type,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
{
+ struct wined3d_query_data_timestamp_disjoint *disjoint_data;
const struct wined3d_query_ops *ops = &wined3d_query_vk_ops;
struct wined3d_query_vk *query_vk;
unsigned int data_size;
+ void *data;
TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
device, type, parent, parent_ops, query);
@@ -1686,6 +1695,16 @@ HRESULT wined3d_query_vk_create(struct wined3d_device *device, enum wined3d_quer
data_size = sizeof(uint64_t);
break;
+ case WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT:
+ if (!wined3d_device_vk(device)->timestamp_bits)
+ {
+ WARN("Timestamp queries not supported.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+ ops = &wined3d_query_timestamp_disjoint_vk_ops;
+ data_size = sizeof(struct wined3d_query_data_timestamp_disjoint);
+ break;
+
default:
FIXME("Unhandled query type %#x.\n", type);
return WINED3DERR_NOTAVAILABLE;
@@ -1693,11 +1712,26 @@ HRESULT wined3d_query_vk_create(struct wined3d_device *device, enum wined3d_quer
if (!(query_vk = heap_alloc_zero(sizeof(*query_vk) + data_size)))
return E_OUTOFMEMORY;
+ data = query_vk + 1;
- wined3d_query_init(&query_vk->q, device, type, query_vk + 1, data_size, ops, parent, parent_ops);
+ wined3d_query_init(&query_vk->q, device, type, data, data_size, ops, parent, parent_ops);
list_init(&query_vk->entry);
- if (type == WINED3D_QUERY_TYPE_OCCLUSION)
- query_vk->control_flags = VK_QUERY_CONTROL_PRECISE_BIT;
+
+ switch (type)
+ {
+ case WINED3D_QUERY_TYPE_OCCLUSION:
+ query_vk->control_flags = VK_QUERY_CONTROL_PRECISE_BIT;
+ break;
+
+ case WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT:
+ disjoint_data = data;
+ disjoint_data->frequency = 1000000000 / wined3d_adapter_vk(device->adapter)->device_limits.timestampPeriod;
+ disjoint_data->disjoint = FALSE;
+ break;
+
+ default:
+ break;
+ }
TRACE("Created query %p.\n", query_vk);
*query = &query_vk->q;
--
2.20.1
1
0
[PATCH 4/5] wined3d: Implement timestamp queries for the Vulkan adapter.
by Henri Verbeet 26 May '20
by Henri Verbeet 26 May '20
26 May '20
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 7 ++--
dlls/wined3d/context_vk.c | 6 ++++
dlls/wined3d/query.c | 66 +++++++++++++++++++++++++++++++++-
dlls/wined3d/wined3d_private.h | 2 ++
4 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 84eda1e551b..3cccda3b2c6 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -292,7 +292,7 @@ static void adapter_vk_destroy(struct wined3d_adapter *adapter)
}
static HRESULT wined3d_select_vulkan_queue_family(const struct wined3d_adapter_vk *adapter_vk,
- uint32_t *queue_family_index)
+ uint32_t *queue_family_index, uint32_t *timestamp_bits)
{
VkPhysicalDevice physical_device = adapter_vk->physical_device;
const struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
@@ -311,6 +311,7 @@ static HRESULT wined3d_select_vulkan_queue_family(const struct wined3d_adapter_v
if (queue_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
{
*queue_family_index = i;
+ *timestamp_bits = queue_properties[i].timestampValidBits;
heap_free(queue_properties);
return WINED3D_OK;
}
@@ -496,13 +497,14 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
VkPhysicalDevice physical_device;
VkDeviceCreateInfo device_info;
uint32_t queue_family_index;
+ uint32_t timestamp_bits;
VkResult vr;
HRESULT hr;
if (!(device_vk = heap_alloc_zero(sizeof(*device_vk))))
return E_OUTOFMEMORY;
- if (FAILED(hr = wined3d_select_vulkan_queue_family(adapter_vk, &queue_family_index)))
+ if (FAILED(hr = wined3d_select_vulkan_queue_family(adapter_vk, &queue_family_index, ×tamp_bits)))
goto fail;
physical_device = adapter_vk->physical_device;
@@ -564,6 +566,7 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
device_vk->vk_device = vk_device;
VK_CALL(vkGetDeviceQueue(vk_device, queue_family_index, 0, &device_vk->vk_queue));
device_vk->vk_queue_family_index = queue_family_index;
+ device_vk->timestamp_bits = timestamp_bits;
device_vk->vk_info = *vk_info;
#define LOAD_DEVICE_PFN(name) \
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 2964eb30cc4..af29ef7e7a7 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -1227,6 +1227,10 @@ bool wined3d_context_vk_allocate_query(struct wined3d_context_vk *context_vk,
free_pools = &context_vk->free_occlusion_query_pools;
break;
+ case WINED3D_QUERY_TYPE_TIMESTAMP:
+ free_pools = &context_vk->free_timestamp_query_pools;
+ break;
+
default:
FIXME("Unhandled query type %#x.\n", type);
return false;
@@ -1286,6 +1290,7 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
VK_CALL(vkDestroyCommandPool(device_vk->vk_device, context_vk->vk_command_pool, NULL));
wined3d_context_vk_cleanup_resources(context_vk);
wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_occlusion_query_pools);
+ wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_timestamp_query_pools);
wine_rb_destroy(&context_vk->bo_slab_available, wined3d_context_vk_destroy_bo_slab, context_vk);
heap_free(context_vk->pending_queries.queries);
heap_free(context_vk->submitted.buffers);
@@ -3057,6 +3062,7 @@ HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wi
list_init(&context_vk->active_queries);
list_init(&context_vk->free_occlusion_query_pools);
+ list_init(&context_vk->free_timestamp_query_pools);
wine_rb_init(&context_vk->render_passes, wined3d_render_pass_vk_compare);
wine_rb_init(&context_vk->pipeline_layouts, wined3d_pipeline_layout_vk_compare);
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index b72ffd633c5..3b6f442f4a7 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -1403,6 +1403,11 @@ bool wined3d_query_pool_vk_init(struct wined3d_query_pool_vk *pool_vk,
pool_info.pipelineStatistics = 0;
break;
+ case WINED3D_QUERY_TYPE_TIMESTAMP:
+ pool_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
+ pool_info.pipelineStatistics = 0;
+ break;
+
default:
FIXME("Unhandled query type %#x.\n", type);
return false;
@@ -1428,6 +1433,7 @@ bool wined3d_query_vk_accumulate_data(struct wined3d_query_vk *query_vk,
union
{
uint64_t occlusion;
+ uint64_t timestamp;
} tmp, *result;
if ((vr = VK_CALL(vkGetQueryPoolResults(device_vk->vk_device, pool_idx->pool_vk->vk_query_pool,
@@ -1447,6 +1453,10 @@ bool wined3d_query_vk_accumulate_data(struct wined3d_query_vk *query_vk,
result->occlusion += tmp.occlusion;
break;
+ case WINED3D_QUERY_TYPE_TIMESTAMP:
+ result->timestamp = tmp.timestamp;
+ break;
+
default:
FIXME("Unhandled query type %#x.\n", query_vk->q.type);
return false;
@@ -1607,9 +1617,53 @@ static const struct wined3d_query_ops wined3d_query_vk_ops =
.query_destroy = wined3d_query_vk_destroy,
};
+static BOOL wined3d_query_timestamp_vk_issue(struct wined3d_query *query, uint32_t flags)
+{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(query->device);
+ struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
+ const struct wined3d_vk_info *vk_info;
+ struct wined3d_context_vk *context_vk;
+ VkCommandBuffer command_buffer;
+
+ TRACE("query %p, flags %#x.\n", query, flags);
+
+ if (flags & WINED3DISSUE_BEGIN)
+ TRACE("Ignoring WINED3DISSUE_BEGIN.\n");
+
+ if (flags & WINED3DISSUE_END)
+ {
+ context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0));
+ vk_info = context_vk->vk_info;
+
+ wined3d_context_vk_end_current_render_pass(context_vk);
+ command_buffer = wined3d_context_vk_get_command_buffer(context_vk);
+ if (!query_vk->pool_idx.pool_vk)
+ wined3d_context_vk_allocate_query(context_vk, query_vk->q.type, &query_vk->pool_idx);
+ VK_CALL(vkCmdResetQueryPool(command_buffer, query_vk->pool_idx.pool_vk->vk_query_pool,
+ query_vk->pool_idx.idx, 1));
+ VK_CALL(vkCmdWriteTimestamp(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+ query_vk->pool_idx.pool_vk->vk_query_pool, query_vk->pool_idx.idx));
+ wined3d_context_vk_reference_query(context_vk, query_vk);
+
+ context_release(&context_vk->c);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static const struct wined3d_query_ops wined3d_query_timestamp_vk_ops =
+{
+ .query_poll = wined3d_query_vk_poll,
+ .query_issue = wined3d_query_timestamp_vk_issue,
+ .query_destroy = wined3d_query_vk_destroy,
+};
+
HRESULT wined3d_query_vk_create(struct wined3d_device *device, enum wined3d_query_type type,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
{
+ const struct wined3d_query_ops *ops = &wined3d_query_vk_ops;
struct wined3d_query_vk *query_vk;
unsigned int data_size;
@@ -1622,6 +1676,16 @@ HRESULT wined3d_query_vk_create(struct wined3d_device *device, enum wined3d_quer
data_size = sizeof(uint64_t);
break;
+ case WINED3D_QUERY_TYPE_TIMESTAMP:
+ if (!wined3d_device_vk(device)->timestamp_bits)
+ {
+ WARN("Timestamp queries not supported.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+ ops = &wined3d_query_timestamp_vk_ops;
+ data_size = sizeof(uint64_t);
+ break;
+
default:
FIXME("Unhandled query type %#x.\n", type);
return WINED3DERR_NOTAVAILABLE;
@@ -1630,7 +1694,7 @@ HRESULT wined3d_query_vk_create(struct wined3d_device *device, enum wined3d_quer
if (!(query_vk = heap_alloc_zero(sizeof(*query_vk) + data_size)))
return E_OUTOFMEMORY;
- wined3d_query_init(&query_vk->q, device, type, query_vk + 1, data_size, &wined3d_query_vk_ops, parent, parent_ops);
+ wined3d_query_init(&query_vk->q, device, type, query_vk + 1, data_size, ops, parent, parent_ops);
list_init(&query_vk->entry);
if (type == WINED3D_QUERY_TYPE_OCCLUSION)
query_vk->control_flags = VK_QUERY_CONTROL_PRECISE_BIT;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 5c92eecbf3e..9f8c212fbf3 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2495,6 +2495,7 @@ struct wined3d_context_vk
struct list active_queries;
struct wined3d_pending_queries_vk pending_queries;
struct list free_occlusion_query_pools;
+ struct list free_timestamp_query_pools;
struct wined3d_retired_objects_vk retired;
struct wine_rb_tree render_passes;
@@ -3857,6 +3858,7 @@ struct wined3d_device_vk
VkDevice vk_device;
VkQueue vk_queue;
uint32_t vk_queue_family_index;
+ uint32_t timestamp_bits;
struct wined3d_vk_info vk_info;
--
2.20.1
1
0
[PATCH 3/5] wined3d: Implement occlusion queries for the Vulkan adapter.
by Henri Verbeet 26 May '20
by Henri Verbeet 26 May '20
26 May '20
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 15 +-
dlls/wined3d/context_vk.c | 157 +++++++++++++++++-
dlls/wined3d/query.c | 287 +++++++++++++++++++++++++++++++++
dlls/wined3d/wined3d_private.h | 86 ++++++++++
4 files changed, 539 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 8cbd8206617..84eda1e551b 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -1609,12 +1609,23 @@ static HRESULT adapter_vk_create_query(struct wined3d_device *device, enum wined
TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
device, type, parent, parent_ops, query);
- return WINED3DERR_NOTAVAILABLE;
+ return wined3d_query_vk_create(device, type, parent, parent_ops, query);
+}
+
+static void wined3d_query_vk_destroy_object(void *object)
+{
+ struct wined3d_query_vk *query_vk = object;
+
+ query_vk->q.query_ops->query_destroy(&query_vk->q);
}
static void adapter_vk_destroy_query(struct wined3d_query *query)
{
- TRACE("query %p.\n", query);
+ struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
+
+ TRACE("query_vk %p.\n", query_vk);
+
+ wined3d_cs_destroy_object(query->device->cs, wined3d_query_vk_destroy_object, query_vk);
}
static void adapter_vk_flush_context(struct wined3d_context *context)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 3a6671036e2..2964eb30cc4 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -813,14 +813,11 @@ void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk, const
wined3d_context_vk_destroy_memory(context_vk, bo->vk_memory, bo->command_buffer_id);
}
-static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *context_vk)
+void wined3d_context_vk_poll_command_buffers(struct wined3d_context_vk *context_vk)
{
struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
- struct wined3d_retired_objects_vk *retired = &context_vk->retired;
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
struct wined3d_command_buffer_vk *buffer;
- struct wined3d_retired_object_vk *o;
- uint64_t command_buffer_id;
SIZE_T i = 0;
while (i < context_vk->submitted.buffer_count)
@@ -842,6 +839,18 @@ static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *cont
context_vk->completed_command_buffer_id = buffer->id;
*buffer = context_vk->submitted.buffers[--context_vk->submitted.buffer_count];
}
+}
+
+static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *context_vk)
+{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
+ struct wined3d_retired_objects_vk *retired = &context_vk->retired;
+ const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+ struct wined3d_retired_object_vk *o;
+ uint64_t command_buffer_id;
+ SIZE_T i = 0;
+
+ wined3d_context_vk_poll_command_buffers(context_vk);
command_buffer_id = context_vk->completed_command_buffer_id;
retired->free = NULL;
@@ -1194,6 +1203,64 @@ static void wined3d_shader_descriptor_writes_vk_cleanup(struct wined3d_shader_de
heap_free(writes->writes);
}
+static void wined3d_context_vk_destroy_query_pools(struct wined3d_context_vk *context_vk, struct list *free_pools)
+{
+ struct wined3d_query_pool_vk *pool_vk, *entry;
+
+ LIST_FOR_EACH_ENTRY_SAFE(pool_vk, entry, free_pools, struct wined3d_query_pool_vk, entry)
+ {
+ wined3d_query_pool_vk_cleanup(pool_vk, context_vk);
+ heap_free(pool_vk);
+ }
+}
+
+bool wined3d_context_vk_allocate_query(struct wined3d_context_vk *context_vk,
+ enum wined3d_query_type type, struct wined3d_query_pool_idx_vk *pool_idx)
+{
+ struct wined3d_query_pool_vk *pool_vk, *entry;
+ struct list *free_pools;
+ size_t idx;
+
+ switch (type)
+ {
+ case WINED3D_QUERY_TYPE_OCCLUSION:
+ free_pools = &context_vk->free_occlusion_query_pools;
+ break;
+
+ default:
+ FIXME("Unhandled query type %#x.\n", type);
+ return false;
+ }
+
+ LIST_FOR_EACH_ENTRY_SAFE(pool_vk, entry, free_pools, struct wined3d_query_pool_vk, entry)
+ {
+ if (wined3d_query_pool_vk_allocate_query(pool_vk, &idx))
+ goto done;
+ list_remove(&pool_vk->entry);
+ }
+
+ if (!(pool_vk = heap_alloc_zero(sizeof(*pool_vk))))
+ return false;
+ if (!wined3d_query_pool_vk_init(pool_vk, context_vk, type, free_pools))
+ {
+ heap_free(pool_vk);
+ return false;
+ }
+
+ if (!wined3d_query_pool_vk_allocate_query(pool_vk, &idx))
+ {
+ wined3d_query_pool_vk_cleanup(pool_vk, context_vk);
+ heap_free(pool_vk);
+ return false;
+ }
+
+done:
+ pool_idx->pool_vk = pool_vk;
+ pool_idx->idx = idx;
+
+ return true;
+}
+
void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
{
struct wined3d_command_buffer_vk *buffer = &context_vk->current_command_buffer;
@@ -1218,7 +1285,9 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
VK_CALL(vkDestroyFramebuffer(device_vk->vk_device, context_vk->vk_framebuffer, NULL));
VK_CALL(vkDestroyCommandPool(device_vk->vk_device, context_vk->vk_command_pool, NULL));
wined3d_context_vk_cleanup_resources(context_vk);
+ wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_occlusion_query_pools);
wine_rb_destroy(&context_vk->bo_slab_available, wined3d_context_vk_destroy_bo_slab, context_vk);
+ heap_free(context_vk->pending_queries.queries);
heap_free(context_vk->submitted.buffers);
heap_free(context_vk->retired.objects);
@@ -1230,6 +1299,70 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
wined3d_context_cleanup(&context_vk->c);
}
+void wined3d_context_vk_remove_pending_queries(struct wined3d_context_vk *context_vk,
+ struct wined3d_query_vk *query_vk)
+{
+ struct wined3d_pending_queries_vk *pending = &context_vk->pending_queries;
+ struct wined3d_pending_query_vk *p;
+ size_t i;
+
+ pending->free_idx = ~(size_t)0;
+ for (i = pending->count; i; --i)
+ {
+ p = &pending->queries[i - 1];
+
+ if (p->query_vk)
+ {
+ if (p->query_vk != query_vk && !wined3d_query_vk_accumulate_data(p->query_vk, context_vk, &p->pool_idx))
+ continue;
+ wined3d_query_pool_vk_free_query(p->pool_idx.pool_vk, p->pool_idx.idx);
+ --p->query_vk->pending_count;
+ }
+
+ if (i == pending->count)
+ {
+ --pending->count;
+ continue;
+ }
+
+ p->query_vk = NULL;
+ p->pool_idx.pool_vk = NULL;
+ p->pool_idx.idx = pending->free_idx;
+ pending->free_idx = i - 1;
+ }
+}
+
+void wined3d_context_vk_accumulate_pending_queries(struct wined3d_context_vk *context_vk)
+{
+ wined3d_context_vk_remove_pending_queries(context_vk, NULL);
+}
+
+void wined3d_context_vk_add_pending_query(struct wined3d_context_vk *context_vk, struct wined3d_query_vk *query_vk)
+{
+ struct wined3d_pending_queries_vk *pending = &context_vk->pending_queries;
+ struct wined3d_pending_query_vk *p;
+
+ if (pending->free_idx != ~(size_t)0)
+ {
+ p = &pending->queries[pending->free_idx];
+ pending->free_idx = p->pool_idx.idx;
+ }
+ else
+ {
+ if (!wined3d_array_reserve((void **)&pending->queries, &pending->size,
+ pending->count + 1, sizeof(*pending->queries)))
+ {
+ ERR("Failed to allocate entry.\n");
+ return;
+ }
+ p = &pending->queries[pending->count++];
+ }
+
+ p->query_vk = query_vk;
+ p->pool_idx = query_vk->pool_idx;
+ ++query_vk->pending_count;
+}
+
VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk *context_vk)
{
struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
@@ -1237,6 +1370,7 @@ VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk
VkCommandBufferAllocateInfo command_buffer_info;
struct wined3d_command_buffer_vk *buffer;
VkCommandBufferBeginInfo begin_info;
+ struct wined3d_query_vk *query_vk;
VkResult vr;
TRACE("context_vk %p.\n", context_vk);
@@ -1273,6 +1407,12 @@ VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk
return buffer->vk_command_buffer = VK_NULL_HANDLE;
}
+ wined3d_context_vk_accumulate_pending_queries(context_vk);
+ LIST_FOR_EACH_ENTRY(query_vk, &context_vk->active_queries, struct wined3d_query_vk, entry)
+ {
+ wined3d_query_vk_resume(query_vk, context_vk);
+ }
+
TRACE("Created new command buffer %p with id 0x%s.\n",
buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id));
@@ -1286,6 +1426,7 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context
struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
struct wined3d_command_buffer_vk *buffer;
+ struct wined3d_query_vk *query_vk;
VkFenceCreateInfo fence_desc;
VkSubmitInfo submit_info;
VkResult vr;
@@ -1302,6 +1443,11 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context
TRACE("Submitting command buffer %p with id 0x%s.\n",
buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id));
+ LIST_FOR_EACH_ENTRY(query_vk, &context_vk->active_queries, struct wined3d_query_vk, entry)
+ {
+ wined3d_query_vk_suspend(query_vk, context_vk);
+ }
+
wined3d_context_vk_end_current_render_pass(context_vk);
context_vk->graphics.vk_pipeline = VK_NULL_HANDLE;
context_vk->update_compute_pipeline = 1;
@@ -2909,6 +3055,9 @@ HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wi
wined3d_context_vk_init_graphics_pipeline_key(context_vk);
+ list_init(&context_vk->active_queries);
+ list_init(&context_vk->free_occlusion_query_pools);
+
wine_rb_init(&context_vk->render_passes, wined3d_render_pass_vk_compare);
wine_rb_init(&context_vk->pipeline_layouts, wined3d_pipeline_layout_vk_compare);
wine_rb_init(&context_vk->graphics_pipelines, wined3d_graphics_pipeline_vk_compare);
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index ab3bb743809..b72ffd633c5 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -1354,6 +1354,293 @@ HRESULT wined3d_query_gl_create(struct wined3d_device *device, enum wined3d_quer
}
}
+void wined3d_query_pool_vk_free_query(struct wined3d_query_pool_vk *pool_vk, size_t idx)
+{
+ wined3d_bitmap_clear(pool_vk->allocated, idx);
+
+ if (list_empty(&pool_vk->entry))
+ list_add_tail(pool_vk->free_list, &pool_vk->entry);
+}
+
+bool wined3d_query_pool_vk_allocate_query(struct wined3d_query_pool_vk *pool_vk, size_t *idx)
+{
+ if ((*idx = wined3d_bitmap_ffz(pool_vk->allocated, WINED3D_QUERY_POOL_SIZE, 0)) > WINED3D_QUERY_POOL_SIZE)
+ return false;
+ wined3d_bitmap_set(pool_vk->allocated, *idx);
+
+ return true;
+}
+
+void wined3d_query_pool_vk_cleanup(struct wined3d_query_pool_vk *pool_vk, struct wined3d_context_vk *context_vk)
+{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
+ const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+
+ VK_CALL(vkDestroyQueryPool(device_vk->vk_device, pool_vk->vk_query_pool, NULL));
+ list_remove(&pool_vk->entry);
+}
+
+bool wined3d_query_pool_vk_init(struct wined3d_query_pool_vk *pool_vk,
+ struct wined3d_context_vk *context_vk, enum wined3d_query_type type, struct list *free_pools)
+{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
+ const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+ VkQueryPoolCreateInfo pool_info;
+ VkResult vr;
+
+ list_init(&pool_vk->entry);
+ pool_vk->free_list = free_pools;
+
+ pool_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
+ pool_info.pNext = NULL;
+ pool_info.flags = 0;
+ pool_info.queryCount = WINED3D_QUERY_POOL_SIZE;
+
+ switch (type)
+ {
+ case WINED3D_QUERY_TYPE_OCCLUSION:
+ pool_info.queryType = VK_QUERY_TYPE_OCCLUSION;
+ pool_info.pipelineStatistics = 0;
+ break;
+
+ default:
+ FIXME("Unhandled query type %#x.\n", type);
+ return false;
+ }
+
+ if ((vr = VK_CALL(vkCreateQueryPool(device_vk->vk_device, &pool_info, NULL, &pool_vk->vk_query_pool))) < 0)
+ {
+ ERR("Failed to create Vulkan query pool, vr %s.\n", wined3d_debug_vkresult(vr));
+ return false;
+ }
+
+ list_add_head(free_pools, &pool_vk->entry);
+
+ return true;
+}
+
+bool wined3d_query_vk_accumulate_data(struct wined3d_query_vk *query_vk,
+ struct wined3d_context_vk *context_vk, const struct wined3d_query_pool_idx_vk *pool_idx)
+{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
+ const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+ VkResult vr;
+ union
+ {
+ uint64_t occlusion;
+ } tmp, *result;
+
+ if ((vr = VK_CALL(vkGetQueryPoolResults(device_vk->vk_device, pool_idx->pool_vk->vk_query_pool,
+ pool_idx->idx, 1, sizeof(tmp), &tmp, sizeof(tmp), VK_QUERY_RESULT_64_BIT))) < 0)
+ {
+ ERR("Failed to get query results, vr %s.\n", wined3d_debug_vkresult(vr));
+ return false;
+ }
+
+ if (vr == VK_NOT_READY)
+ return false;
+
+ result = (void *)query_vk->q.data;
+ switch (query_vk->q.type)
+ {
+ case WINED3D_QUERY_TYPE_OCCLUSION:
+ result->occlusion += tmp.occlusion;
+ break;
+
+ default:
+ FIXME("Unhandled query type %#x.\n", query_vk->q.type);
+ return false;
+ }
+
+ return true;
+}
+
+static void wined3d_query_vk_begin(struct wined3d_query_vk *query_vk,
+ struct wined3d_context_vk *context_vk, VkCommandBuffer vk_command_buffer)
+{
+ const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+ struct wined3d_query_pool_vk *pool_vk;
+ size_t idx;
+
+ if (!query_vk->pool_idx.pool_vk
+ && !wined3d_context_vk_allocate_query(context_vk, query_vk->q.type, &query_vk->pool_idx))
+ {
+ ERR("Failed to allocate new query.\n");
+ return;
+ }
+ pool_vk = query_vk->pool_idx.pool_vk;
+ idx = query_vk->pool_idx.idx;
+
+ VK_CALL(vkCmdResetQueryPool(vk_command_buffer, pool_vk->vk_query_pool, idx, 1));
+ VK_CALL(vkCmdBeginQuery(vk_command_buffer, pool_vk->vk_query_pool, idx, query_vk->control_flags));
+ wined3d_context_vk_reference_query(context_vk, query_vk);
+}
+
+static void wined3d_query_vk_end(struct wined3d_query_vk *query_vk,
+ struct wined3d_context_vk *context_vk, VkCommandBuffer vk_command_buffer)
+{
+ const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+ struct wined3d_query_pool_vk *pool_vk;
+ size_t idx;
+
+ pool_vk = query_vk->pool_idx.pool_vk;
+ idx = query_vk->pool_idx.idx;
+
+ VK_CALL(vkCmdEndQuery(vk_command_buffer, pool_vk->vk_query_pool, idx));
+}
+
+void wined3d_query_vk_resume(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk)
+{
+ VkCommandBuffer vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer;
+
+ wined3d_query_vk_begin(query_vk, context_vk, vk_command_buffer);
+}
+
+void wined3d_query_vk_suspend(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk)
+{
+ VkCommandBuffer vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer;
+
+ wined3d_query_vk_end(query_vk, context_vk, vk_command_buffer);
+ wined3d_context_vk_add_pending_query(context_vk, query_vk);
+ query_vk->pool_idx.pool_vk = NULL;
+}
+
+static BOOL wined3d_query_vk_poll(struct wined3d_query *query, uint32_t flags)
+{
+ struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
+ struct wined3d_context_vk *context_vk;
+
+ context_vk = wined3d_context_vk(context_acquire(query->device, NULL, 0));
+
+ if (flags & WINED3DGETDATA_FLUSH)
+ wined3d_context_vk_submit_command_buffer(context_vk, 0, NULL, NULL, 0, NULL);
+ if (query_vk->command_buffer_id == context_vk->current_command_buffer.id)
+ goto unavailable;
+
+ if (query_vk->command_buffer_id > context_vk->completed_command_buffer_id)
+ wined3d_context_vk_poll_command_buffers(context_vk);
+ if (query_vk->command_buffer_id > context_vk->completed_command_buffer_id)
+ goto unavailable;
+
+ if (query_vk->pending_count)
+ wined3d_context_vk_accumulate_pending_queries(context_vk);
+ if (query_vk->pending_count)
+ goto unavailable;
+
+ if (!wined3d_query_vk_accumulate_data(query_vk, context_vk, &query_vk->pool_idx))
+ goto unavailable;
+
+ context_release(&context_vk->c);
+
+ return TRUE;
+
+unavailable:
+ context_release(&context_vk->c);
+ return FALSE;
+}
+
+static BOOL wined3d_query_vk_issue(struct wined3d_query *query, uint32_t flags)
+{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(query->device);
+ struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
+ struct wined3d_context_vk *context_vk;
+ VkCommandBuffer vk_command_buffer;
+ bool poll = false;
+
+ TRACE("query %p, flags %#x.\n", query, flags);
+
+ if (flags & WINED3DISSUE_BEGIN)
+ {
+ context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0));
+
+ wined3d_context_vk_end_current_render_pass(context_vk);
+ list_remove(&query_vk->entry);
+ if (query_vk->pending_count)
+ wined3d_context_vk_remove_pending_queries(context_vk, query_vk);
+ memset((void *)query->data, 0, query->data_size);
+ vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk);
+ wined3d_query_vk_begin(query_vk, context_vk, vk_command_buffer);
+ list_add_head(&context_vk->active_queries, &query_vk->entry);
+ query_vk->started = true;
+
+ context_release(&context_vk->c);
+ }
+ if (flags & WINED3DISSUE_END && query_vk->started)
+ {
+ context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0));
+
+ /* If the query was already ended because the command buffer was
+ * flushed, we don't need to end it here. */
+ if ((vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer))
+ wined3d_query_vk_end(query_vk, context_vk, vk_command_buffer);
+ list_remove(&query_vk->entry);
+ query_vk->started = false;
+ poll = true;
+
+ context_release(&context_vk->c);
+ }
+
+ return poll;
+}
+
+static void wined3d_query_vk_destroy(struct wined3d_query *query)
+{
+ struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
+ struct wined3d_context_vk *context_vk;
+
+ list_remove(&query_vk->entry);
+ if (query_vk->pending_count)
+ {
+ context_vk = wined3d_context_vk(context_acquire(query_vk->q.device, NULL, 0));
+ wined3d_context_vk_remove_pending_queries(context_vk, query_vk);
+ context_release(&context_vk->c);
+ }
+ if (query_vk->pool_idx.pool_vk)
+ wined3d_query_pool_vk_free_query(query_vk->pool_idx.pool_vk, query_vk->pool_idx.idx);
+ heap_free(query_vk);
+}
+
+static const struct wined3d_query_ops wined3d_query_vk_ops =
+{
+ .query_poll = wined3d_query_vk_poll,
+ .query_issue = wined3d_query_vk_issue,
+ .query_destroy = wined3d_query_vk_destroy,
+};
+
+HRESULT wined3d_query_vk_create(struct wined3d_device *device, enum wined3d_query_type type,
+ void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
+{
+ struct wined3d_query_vk *query_vk;
+ unsigned int data_size;
+
+ TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
+ device, type, parent, parent_ops, query);
+
+ switch (type)
+ {
+ case WINED3D_QUERY_TYPE_OCCLUSION:
+ data_size = sizeof(uint64_t);
+ break;
+
+ default:
+ FIXME("Unhandled query type %#x.\n", type);
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ if (!(query_vk = heap_alloc_zero(sizeof(*query_vk) + data_size)))
+ return E_OUTOFMEMORY;
+
+ wined3d_query_init(&query_vk->q, device, type, query_vk + 1, data_size, &wined3d_query_vk_ops, parent, parent_ops);
+ list_init(&query_vk->entry);
+ if (type == WINED3D_QUERY_TYPE_OCCLUSION)
+ query_vk->control_flags = VK_QUERY_CONTROL_PRECISE_BIT;
+
+ TRACE("Created query %p.\n", query_vk);
+ *query = &query_vk->q;
+
+ return WINED3D_OK;
+}
+
HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type type,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
{
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e9081e5d17d..5c92eecbf3e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -86,6 +86,7 @@ struct wined3d_fragment_pipe_ops;
struct wined3d_adapter;
struct wined3d_buffer_vk;
struct wined3d_context;
+struct wined3d_context_vk;
struct wined3d_gl_info;
struct wined3d_state;
struct wined3d_swapchain_gl;
@@ -1952,6 +1953,54 @@ struct wined3d_pipeline_statistics_query
BOOL started;
};
+#define WINED3D_QUERY_POOL_SIZE 256
+
+struct wined3d_query_pool_vk
+{
+ struct list entry;
+
+ struct list *free_list;
+ VkQueryPool vk_query_pool;
+ uint32_t allocated[WINED3D_BITMAP_SIZE(WINED3D_QUERY_POOL_SIZE)];
+};
+
+bool wined3d_query_pool_vk_allocate_query(struct wined3d_query_pool_vk *pool_vk, size_t *idx) DECLSPEC_HIDDEN;
+void wined3d_query_pool_vk_cleanup(struct wined3d_query_pool_vk *pool_vk,
+ struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
+void wined3d_query_pool_vk_free_query(struct wined3d_query_pool_vk *pool_vk, size_t idx) DECLSPEC_HIDDEN;
+bool wined3d_query_pool_vk_init(struct wined3d_query_pool_vk *pool_vk, struct wined3d_context_vk *context_vk,
+ enum wined3d_query_type type, struct list *free_pools) DECLSPEC_HIDDEN;
+
+struct wined3d_query_pool_idx_vk
+{
+ struct wined3d_query_pool_vk *pool_vk;
+ size_t idx;
+};
+
+struct wined3d_query_vk
+{
+ struct wined3d_query q;
+
+ struct list entry;
+ struct wined3d_query_pool_idx_vk pool_idx;
+ bool started;
+ uint64_t command_buffer_id;
+ uint32_t control_flags;
+ size_t pending_count;
+};
+
+static inline struct wined3d_query_vk *wined3d_query_vk(struct wined3d_query *query)
+{
+ return CONTAINING_RECORD(query, struct wined3d_query_vk, q);
+}
+
+bool wined3d_query_vk_accumulate_data(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk,
+ const struct wined3d_query_pool_idx_vk *pool_idx) DECLSPEC_HIDDEN;
+HRESULT wined3d_query_vk_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent,
+ const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query) DECLSPEC_HIDDEN;
+void wined3d_query_vk_resume(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
+void wined3d_query_vk_suspend(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
+
struct wined3d_gl_view
{
GLenum target;
@@ -2382,6 +2431,20 @@ struct wined3d_shader_descriptor_writes_vk
SIZE_T size, count;
};
+struct wined3d_pending_query_vk
+{
+ struct wined3d_query_vk *query_vk;
+ struct wined3d_query_pool_idx_vk pool_idx;
+};
+
+struct wined3d_pending_queries_vk
+{
+ struct wined3d_pending_query_vk *queries;
+ SIZE_T free_idx;
+ SIZE_T size;
+ SIZE_T count;
+};
+
struct wined3d_context_vk
{
struct wined3d_context c;
@@ -2429,6 +2492,10 @@ struct wined3d_context_vk
VkSampleCountFlagBits sample_count;
unsigned int rt_count;
+ struct list active_queries;
+ struct wined3d_pending_queries_vk pending_queries;
+ struct list free_occlusion_query_pools;
+
struct wined3d_retired_objects_vk retired;
struct wine_rb_tree render_passes;
struct wine_rb_tree pipeline_layouts;
@@ -2441,8 +2508,13 @@ static inline struct wined3d_context_vk *wined3d_context_vk(struct wined3d_conte
return CONTAINING_RECORD(context, struct wined3d_context_vk, c);
}
+void wined3d_context_vk_accumulate_pending_queries(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
+void wined3d_context_vk_add_pending_query(struct wined3d_context_vk *context_vk,
+ struct wined3d_query_vk *query_vk) DECLSPEC_HIDDEN;
struct wined3d_allocator_block *wined3d_context_vk_allocate_memory(struct wined3d_context_vk *context_vk,
unsigned int memory_type, VkDeviceSize size, VkDeviceMemory *vk_memory) DECLSPEC_HIDDEN;
+bool wined3d_context_vk_allocate_query(struct wined3d_context_vk *context_vk,
+ enum wined3d_query_type type, struct wined3d_query_pool_idx_vk *pool_idx) DECLSPEC_HIDDEN;
VkDeviceMemory wined3d_context_vk_allocate_vram_chunk_memory(struct wined3d_context_vk *context_vk,
unsigned int pool, size_t size) DECLSPEC_HIDDEN;
VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk *context_vk,
@@ -2481,6 +2553,9 @@ void wined3d_context_vk_image_barrier(struct wined3d_context_vk *context_vk,
VkImageLayout new_layout, VkImage image, VkImageAspectFlags aspect_mask) DECLSPEC_HIDDEN;
HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk,
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+void wined3d_context_vk_poll_command_buffers(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
+void wined3d_context_vk_remove_pending_queries(struct wined3d_context_vk *context_vk,
+ struct wined3d_query_vk *query_vk) DECLSPEC_HIDDEN;
void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context_vk,
unsigned int wait_semaphore_count, const VkSemaphore *wait_semaphores, const VkPipelineStageFlags *wait_stages,
unsigned int signal_semaphore_count, const VkSemaphore *signal_semaphores) DECLSPEC_HIDDEN;
@@ -5780,6 +5855,12 @@ static inline void wined3d_context_vk_reference_texture(const struct wined3d_con
texture_vk->command_buffer_id = context_vk->current_command_buffer.id;
}
+static inline void wined3d_context_vk_reference_query(const struct wined3d_context_vk *context_vk,
+ struct wined3d_query_vk *query_vk)
+{
+ query_vk->command_buffer_id = context_vk->current_command_buffer.id;
+}
+
static inline void wined3d_context_vk_reference_sampler(const struct wined3d_context_vk *context_vk,
struct wined3d_sampler_vk *sampler_vk)
{
@@ -5859,6 +5940,11 @@ static inline void wined3d_viewport_get_z_range(const struct wined3d_viewport *v
*max_z = max(vp->max_z, vp->min_z + 0.001f);
}
+static inline BOOL wined3d_bitmap_clear(uint32_t *map, unsigned int idx)
+{
+ return map[idx >> 5] &= ~(1u << (idx & 0x1f));
+}
+
static inline BOOL wined3d_bitmap_set(uint32_t *map, unsigned int idx)
{
return map[idx >> 5] |= (1u << (idx & 0x1f));
--
2.20.1
1
0
[PATCH 2/5] wined3d: Move the swapchain cursor texture blit to wined3d_cs_exec_present().
by Henri Verbeet 26 May '20
by Henri Verbeet 26 May '20
26 May '20
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/cs.c | 27 ++++++++++++++++++++++++++-
dlls/wined3d/swapchain.c | 26 --------------------------
2 files changed, 26 insertions(+), 27 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index b5a34a6ab62..ffd00c9b950 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -521,7 +521,7 @@ static void wined3d_cs_exec_nop(struct wined3d_cs *cs, const void *data)
static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
{
- struct wined3d_texture *logo_texture, *back_buffer;
+ struct wined3d_texture *logo_texture, *cursor_texture, *back_buffer;
const struct wined3d_cs_present *op = data;
struct wined3d_swapchain *swapchain;
unsigned int i;
@@ -539,6 +539,31 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
&rect, WINED3D_BLT_SRC_CKEY, NULL, WINED3D_TEXF_POINT);
}
+ if ((cursor_texture = swapchain->device->cursor_texture)
+ && swapchain->device->bCursorVisible && !swapchain->device->hardwareCursor)
+ {
+ RECT dst_rect =
+ {
+ swapchain->device->xScreenSpace - swapchain->device->xHotSpot,
+ swapchain->device->yScreenSpace - swapchain->device->yHotSpot,
+ swapchain->device->xScreenSpace + swapchain->device->cursorWidth - swapchain->device->xHotSpot,
+ swapchain->device->yScreenSpace + swapchain->device->cursorHeight - swapchain->device->yHotSpot,
+ };
+ RECT src_rect =
+ {
+ 0, 0, cursor_texture->resource.width, cursor_texture->resource.height
+ };
+ const RECT clip_rect = {0, 0, back_buffer->resource.width, back_buffer->resource.height};
+
+ TRACE("Rendering the software cursor.\n");
+
+ if (swapchain->state.desc.windowed)
+ MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&dst_rect, 2);
+ if (wined3d_clip_blit(&clip_rect, &dst_rect, &src_rect))
+ wined3d_texture_blt(back_buffer, 0, &dst_rect, cursor_texture, 0,
+ &src_rect, WINED3D_BLT_ALPHA_TEST, NULL, WINED3D_TEXF_POINT);
+ }
+
swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->swap_interval, op->flags);
if (TRACE_ON(fps))
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index a48b98aac3f..289013f4e99 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -469,7 +469,6 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain,
struct wined3d_texture *back_buffer = swapchain->back_buffers[0];
const struct wined3d_fb_state *fb = &swapchain->device->cs->state.fb;
struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
- struct wined3d_texture *cursor_texture;
const struct wined3d_gl_info *gl_info;
struct wined3d_context_gl *context_gl;
struct wined3d_context *context;
@@ -488,31 +487,6 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain,
swapchain_gl_set_swap_interval(swapchain, context_gl, swap_interval);
- if ((cursor_texture = swapchain->device->cursor_texture)
- && swapchain->device->bCursorVisible && !swapchain->device->hardwareCursor)
- {
- RECT dst_rect =
- {
- swapchain->device->xScreenSpace - swapchain->device->xHotSpot,
- swapchain->device->yScreenSpace - swapchain->device->yHotSpot,
- swapchain->device->xScreenSpace + swapchain->device->cursorWidth - swapchain->device->xHotSpot,
- swapchain->device->yScreenSpace + swapchain->device->cursorHeight - swapchain->device->yHotSpot,
- };
- RECT src_rect =
- {
- 0, 0, cursor_texture->resource.width, cursor_texture->resource.height
- };
- const RECT clip_rect = {0, 0, back_buffer->resource.width, back_buffer->resource.height};
-
- TRACE("Rendering the software cursor.\n");
-
- if (desc->windowed)
- MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&dst_rect, 2);
- if (wined3d_clip_blit(&clip_rect, &dst_rect, &src_rect))
- wined3d_texture_blt(back_buffer, 0, &dst_rect, cursor_texture, 0,
- &src_rect, WINED3D_BLT_ALPHA_TEST, NULL, WINED3D_TEXF_POINT);
- }
-
TRACE("Presenting DC %p.\n", context_gl->dc);
if (!(render_to_fbo = swapchain->render_to_fbo)
--
2.20.1
1
0
[PATCH 1/5] wined3d: Move the swapchain logo texture blit to wined3d_cs_exec_present().
by Henri Verbeet 26 May '20
by Henri Verbeet 26 May '20
26 May '20
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/cs.c | 11 +++++++++++
dlls/wined3d/swapchain.c | 11 +----------
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 89e59b5373a..b5a34a6ab62 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -521,13 +521,24 @@ static void wined3d_cs_exec_nop(struct wined3d_cs *cs, const void *data)
static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data)
{
+ struct wined3d_texture *logo_texture, *back_buffer;
const struct wined3d_cs_present *op = data;
struct wined3d_swapchain *swapchain;
unsigned int i;
swapchain = op->swapchain;
+ back_buffer = swapchain->back_buffers[0];
wined3d_swapchain_set_window(swapchain, op->dst_window_override);
+ if ((logo_texture = swapchain->device->logo_texture))
+ {
+ RECT rect = {0, 0, logo_texture->resource.width, logo_texture->resource.height};
+
+ /* Blit the logo into the upper left corner of the back-buffer. */
+ wined3d_texture_blt(back_buffer, 0, &rect, logo_texture, 0,
+ &rect, WINED3D_BLT_SRC_CKEY, NULL, WINED3D_TEXF_POINT);
+ }
+
swapchain->swapchain_ops->swapchain_present(swapchain, &op->src_rect, &op->dst_rect, op->swap_interval, op->flags);
if (TRACE_ON(fps))
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 9020a995209..a48b98aac3f 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -469,7 +469,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain,
struct wined3d_texture *back_buffer = swapchain->back_buffers[0];
const struct wined3d_fb_state *fb = &swapchain->device->cs->state.fb;
struct wined3d_rendertarget_view *dsv = fb->depth_stencil;
- struct wined3d_texture *logo_texture, *cursor_texture;
+ struct wined3d_texture *cursor_texture;
const struct wined3d_gl_info *gl_info;
struct wined3d_context_gl *context_gl;
struct wined3d_context *context;
@@ -488,15 +488,6 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain,
swapchain_gl_set_swap_interval(swapchain, context_gl, swap_interval);
- if ((logo_texture = swapchain->device->logo_texture))
- {
- RECT rect = {0, 0, logo_texture->resource.width, logo_texture->resource.height};
-
- /* Blit the logo into the upper left corner of the drawable. */
- wined3d_texture_blt(back_buffer, 0, &rect, logo_texture, 0, &rect,
- WINED3D_BLT_SRC_CKEY, NULL, WINED3D_TEXF_POINT);
- }
-
if ((cursor_texture = swapchain->device->cursor_texture)
&& swapchain->device->bCursorVisible && !swapchain->device->hardwareCursor)
{
--
2.20.1
1
0
https://bugs.winehq.org/show_bug.cgi?id=45536
Signed-off-by: Louis Lenders <xerox.xerox2000x(a)gmail.com>
---
dlls/usp10/usp10.c | 12 ++++++++++++
dlls/usp10/usp10.spec | 2 +-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index c9fe12a544..322091c547 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -4095,3 +4095,15 @@ HRESULT WINAPI ScriptGetFontFeatureTags( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANAL
return SHAPE_GetFontFeatureTags(hdc, (ScriptCache *)*psc, psa, tagScript, tagLangSys, cMaxTags, pFeatureTags, pcTags);
}
+
+HRESULT WINAPI ScriptGetFontAlternateGlyphs( HDC hdc, SCRIPT_CACHE *sc, SCRIPT_ANALYSIS *sa, OPENTYPE_TAG tag_script, OPENTYPE_TAG tag_langsys, OPENTYPE_TAG tag_feature,
+ WORD id, int size, WORD *list, int *count )
+{
+ FIXME("(%p, %p, %p, %s, %s, %s, 0x%04x, %d, %p, %p)\n", hdc, sc, sa, debugstr_an((char*)&tag_script,4), debugstr_an((char*)&tag_langsys,4),
+ debugstr_an((char*)&tag_feature,4), id, size, list, count);
+
+ if(count)
+ *count = 0;
+
+ return E_NOTIMPL;
+}
diff --git a/dlls/usp10/usp10.spec b/dlls/usp10/usp10.spec
index 3e97d919a9..96bf47147a 100644
--- a/dlls/usp10/usp10.spec
+++ b/dlls/usp10/usp10.spec
@@ -6,7 +6,7 @@
@ stdcall ScriptCacheGetHeight(ptr ptr ptr)
@ stdcall ScriptFreeCache(ptr)
@ stdcall ScriptGetCMap(ptr ptr ptr long long ptr)
-@ stub ScriptGetFontAlternateGlyphs
+@ stdcall ScriptGetFontAlternateGlyphs(long ptr ptr long long long long long ptr ptr)
@ stdcall ScriptGetFontFeatureTags(long ptr ptr long long long ptr ptr)
@ stdcall ScriptGetFontLanguageTags(long ptr ptr long long ptr ptr)
@ stdcall ScriptGetFontProperties(long ptr ptr)
--
2.27.0.rc0
2
1
26 May '20
Signed-off-by: Daniel Lehman <dlehman25(a)gmail.com>
v2: use getdents instead of open/closedir
needed by std::filesystem::remove_all, which removes files with:
- CreateFileW
- SetFileInformationByHandle(FileDispositionInfoEx) // currently unimplemented
- SetFileInformationByHandle(FileDispositionInfo) - DeleteFile = TRUE
- CloseHandle
---
dlls/ntdll/tests/file.c | 3 ---
server/fd.c | 57 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 31c18454f0..1d0682a633 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -3185,17 +3185,14 @@ todo_wine
CloseHandle( handle2 );
fdi.DoDeleteFile = TRUE;
res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
- todo_wine
ok( res == STATUS_DIRECTORY_NOT_EMPTY, "unexpected FileDispositionInformation result (expected STATUS_DIRECTORY_NOT_EMPTY, got %x)\n", res );
fileDeleted = DeleteFileA( buffer );
ok( fileDeleted, "File should have been deleted\n" );
buffer[dirpos] = '\0';
CloseHandle( handle );
fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
- todo_wine
ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
fileDeleted = RemoveDirectoryA( buffer );
-todo_wine
ok( fileDeleted, "Directory should have been deleted\n" );
}
diff --git a/server/fd.c b/server/fd.c
index 06d1d81bdb..178bbccfc7 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2364,6 +2364,56 @@ static struct fd *get_handle_fd_obj( struct process *process, obj_handle_t handl
return fd;
}
+#if defined(linux) && defined(SYS_getdents64)
+typedef struct
+{
+ uint64_t d_ino;
+ int64_t d_off;
+ unsigned short d_reclen;
+ unsigned char d_type;
+ char d_name[256];
+} KERNEL_DIRENT64;
+
+static inline int getdents64( int fd, char *de, unsigned int size )
+{
+ return syscall( SYS_getdents64, fd, de, size );
+}
+#define USE_GETDENTS
+#endif
+
+static int is_dir_empty(int fd)
+{
+#ifdef USE_GETDENTS
+ char *name, buffer[8192];
+ KERNEL_DIRENT64 *de;
+ off_t old_pos;
+ int res;
+
+ de = (KERNEL_DIRENT64 *)buffer;
+ if ((old_pos = lseek( fd, 0, SEEK_CUR )) == -1)
+ return 0;
+
+ lseek( fd, 0, SEEK_SET );
+ res = getdents64( fd, buffer, sizeof(buffer) );
+ lseek( fd, old_pos, SEEK_SET );
+ if (res == -1)
+ return 0;
+
+ while (res > 0)
+ {
+ res -= de->d_reclen;
+ name = de->d_name;
+ de = (KERNEL_DIRENT64 *)((char *)de + de->d_reclen);
+ if (!strcmp( name, "." ) || !strcmp( name, ".." ))
+ continue;
+ return 0;
+ }
+ return 1;
+#else
+ return 1;
+#endif
+}
+
/* set disposition for the fd */
static void set_fd_disposition( struct fd *fd, int unlink )
{
@@ -2401,6 +2451,13 @@ static void set_fd_disposition( struct fd *fd, int unlink )
return;
}
+ /* can't remove non-empty directories */
+ if (unlink && S_ISDIR(st.st_mode) && !is_dir_empty(fd->unix_fd))
+ {
+ set_error( STATUS_DIRECTORY_NOT_EMPTY );
+ return;
+ }
+
fd->closed->unlink = unlink ? 1 : 0;
if (fd->options & FILE_DELETE_ON_CLOSE)
fd->closed->unlink = -1;
--
2.17.1
2
2