ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
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
List overview
Download
Ros-diffs
October 2019
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
23 participants
180 discussions
Start a n
N
ew thread
[reactos] 01/01: [DPNHPAST] Sync with Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4188095a3a999bb7e1026…
commit 4188095a3a999bb7e102639c15c46c06696e6b6e Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Oct 26 13:05:19 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Oct 26 13:05:19 2019 +0100 [DPNHPAST] Sync with Wine Staging 4.18. CORE-16441 --- dll/directx/wine/dpnhpast/main.c | 1 - media/doc/README.WINE | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dll/directx/wine/dpnhpast/main.c b/dll/directx/wine/dpnhpast/main.c index 4e46608abda..0fc70cd6c7c 100644 --- a/dll/directx/wine/dpnhpast/main.c +++ b/dll/directx/wine/dpnhpast/main.c @@ -17,7 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include <stdarg.h> #include "windef.h" diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 251a6528d34..97ff756270b 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -35,7 +35,7 @@ dll/directx/wine/dinput8 # Synced to WineStaging-3.3 dll/directx/wine/dmusic # Synced to WineStaging-4.18 dll/directx/wine/dplay # Synced to WineStaging-3.3 dll/directx/wine/dplayx # Synced to WineStaging-4.18 -dll/directx/wine/dpnhpast # Synced to WineStaging-4.5 +dll/directx/wine/dpnhpast # Synced to WineStaging-4.18 dll/directx/wine/dsound # Synced to Wine-1.3.29 dll/directx/wine/dxdiagn # Synced to WineStaging-3.3 dll/directx/wine/msdmo # Synced to WineStaging-3.17
5 years, 1 month
1
0
0
0
[reactos] 01/01: [DPLAYX] Sync with Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=eed824362a80311eceba6…
commit eed824362a80311eceba622adab4fb8d9b2cffe9 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Oct 26 13:04:51 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Oct 26 13:04:51 2019 +0100 [DPLAYX] Sync with Wine Staging 4.18. CORE-16441 --- dll/directx/wine/dplayx/dplay.c | 11 ++++------- dll/directx/wine/dplayx/dplaysp.c | 2 +- dll/directx/wine/dplayx/dplayx_global.c | 25 ++++++++++++------------- dll/directx/wine/dplayx/name_server.c | 1 - media/doc/README.WINE | 2 +- 5 files changed, 18 insertions(+), 23 deletions(-) diff --git a/dll/directx/wine/dplayx/dplay.c b/dll/directx/wine/dplayx/dplay.c index 65c7e4df5d5..e7d6edc6a06 100644 --- a/dll/directx/wine/dplayx/dplay.c +++ b/dll/directx/wine/dplayx/dplay.c @@ -18,8 +18,6 @@ */ #define COBJMACROS -#include "config.h" -#include "wine/port.h" #include <stdarg.h> #include <string.h> @@ -32,7 +30,6 @@ #include "winnt.h" #include "winreg.h" #include "winnls.h" -#include "wine/unicode.h" #include "wine/debug.h" #include "dplayx_global.h" @@ -1440,14 +1437,14 @@ static BOOL DP_CopyDPNAMEStruct( LPDPNAME lpDst, const DPNAME *lpSrc, BOOL bAnsi if( lpSrc->u1.lpszShortNameA ) { lpDst->u1.lpszShortName = HeapAlloc( GetProcessHeap(), 0, - (strlenW(lpSrc->u1.lpszShortName)+1)*sizeof(WCHAR) ); - strcpyW( lpDst->u1.lpszShortName, lpSrc->u1.lpszShortName ); + (lstrlenW(lpSrc->u1.lpszShortName)+1)*sizeof(WCHAR) ); + lstrcpyW( lpDst->u1.lpszShortName, lpSrc->u1.lpszShortName ); } if( lpSrc->u2.lpszLongNameA ) { lpDst->u2.lpszLongName = HeapAlloc( GetProcessHeap(), 0, - (strlenW(lpSrc->u2.lpszLongName)+1)*sizeof(WCHAR) ); - strcpyW( lpDst->u2.lpszLongName, lpSrc->u2.lpszLongName ); + (lstrlenW(lpSrc->u2.lpszLongName)+1)*sizeof(WCHAR) ); + lstrcpyW( lpDst->u2.lpszLongName, lpSrc->u2.lpszLongName ); } } diff --git a/dll/directx/wine/dplayx/dplaysp.c b/dll/directx/wine/dplayx/dplaysp.c index 43938e8511c..53be88e0648 100644 --- a/dll/directx/wine/dplayx/dplaysp.c +++ b/dll/directx/wine/dplayx/dplaysp.c @@ -466,7 +466,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage( IDirectPlaySP *iface, voi { LPDPMSG_CHAT msg = lpMsg; - FIXME( "DPSYS_CHAT not implemeneted\n" ); + FIXME( "DPSYS_CHAT not implemented\n" ); break; } diff --git a/dll/directx/wine/dplayx/dplayx_global.c b/dll/directx/wine/dplayx/dplayx_global.c index bc087c8b33b..a544cd2196e 100644 --- a/dll/directx/wine/dplayx/dplayx_global.c +++ b/dll/directx/wine/dplayx/dplayx_global.c @@ -38,7 +38,6 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" -#include "wine/unicode.h" #include "wingdi.h" #include "winuser.h" @@ -624,18 +623,18 @@ static void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, const DPLCONNECTION *s /* Session names may or may not exist */ if( src->lpSessionDesc->u1.lpszSessionName ) { - strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->u1.lpszSessionName ); + lstrcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->u1.lpszSessionName ); dest->lpSessionDesc->u1.lpszSessionName = (LPWSTR)lpStartOfFreeSpace; lpStartOfFreeSpace += sizeof(WCHAR) * - ( strlenW( dest->lpSessionDesc->u1.lpszSessionName ) + 1 ); + ( lstrlenW( dest->lpSessionDesc->u1.lpszSessionName ) + 1 ); } if( src->lpSessionDesc->u2.lpszPassword ) { - strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->u2.lpszPassword ); + lstrcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->u2.lpszPassword ); dest->lpSessionDesc->u2.lpszPassword = (LPWSTR)lpStartOfFreeSpace; lpStartOfFreeSpace += sizeof(WCHAR) * - ( strlenW( dest->lpSessionDesc->u2.lpszPassword ) + 1 ); + ( lstrlenW( dest->lpSessionDesc->u2.lpszPassword ) + 1 ); } } @@ -648,18 +647,18 @@ static void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, const DPLCONNECTION *s if( src->lpPlayerName->u1.lpszShortName ) { - strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->u1.lpszShortName ); + lstrcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->u1.lpszShortName ); dest->lpPlayerName->u1.lpszShortName = (LPWSTR)lpStartOfFreeSpace; lpStartOfFreeSpace += sizeof(WCHAR) * - ( strlenW( dest->lpPlayerName->u1.lpszShortName ) + 1 ); + ( lstrlenW( dest->lpPlayerName->u1.lpszShortName ) + 1 ); } if( src->lpPlayerName->u2.lpszLongName ) { - strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->u2.lpszLongName ); + lstrcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->u2.lpszLongName ); dest->lpPlayerName->u2.lpszLongName = (LPWSTR)lpStartOfFreeSpace; lpStartOfFreeSpace += sizeof(WCHAR) * - ( strlenW( dest->lpPlayerName->u2.lpszLongName ) + 1 ); + ( lstrlenW( dest->lpPlayerName->u2.lpszLongName ) + 1 ); } } @@ -739,13 +738,13 @@ static DWORD DPLAYX_SizeOfLobbyDataW( const DPLCONNECTION *lpConn ) if( lpConn->lpSessionDesc->u1.lpszSessionName ) { dwTotalSize += sizeof( WCHAR ) * - ( strlenW( lpConn->lpSessionDesc->u1.lpszSessionName ) + 1 ); + ( lstrlenW( lpConn->lpSessionDesc->u1.lpszSessionName ) + 1 ); } if( lpConn->lpSessionDesc->u2.lpszPassword ) { dwTotalSize += sizeof( WCHAR ) * - ( strlenW( lpConn->lpSessionDesc->u2.lpszPassword ) + 1 ); + ( lstrlenW( lpConn->lpSessionDesc->u2.lpszPassword ) + 1 ); } } @@ -756,13 +755,13 @@ static DWORD DPLAYX_SizeOfLobbyDataW( const DPLCONNECTION *lpConn ) if( lpConn->lpPlayerName->u1.lpszShortName ) { dwTotalSize += sizeof( WCHAR ) * - ( strlenW( lpConn->lpPlayerName->u1.lpszShortName ) + 1 ); + ( lstrlenW( lpConn->lpPlayerName->u1.lpszShortName ) + 1 ); } if( lpConn->lpPlayerName->u2.lpszLongName ) { dwTotalSize += sizeof( WCHAR ) * - ( strlenW( lpConn->lpPlayerName->u2.lpszLongName ) + 1 ); + ( lstrlenW( lpConn->lpPlayerName->u2.lpszLongName ) + 1 ); } } diff --git a/dll/directx/wine/dplayx/name_server.c b/dll/directx/wine/dplayx/name_server.c index 7ca1500bfb3..f1ebc4403c1 100644 --- a/dll/directx/wine/dplayx/name_server.c +++ b/dll/directx/wine/dplayx/name_server.c @@ -27,7 +27,6 @@ #include "windef.h" #include "winbase.h" #include "winnls.h" -#include "wine/unicode.h" #include "wine/debug.h" #include "mmsystem.h" diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 847c5e092de..251a6528d34 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -34,7 +34,7 @@ dll/directx/wine/dinput # Synced to WineStaging-4.18 dll/directx/wine/dinput8 # Synced to WineStaging-3.3 dll/directx/wine/dmusic # Synced to WineStaging-4.18 dll/directx/wine/dplay # Synced to WineStaging-3.3 -dll/directx/wine/dplayx # Synced to WineStaging-3.17 +dll/directx/wine/dplayx # Synced to WineStaging-4.18 dll/directx/wine/dpnhpast # Synced to WineStaging-4.5 dll/directx/wine/dsound # Synced to Wine-1.3.29 dll/directx/wine/dxdiagn # Synced to WineStaging-3.3
5 years, 1 month
1
0
0
0
[reactos] 01/01: [DMUSIC] Sync with Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c1cf2ac305eccd9264652…
commit c1cf2ac305eccd926465261c045099bf93f0686f Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Oct 26 13:04:24 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Oct 26 13:04:24 2019 +0100 [DMUSIC] Sync with Wine Staging 4.18. CORE-16441 --- dll/directx/wine/dmusic/collection.c | 10 +-- dll/directx/wine/dmusic/dmusic.c | 147 ++++++++++++++++++++++++++++--- dll/directx/wine/dmusic/dmusic_main.c | 14 +-- dll/directx/wine/dmusic/dmusic_private.h | 6 +- media/doc/README.WINE | 2 +- 5 files changed, 149 insertions(+), 30 deletions(-) diff --git a/dll/directx/wine/dmusic/collection.c b/dll/directx/wine/dmusic/collection.c index 28202228bce..1fddab5c5a3 100644 --- a/dll/directx/wine/dmusic/collection.c +++ b/dll/directx/wine/dmusic/collection.c @@ -155,7 +155,7 @@ static HRESULT WINAPI IDirectMusicCollectionImpl_EnumInstrument(IDirectMusicColl IDirectMusicInstrumentImpl *instrument = impl_from_IDirectMusicInstrument(inst_entry->pInstrument); IDirectMusicInstrument_GetPatch(inst_entry->pInstrument, patch); if (name) { - length = min(strlenW(instrument->wszName), name_length - 1); + length = min(lstrlenW(instrument->wszName), name_length - 1); memcpy(name, instrument->wszName, length * sizeof(WCHAR)); name[length] = '\0'; } @@ -499,13 +499,7 @@ static HRESULT WINAPI IPersistStreamImpl_Load(IPersistStream *iface, struct list *listEntry; TRACE("*** IDirectMusicCollection (%p) ***\n", &This->IDirectMusicCollection_iface); - if (This->dmobj.desc.dwValidData & DMUS_OBJ_OBJECT) - TRACE(" - GUID = %s\n", debugstr_dmguid(&This->dmobj.desc.guidObject)); - if (This->dmobj.desc.dwValidData & DMUS_OBJ_VERSION) - TRACE(" - Version = %i,%i,%i,%i\n", (This->dmobj.desc.vVersion.dwVersionMS >> 8) & 0x0000FFFF, This->dmobj.desc.vVersion.dwVersionMS & 0x0000FFFF, - (This->dmobj.desc.vVersion.dwVersionLS >> 8) & 0x0000FFFF, This->dmobj.desc.vVersion.dwVersionLS & 0x0000FFFF); - if (This->dmobj.desc.dwValidData & DMUS_OBJ_NAME) - TRACE(" - Name = %s\n", debugstr_w(This->dmobj.desc.wszName)); + dump_DMUS_OBJECTDESC(&This->dmobj.desc); TRACE(" - Collection header:\n"); TRACE(" - cInstruments: %d\n", This->pHeader->cInstruments); diff --git a/dll/directx/wine/dmusic/dmusic.c b/dll/directx/wine/dmusic/dmusic.c index fd450b8e360..cc798ce4d92 100644 --- a/dll/directx/wine/dmusic/dmusic.c +++ b/dll/directx/wine/dmusic/dmusic.c @@ -22,9 +22,132 @@ #include <stdio.h> #include "dmusic_private.h" +#include "wine/heap.h" WINE_DEFAULT_DEBUG_CHANNEL(dmusic); +struct master_clock { + IReferenceClock IReferenceClock_iface; + LONG ref; + double freq; + REFERENCE_TIME last_time; +}; + +static inline struct master_clock *impl_from_IReferenceClock(IReferenceClock *iface) +{ + return CONTAINING_RECORD(iface, struct master_clock, IReferenceClock_iface); +} + +static HRESULT WINAPI master_IReferenceClock_QueryInterface(IReferenceClock *iface, REFIID riid, + void **ret_iface) +{ + TRACE("(%p, %s, %p)\n", iface, debugstr_dmguid(riid), ret_iface); + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IReferenceClock)) + *ret_iface = iface; + else { + WARN("no interface for %s\n", debugstr_dmguid(riid)); + *ret_iface = NULL; + return E_NOINTERFACE; + } + + IReferenceClock_AddRef(iface); + + return S_OK; +} + +static ULONG WINAPI master_IReferenceClock_AddRef(IReferenceClock *iface) +{ + struct master_clock *This = impl_from_IReferenceClock(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref = %u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI master_IReferenceClock_Release(IReferenceClock *iface) +{ + struct master_clock *This = impl_from_IReferenceClock(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref = %u\n", iface, ref); + + if (!ref) + heap_free(This); + + return ref; +} + +static HRESULT WINAPI master_IReferenceClock_GetTime(IReferenceClock *iface, + REFERENCE_TIME *time) +{ + struct master_clock *This = impl_from_IReferenceClock(iface); + LARGE_INTEGER counter; + HRESULT hr; + + TRACE("(%p, %p)\n", iface, time); + + QueryPerformanceCounter(&counter); + *time = counter.QuadPart * This->freq; + hr = (*time == This->last_time) ? S_FALSE : S_OK; + This->last_time = *time; + + return hr; +} + +static HRESULT WINAPI master_IReferenceClock_AdviseTime(IReferenceClock *iface, + REFERENCE_TIME base, REFERENCE_TIME offset, HANDLE event, DWORD *cookie) +{ + TRACE("(%p, %s, %s, %p, %p): method not implemented\n", iface, wine_dbgstr_longlong(base), + wine_dbgstr_longlong(offset), event, cookie); + return E_NOTIMPL; +} + +static HRESULT WINAPI master_IReferenceClock_AdvisePeriodic(IReferenceClock *iface, + REFERENCE_TIME start, REFERENCE_TIME period, HANDLE semaphore, DWORD *cookie) +{ + TRACE("(%p, %s, %s, %p, %p): method not implemented\n", iface, wine_dbgstr_longlong(start), + wine_dbgstr_longlong(period), semaphore, cookie); + return E_NOTIMPL; +} + +static HRESULT WINAPI master_IReferenceClock_Unadvise(IReferenceClock *iface, DWORD cookie) +{ + TRACE("(%p, %#x): method not implemented\n", iface, cookie); + return E_NOTIMPL; +} + +static const IReferenceClockVtbl master_clock_vtbl = { + master_IReferenceClock_QueryInterface, + master_IReferenceClock_AddRef, + master_IReferenceClock_Release, + master_IReferenceClock_GetTime, + master_IReferenceClock_AdviseTime, + master_IReferenceClock_AdvisePeriodic, + master_IReferenceClock_Unadvise, +}; + +static HRESULT master_clock_create(IReferenceClock **clock) +{ + struct master_clock *obj; + LARGE_INTEGER freq; + + TRACE("(%p)\n", clock); + + if (!(obj = heap_alloc_zero(sizeof(*obj)))) + return E_OUTOFMEMORY; + + obj->IReferenceClock_iface.lpVtbl = &master_clock_vtbl; + obj->ref = 1; + QueryPerformanceFrequency(&freq); + obj->freq = 10000000.0 / freq.QuadPart; + + *clock = &obj->IReferenceClock_iface; + + return S_OK; +} + static inline IDirectMusic8Impl *impl_from_IDirectMusic8(IDirectMusic8 *iface) { return CONTAINING_RECORD(iface, IDirectMusic8Impl, IDirectMusic8_iface); @@ -72,7 +195,7 @@ static ULONG WINAPI IDirectMusic8Impl_Release(LPDIRECTMUSIC8 iface) TRACE("(%p)->(): new ref = %u\n", This, ref); if (!ref) { - IReferenceClock_Release(&This->master_clock->IReferenceClock_iface); + IReferenceClock_Release(This->master_clock); if (This->dsound) IDirectSound_Release(This->dsound); HeapFree(GetProcessHeap(), 0, This->system_ports); @@ -224,7 +347,7 @@ static HRESULT WINAPI IDirectMusic8Impl_EnumMasterClock(LPDIRECTMUSIC8 iface, DW clock_info->ctType = 0; clock_info->guidClock = guid_system_clock; - strcpyW(clock_info->wszDescription, name_system_clock); + lstrcpyW(clock_info->wszDescription, name_system_clock); } else { @@ -233,7 +356,7 @@ static HRESULT WINAPI IDirectMusic8Impl_EnumMasterClock(LPDIRECTMUSIC8 iface, DW clock_info->ctType = 0; clock_info->guidClock = guid_dsound_clock; - strcpyW(clock_info->wszDescription, name_dsound_clock); + lstrcpyW(clock_info->wszDescription, name_dsound_clock); } return S_OK; @@ -246,9 +369,9 @@ static HRESULT WINAPI IDirectMusic8Impl_GetMasterClock(LPDIRECTMUSIC8 iface, LPG TRACE("(%p)->(%p, %p)\n", This, guid_clock, reference_clock); if (guid_clock) - *guid_clock = This->master_clock->pClockInfo.guidClock; + *guid_clock = GUID_NULL; if (reference_clock) { - *reference_clock = &This->master_clock->IReferenceClock_iface; + *reference_clock = This->master_clock; IReferenceClock_AddRef(*reference_clock); } @@ -418,8 +541,8 @@ static void create_system_ports_list(IDirectMusic8Impl* object) port->device = MIDI_MAPPER; port->create = midi_out_port_create; midiOutGetDevCapsW(MIDI_MAPPER, &caps_out, sizeof(caps_out)); - strcpyW(port->caps.wszDescription, caps_out.szPname); - strcatW(port->caps.wszDescription, emulated); + lstrcpyW(port->caps.wszDescription, caps_out.szPname); + lstrcatW(port->caps.wszDescription, emulated); port->caps.dwFlags = DMUS_PC_SHAREABLE; port->caps.dwClass = DMUS_PC_OUTPUTCLASS; port++; @@ -430,8 +553,8 @@ static void create_system_ports_list(IDirectMusic8Impl* object) port->device = i; port->create = midi_out_port_create; midiOutGetDevCapsW(i, &caps_out, sizeof(caps_out)); - strcpyW(port->caps.wszDescription, caps_out.szPname); - strcatW(port->caps.wszDescription, emulated); + lstrcpyW(port->caps.wszDescription, caps_out.szPname); + lstrcatW(port->caps.wszDescription, emulated); port->caps.dwFlags = DMUS_PC_SHAREABLE | DMUS_PC_EXTERNAL; port->caps.dwClass = DMUS_PC_OUTPUTCLASS; port++; @@ -443,8 +566,8 @@ static void create_system_ports_list(IDirectMusic8Impl* object) port->device = i; port->create = midi_in_port_create; midiInGetDevCapsW(i, &caps_in, sizeof(caps_in)); - strcpyW(port->caps.wszDescription, caps_in.szPname); - strcatW(port->caps.wszDescription, emulated); + lstrcpyW(port->caps.wszDescription, caps_in.szPname); + lstrcatW(port->caps.wszDescription, emulated); port->caps.dwFlags = DMUS_PC_EXTERNAL; port->caps.dwClass = DMUS_PC_INPUTCLASS; port++; @@ -483,7 +606,7 @@ HRESULT WINAPI DMUSIC_CreateDirectMusicImpl(LPCGUID riid, LPVOID* ret_iface, LPU dmusic->IDirectMusic8_iface.lpVtbl = &DirectMusic8_Vtbl; dmusic->ref = 1; - ret = DMUSIC_CreateReferenceClockImpl(&IID_IReferenceClock, (void **)&dmusic->master_clock, NULL); + ret = master_clock_create(&dmusic->master_clock); if (FAILED(ret)) { HeapFree(GetProcessHeap(), 0, dmusic); return ret; diff --git a/dll/directx/wine/dmusic/dmusic_main.c b/dll/directx/wine/dmusic/dmusic_main.c index 7f77095cb6f..2f9016f70ac 100644 --- a/dll/directx/wine/dmusic/dmusic_main.c +++ b/dll/directx/wine/dmusic/dmusic_main.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" #include <stdio.h> #include <stdarg.h> @@ -226,11 +224,13 @@ const char *debugstr_fourcc (DWORD fourcc) { } /* DMUS_VERSION struct to string conversion for debug messages */ -static const char *debugstr_dmversion (const DMUS_VERSION *version) { - if (!version) return "'null'"; - return wine_dbg_sprintf ("\'%i,%i,%i,%i\'", - (int)((version->dwVersionMS & 0xFFFF0000) >> 8), (int)(version->dwVersionMS & 0x0000FFFF), - (int)((version->dwVersionLS & 0xFFFF0000) >> 8), (int)(version->dwVersionLS & 0x0000FFFF)); +static const char *debugstr_dmversion(const DMUS_VERSION *version) +{ + if (!version) + return "'null'"; + return wine_dbg_sprintf("'%hu,%hu,%hu,%hu'", + HIWORD(version->dwVersionMS), LOWORD(version->dwVersionMS), + HIWORD(version->dwVersionLS), LOWORD(version->dwVersionLS)); } /* returns name of given GUID */ diff --git a/dll/directx/wine/dmusic/dmusic_private.h b/dll/directx/wine/dmusic/dmusic_private.h index f9839edfdae..3a62b8727b7 100644 --- a/dll/directx/wine/dmusic/dmusic_private.h +++ b/dll/directx/wine/dmusic/dmusic_private.h @@ -33,10 +33,12 @@ #include "winnt.h" #include "wingdi.h" #include "winuser.h" +#ifdef __REACTOS__ +#include "winnls.h" +#endif #include "wine/debug.h" #include "wine/list.h" -#include "wine/unicode.h" #include "winreg.h" #include "objbase.h" @@ -112,7 +114,7 @@ struct IDirectMusic8Impl { IDirectMusic8 IDirectMusic8_iface; LONG ref; IDirectSound *dsound; - IReferenceClockImpl *master_clock; + IReferenceClock *master_clock; IDirectMusicPort **ports; int num_ports; port_info *system_ports; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 4146f4e260d..847c5e092de 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -32,7 +32,7 @@ dll/directx/wine/ddraw # Synced to WineStaging-3.3 dll/directx/wine/devenum # Synced to WineStaging-4.18 dll/directx/wine/dinput # Synced to WineStaging-4.18 dll/directx/wine/dinput8 # Synced to WineStaging-3.3 -dll/directx/wine/dmusic # Synced to WineStaging-4.0 +dll/directx/wine/dmusic # Synced to WineStaging-4.18 dll/directx/wine/dplay # Synced to WineStaging-3.3 dll/directx/wine/dplayx # Synced to WineStaging-3.17 dll/directx/wine/dpnhpast # Synced to WineStaging-4.5
5 years, 1 month
1
0
0
0
[reactos] 01/01: [DINPUT_WINETEST] Sync with Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8de4fae42b485c63afd07…
commit 8de4fae42b485c63afd071d70ba8af43a99a2ef8 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Oct 26 13:03:59 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Oct 26 13:03:59 2019 +0100 [DINPUT_WINETEST] Sync with Wine Staging 4.18. CORE-16441 --- modules/rostests/winetests/dinput/dinput.c | 78 ++++++++++++++++------------ modules/rostests/winetests/dinput/joystick.c | 63 +++++++++++++++++++++- modules/rostests/winetests/dinput/keyboard.c | 47 +++++++++++++++++ modules/rostests/winetests/dinput/mouse.c | 74 ++++++++++++++++++++++++-- 4 files changed, 223 insertions(+), 39 deletions(-) diff --git a/modules/rostests/winetests/dinput/dinput.c b/modules/rostests/winetests/dinput/dinput.c index cb7268908c5..5947b17468b 100644 --- a/modules/rostests/winetests/dinput/dinput.c +++ b/modules/rostests/winetests/dinput/dinput.c @@ -269,23 +269,19 @@ static void test_QueryInterface(void) &IID_IDirectInput2A, &IID_IDirectInput2W, &IID_IDirectInput7A, &IID_IDirectInput7W}; - static const struct - { - REFIID riid; - int test_todo; - } no_interface_list[] = + static REFIID no_interface_list[] = { - {&IID_IDirectInput8A, 1}, - {&IID_IDirectInput8W, 1}, - {&IID_IDirectInputDeviceA}, - {&IID_IDirectInputDeviceW}, - {&IID_IDirectInputDevice2A}, - {&IID_IDirectInputDevice2W}, - {&IID_IDirectInputDevice7A}, - {&IID_IDirectInputDevice7W}, - {&IID_IDirectInputDevice8A}, - {&IID_IDirectInputDevice8W}, - {&IID_IDirectInputEffect}, + &IID_IDirectInput8A, + &IID_IDirectInput8W, + &IID_IDirectInputDeviceA, + &IID_IDirectInputDeviceW, + &IID_IDirectInputDevice2A, + &IID_IDirectInputDevice2W, + &IID_IDirectInputDevice7A, + &IID_IDirectInputDevice7W, + &IID_IDirectInputDevice8A, + &IID_IDirectInputDevice8W, + &IID_IDirectInputEffect, }; IDirectInputA *pDI; @@ -323,21 +319,9 @@ static void test_QueryInterface(void) for (i = 0; i < ARRAY_SIZE(no_interface_list); i++) { pUnk = (void *)0xdeadbeef; - hr = IDirectInput_QueryInterface(pDI, no_interface_list[i].riid, (void **)&pUnk); - if (no_interface_list[i].test_todo) - { - todo_wine - ok(hr == E_NOINTERFACE, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr); - todo_wine - ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk); - - if (pUnk) IUnknown_Release(pUnk); - } - else - { - ok(hr == E_NOINTERFACE, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr); - ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk); - } + hr = IDirectInput_QueryInterface(pDI, no_interface_list[i], (void **)&pUnk); + ok(hr == E_NOINTERFACE, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr); + ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk); } IDirectInput_Release(pDI); @@ -402,6 +386,30 @@ static BOOL CALLBACK enum_devices_callback(const DIDEVICEINSTANCEA *instance, vo wine_dbgstr_guid(&instance->guidProduct)); } + if ((instance->dwDevType & 0xff) == DIDEVTYPE_KEYBOARD) + ok(IsEqualGUID(&instance->guidProduct, &GUID_SysKeyboard), + "Keyboard guidProduct (%s) does not match GUID_SysKeyboard (%s)\n", + wine_dbgstr_guid(&instance->guidProduct), + wine_dbgstr_guid(&GUID_SysMouse)); + else if ((instance->dwDevType & 0xff) == DIDEVTYPE_MOUSE) + ok(IsEqualGUID(&instance->guidProduct, &GUID_SysMouse), + "Mouse guidProduct (%s) does not match GUID_SysMouse (%s)\n", + wine_dbgstr_guid(&instance->guidProduct), + wine_dbgstr_guid(&GUID_SysMouse)); + else { + /* Non-keyboard/mouse devices use the "PIDVID" guidProduct */ + static const GUID pidvid_product_guid = { /* device_pidvid-0000-0000-0000-504944564944 "PIDVID" */ + 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44} + }; + + ok(instance->guidProduct.Data2 == pidvid_product_guid.Data2, + "guidProduct.Data2 is %04x\n", instance->guidProduct.Data2); + ok(instance->guidProduct.Data3 == pidvid_product_guid.Data3, + "guidProduct.Data3 is %04x\n", instance->guidProduct.Data3); + ok(!memcmp(instance->guidProduct.Data4, pidvid_product_guid.Data4, sizeof(pidvid_product_guid.Data4)), + "guidProduct.Data4 does not match: %s\n", wine_dbgstr_guid(&instance->guidProduct)); + } + enum_test->device_count++; return enum_test->return_value; } @@ -604,10 +612,14 @@ static void test_DirectInputJoyConfig8(void) "IDirectInputJoyConfig8_GetConfig returned 0x%08x\n", hr); if (SUCCEEDED(hr)) - ok (SUCCEEDED(IDirectInput_CreateDevice(pDI, &info.guidInstance, &pDID, NULL)), - "IDirectInput_CreateDevice failed with guid from GetConfig hr = 0x%08x\n", hr); + { + hr = IDirectInput_CreateDevice(pDI, &info.guidInstance, &pDID, NULL); + ok (SUCCEEDED(hr), "IDirectInput_CreateDevice failed with guid from GetConfig hr = 0x%08x\n", hr); + IDirectInputDevice_Release(pDID); + } } + IDirectInputJoyConfig8_Release(pDIJC); IDirectInput_Release(pDI); } diff --git a/modules/rostests/winetests/dinput/joystick.c b/modules/rostests/winetests/dinput/joystick.c index 69e95d0c2db..f009ef347b4 100644 --- a/modules/rostests/winetests/dinput/joystick.c +++ b/modules/rostests/winetests/dinput/joystick.c @@ -270,6 +270,29 @@ static const HRESULT SetCoop_real_window[16] = { E_INVALIDARG, S_OK, S_OK, E_INVALIDARG, E_INVALIDARG, E_INVALIDARG, E_INVALIDARG, E_INVALIDARG}; +static BOOL CALLBACK EnumAllFeedback(const DIDEVICEINSTANCEA *lpddi, void *pvRef) +{ + trace("---- Device Information ----\n" + "Product Name : %s\n" + "Instance Name : %s\n" + "devType : 0x%08x\n" + "GUID Product : %s\n" + "GUID Instance : %s\n" + "HID Page : 0x%04x\n" + "HID Usage : 0x%04x\n", + lpddi->tszProductName, + lpddi->tszInstanceName, + lpddi->dwDevType, + wine_dbgstr_guid(&lpddi->guidProduct), + wine_dbgstr_guid(&lpddi->guidInstance), + lpddi->wUsagePage, + lpddi->wUsage); + + ok(!(IsEqualGUID(&GUID_SysMouse, &lpddi->guidProduct) || IsEqualGUID(&GUID_SysKeyboard, &lpddi->guidProduct)), "Invalid device returned.\n"); + + return DIENUM_CONTINUE; +} + static BOOL CALLBACK EnumJoysticks(const DIDEVICEINSTANCEA *lpddi, void *pvRef) { HRESULT hr; @@ -298,7 +321,7 @@ static BOOL CALLBACK EnumJoysticks(const DIDEVICEINSTANCEA *lpddi, void *pvRef) DIPROPDWORD dip_gain_set, dip_gain_get; struct effect_enum effect_data; - ok(data->version > 0x0300, "Joysticks not supported in version 0x%04x\n", data->version); + ok(data->version >= 0x0300, "Joysticks not supported in version 0x%04x\n", data->version); hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance, NULL, NULL); ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned " @@ -379,7 +402,23 @@ static BOOL CALLBACK EnumJoysticks(const DIDEVICEINSTANCEA *lpddi, void *pvRef) dpg.diph.dwHow = DIPH_DEVICE; hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_GUIDANDPATH, &dpg.diph); - todo_wine ok(SUCCEEDED(hr), "IDirectInput_GetProperty() for DIPROP_GUIDANDPATH failed: %08x\n", hr); + ok(SUCCEEDED(hr), "IDirectInput_GetProperty() for DIPROP_GUIDANDPATH failed: %08x\n", hr); + + { + static const WCHAR formatW[] = {'\\','\\','?','\\','%','*','[','^','#',']','#','v','i','d','_', + '%','0','4','x','&','p','i','d','_','%','0','4','x',0}; + static const WCHAR miW[] = {'m','i','_',0}; + static const WCHAR igW[] = {'i','g','_',0}; + int vid, pid; + + _wcslwr(dpg.wszPath); + count = swscanf(dpg.wszPath, formatW, &vid, &pid); + ok(count == 2, "DIPROP_GUIDANDPATH path has wrong format. Expected count: 2 Got: %i Path: %s\n", + count, wine_dbgstr_w(dpg.wszPath)); + ok(wcsstr(dpg.wszPath, miW) != 0 || wcsstr(dpg.wszPath, igW) != 0, + "DIPROP_GUIDANDPATH path should contain either 'ig_' or 'mi_' substring. Path: %s\n", + wine_dbgstr_w(dpg.wszPath)); + } hr = IDirectInputDevice_SetDataFormat(pJoystick, NULL); ok(hr==E_POINTER,"IDirectInputDevice_SetDataFormat() should have returned " @@ -870,6 +909,24 @@ static void joystick_tests(DWORD version) trace(" Version Not Supported\n"); } +static void test_enum_feedback(void) +{ + HRESULT hr; + IDirectInputA *pDI; + ULONG ref; + HINSTANCE hInstance = GetModuleHandleW(NULL); + + hr = DirectInputCreateA(hInstance, 0x0700, &pDI, NULL); + ok(hr==DI_OK||hr==DIERR_OLDDIRECTINPUTVERSION, "DirectInputCreateA() failed: %08x\n", hr); + if (hr==DI_OK && pDI!=0) { + hr = IDirectInput_EnumDevices(pDI, 0, EnumAllFeedback, NULL, DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK); + ok(hr==DI_OK,"IDirectInput_EnumDevices() failed: %08x\n", hr); + ref = IDirectInput_Release(pDI); + ok(ref==0,"IDirectInput_Release() reference count = %d\n", ref); + } else if (hr==DIERR_OLDDIRECTINPUTVERSION) + trace(" Version Not Supported\n"); +} + START_TEST(joystick) { CoInitialize(NULL); @@ -878,5 +935,7 @@ START_TEST(joystick) joystick_tests(0x0500); joystick_tests(0x0300); + test_enum_feedback(); + CoUninitialize(); } diff --git a/modules/rostests/winetests/dinput/keyboard.c b/modules/rostests/winetests/dinput/keyboard.c index e8dfb4f4843..0e399f021c2 100644 --- a/modules/rostests/winetests/dinput/keyboard.c +++ b/modules/rostests/winetests/dinput/keyboard.c @@ -93,6 +93,7 @@ static void acquire_tests(IDirectInputA *pDI, HWND hwnd) }; DIDATAFORMAT df; HKL hkl, hkl_orig; + UINT prev_raw_devices_count, raw_devices_count; hkl = activate_keyboard_layout(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), &hkl_orig); if (!hkl) return; @@ -165,6 +166,22 @@ static void acquire_tests(IDirectInputA *pDI, HWND hwnd) } keybd_event('Q', 0, KEYEVENTF_KEYUP, 0); + prev_raw_devices_count = 0; + GetRegisteredRawInputDevices(NULL, &prev_raw_devices_count, sizeof(RAWINPUTDEVICE)); + ok(prev_raw_devices_count == 0 || broken(prev_raw_devices_count == 1) /* wxppro, w2003std */, + "Unexpected raw devices registered: %d\n", prev_raw_devices_count); + + hr = IDirectInputDevice_Acquire(pKeyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice_Acquire() failed: %08x\n", hr); + + raw_devices_count = 0; + GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + ok(raw_devices_count == prev_raw_devices_count, + "Unexpected raw devices registered: %d\n", raw_devices_count); + + hr = IDirectInputDevice_Unacquire(pKeyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice_Unacquire() failed: %08x\n", hr); + if (pKeyboard) IUnknown_Release(pKeyboard); ActivateKeyboardLayout(hkl_orig, 0); @@ -453,6 +470,35 @@ fail: IUnknown_Release(device); } +static void test_GetDeviceInfo(IDirectInputA *pDI) +{ + HRESULT hr; + IDirectInputDeviceA *pKey = NULL; + DIDEVICEINSTANCEA instA; + DIDEVICEINSTANCE_DX3A inst3A; + + hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &pKey, NULL); + ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr); + if (FAILED(hr)) return; + + instA.dwSize = sizeof(instA); + hr = IDirectInputDevice_GetDeviceInfo(pKey, &instA); + ok(SUCCEEDED(hr), "got %08x\n", hr); + + inst3A.dwSize = sizeof(inst3A); + hr = IDirectInputDevice_GetDeviceInfo(pKey, (DIDEVICEINSTANCEA *)&inst3A); + ok(SUCCEEDED(hr), "got %08x\n", hr); + + ok(instA.dwSize != inst3A.dwSize, "got %d, %d \n", instA.dwSize, inst3A.dwSize); + ok(IsEqualGUID(&instA.guidInstance, &inst3A.guidInstance), "got %s, %s\n", + wine_dbgstr_guid(&instA.guidInstance), wine_dbgstr_guid(&inst3A.guidInstance) ); + ok(IsEqualGUID(&instA.guidProduct, &inst3A.guidProduct), "got %s, %s\n", + wine_dbgstr_guid(&instA.guidProduct), wine_dbgstr_guid(&inst3A.guidProduct) ); + ok(instA.dwDevType == inst3A.dwDevType, "got %d, %d\n", instA.dwDevType, inst3A.dwDevType); + + IUnknown_Release(pKey); +} + static void keyboard_tests(DWORD version) { HRESULT hr; @@ -483,6 +529,7 @@ static void keyboard_tests(DWORD version) test_set_coop(pDI, hwnd); test_get_prop(pDI, hwnd); test_capabilities(pDI, hwnd); + test_GetDeviceInfo(pDI); test_dik_codes(pDI, hwnd, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)); test_dik_codes(pDI, hwnd, MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH)); diff --git a/modules/rostests/winetests/dinput/mouse.c b/modules/rostests/winetests/dinput/mouse.c index c1a8143d21d..0259cd76a52 100644 --- a/modules/rostests/winetests/dinput/mouse.c +++ b/modules/rostests/winetests/dinput/mouse.c @@ -152,15 +152,20 @@ else { ok(hr == S_OK && cnt > 0, "GetDeviceData() failed: %08x cnt:%d\n", hr, cnt); mouse_event(MOUSEEVENTF_MOVE, 10, 10, 0, 0); - IDirectInputDevice_Unacquire(pMouse); + hr = IDirectInputDevice_Unacquire(pMouse); + ok(hr == S_OK, "Failed: %08x\n", hr); cnt = 1; hr = IDirectInputDevice_GetDeviceData(pMouse, sizeof(mouse_state), &mouse_state, &cnt, 0); ok(hr == S_OK && cnt > 0, "GetDeviceData() failed: %08x cnt:%d\n", hr, cnt); - IDirectInputDevice_Acquire(pMouse); + hr = IDirectInputDevice_Acquire(pMouse); + ok(hr == S_OK, "Failed: %08x\n", hr); mouse_event(MOUSEEVENTF_MOVE, 10, 10, 0, 0); - IDirectInputDevice_Unacquire(pMouse); - IDirectInputDevice_Acquire(pMouse); + hr = IDirectInputDevice_Unacquire(pMouse); + ok(hr == S_OK, "Failed: %08x\n", hr); + + hr = IDirectInputDevice_Acquire(pMouse); + ok(hr == S_OK, "Failed: %08x\n", hr); cnt = 1; hr = IDirectInputDevice_GetDeviceData(pMouse, sizeof(mouse_state), &mouse_state, &cnt, 0); ok(hr == S_OK && cnt > 0, "GetDeviceData() failed: %08x cnt:%d\n", hr, cnt); @@ -202,6 +207,65 @@ else { DestroyWindow( hwnd2 ); } +static void test_GetDeviceInfo(IDirectInputA *pDI) +{ + HRESULT hr; + IDirectInputDeviceA *pMouse = NULL; + DIDEVICEINSTANCEA instA; + DIDEVICEINSTANCE_DX3A inst3A; + + hr = IDirectInput_CreateDevice(pDI, &GUID_SysMouse, &pMouse, NULL); + ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr); + if (FAILED(hr)) return; + + instA.dwSize = sizeof(instA); + hr = IDirectInputDevice_GetDeviceInfo(pMouse, &instA); + ok(SUCCEEDED(hr), "got %08x\n", hr); + + inst3A.dwSize = sizeof(inst3A); + hr = IDirectInputDevice_GetDeviceInfo(pMouse, (DIDEVICEINSTANCEA *)&inst3A); + ok(SUCCEEDED(hr), "got %08x\n", hr); + + ok(instA.dwSize != inst3A.dwSize, "got %d, %d \n", instA.dwSize, inst3A.dwSize); + ok(IsEqualGUID(&instA.guidInstance, &inst3A.guidInstance), "got %s, %s\n", + wine_dbgstr_guid(&instA.guidInstance), wine_dbgstr_guid(&inst3A.guidInstance) ); + ok(IsEqualGUID(&instA.guidProduct, &inst3A.guidProduct), "got %s, %s\n", + wine_dbgstr_guid(&instA.guidProduct), wine_dbgstr_guid(&inst3A.guidProduct) ); + ok(instA.dwDevType == inst3A.dwDevType, "got %d, %d\n", instA.dwDevType, inst3A.dwDevType); + + IUnknown_Release(pMouse); +} + +static BOOL CALLBACK EnumAxes(const DIDEVICEOBJECTINSTANCEA *pdidoi, void *pContext) +{ + if (IsEqualIID(&pdidoi->guidType, &GUID_XAxis) || + IsEqualIID(&pdidoi->guidType, &GUID_YAxis) || + IsEqualIID(&pdidoi->guidType, &GUID_ZAxis)) + { + ok(pdidoi->dwFlags & DIDOI_ASPECTPOSITION, "Missing DIDOI_ASPECTPOSITION, flags are 0x%x\n", + pdidoi->dwFlags); + } + else + ok(pdidoi->dwFlags == 0, "Flags are 0x%x\n", pdidoi->dwFlags); + + return DIENUM_CONTINUE; +} + +static void test_mouse_EnumObjects(IDirectInputA *pDI) +{ + HRESULT hr; + IDirectInputDeviceA *pMouse = NULL; + + hr = IDirectInput_CreateDevice(pDI, &GUID_SysMouse, &pMouse, NULL); + ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr); + if (FAILED(hr)) return; + + hr = IDirectInputDevice_EnumObjects(pMouse, EnumAxes, NULL, DIDFT_ALL); + ok(hr==DI_OK,"IDirectInputDevice_EnumObjects() failed: %08x\n", hr); + + if (pMouse) IUnknown_Release(pMouse); +} + static void mouse_tests(void) { HRESULT hr; @@ -228,6 +292,8 @@ static void mouse_tests(void) test_set_coop(pDI, hwnd); test_acquire(pDI, hwnd); + test_GetDeviceInfo(pDI); + test_mouse_EnumObjects(pDI); DestroyWindow(hwnd); }
5 years, 1 month
1
0
0
0
[reactos] 01/01: [DINPUT] Sync with Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=41c8c312e1a167c179a55…
commit 41c8c312e1a167c179a557a3a435e0bd108b39af Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Oct 26 13:03:34 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Oct 26 13:03:34 2019 +0100 [DINPUT] Sync with Wine Staging 4.18. CORE-16441 --- dll/directx/wine/dinput/CMakeLists.txt | 2 +- dll/directx/wine/dinput/config.c | 203 +++++++++++++------ dll/directx/wine/dinput/device.c | 212 +++++++++++++++----- dll/directx/wine/dinput/device_private.h | 5 + dll/directx/wine/dinput/dinput_main.c | 124 +++++++----- dll/directx/wine/dinput/dinput_private.h | 1 + dll/directx/wine/dinput/effect_linuxinput.c | 6 +- dll/directx/wine/dinput/joystick.c | 271 +++++++++++++++++++------- dll/directx/wine/dinput/joystick_linux.c | 118 ++++++++--- dll/directx/wine/dinput/joystick_linuxinput.c | 255 +++++++++++++++++------- dll/directx/wine/dinput/joystick_osx.c | 116 +++++++++-- dll/directx/wine/dinput/joystick_private.h | 5 + dll/directx/wine/dinput/keyboard.c | 21 +- dll/directx/wine/dinput/mouse.c | 24 ++- dll/directx/wine/dinput/precomp.h | 2 - media/doc/README.WINE | 2 +- 16 files changed, 996 insertions(+), 371 deletions(-) diff --git a/dll/directx/wine/dinput/CMakeLists.txt b/dll/directx/wine/dinput/CMakeLists.txt index 7244903e99f..638312f44b9 100644 --- a/dll/directx/wine/dinput/CMakeLists.txt +++ b/dll/directx/wine/dinput/CMakeLists.txt @@ -1,5 +1,5 @@ -add_definitions(-D__WINESRC__) +add_definitions(-D__WINESRC__ -DDIRECTINPUT_VERSION=0x0700) include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(dinput.dll dinput.spec ADD_IMPORTLIB) diff --git a/dll/directx/wine/dinput/config.c b/dll/directx/wine/dinput/config.c index 885f1f4b8ee..b8a280adac7 100644 --- a/dll/directx/wine/dinput/config.c +++ b/dll/directx/wine/dinput/config.c @@ -18,17 +18,23 @@ #define NONAMELESSUNION + #include "wine/unicode.h" #include "objbase.h" #include "dinput_private.h" #include "device_private.h" #include "resource.h" +#include "wine/heap.h" + typedef struct { int nobjects; IDirectInputDevice8W *lpdid; DIDEVICEINSTANCEW ddi; DIDEVICEOBJECTINSTANCEW ddo[256]; + /* ActionFormat for every user. + * In same order as ConfigureDevicesData usernames */ + DIACTIONFORMATW *user_afs; } DeviceData; typedef struct { @@ -38,10 +44,11 @@ typedef struct { typedef struct { IDirectInput8W *lpDI; - LPDIACTIONFORMATW lpdiaf; LPDIACTIONFORMATW original_lpdiaf; DIDevicesData devices_data; int display_only; + int nusernames; + WCHAR **usernames; } ConfigureDevicesData; /* @@ -57,27 +64,43 @@ static BOOL CALLBACK collect_objects(LPCDIDEVICEOBJECTINSTANCEW lpddo, LPVOID pv return DIENUM_CONTINUE; } -static BOOL CALLBACK count_devices(LPCDIDEVICEINSTANCEW lpddi, IDirectInputDevice8W *lpdid, DWORD dwFlags, DWORD dwRemaining, LPVOID pvRef) +static BOOL CALLBACK collect_devices(LPCDIDEVICEINSTANCEW lpddi, IDirectInputDevice8W *lpdid, DWORD dwFlags, DWORD dwRemaining, LPVOID pvRef) { - DIDevicesData *data = (DIDevicesData*) pvRef; + ConfigureDevicesData *data = (ConfigureDevicesData*) pvRef; + DeviceData *device; + int i, j; - data->ndevices++; - return DIENUM_CONTINUE; -} + IDirectInputDevice_AddRef(lpdid); -static BOOL CALLBACK collect_devices(LPCDIDEVICEINSTANCEW lpddi, IDirectInputDevice8W *lpdid, DWORD dwFlags, DWORD dwRemaining, LPVOID pvRef) -{ - DIDevicesData *data = (DIDevicesData*) pvRef; - DeviceData *device = &data->devices[data->ndevices]; + /* alloc array for devices if this is our first device */ + if (!data->devices_data.ndevices) + data->devices_data.devices = HeapAlloc(GetProcessHeap(), 0, sizeof(DeviceData) * (dwRemaining + 1)); + device = &data->devices_data.devices[data->devices_data.ndevices]; device->lpdid = lpdid; device->ddi = *lpddi; - IDirectInputDevice_AddRef(lpdid); - device->nobjects = 0; IDirectInputDevice_EnumObjects(lpdid, collect_objects, (LPVOID) device, DIDFT_ALL); - data->ndevices++; + device->user_afs = heap_alloc(sizeof(*device->user_afs) * data->nusernames); + memset(device->user_afs, 0, sizeof(*device->user_afs) * data->nusernames); + for (i = 0; i < data->nusernames; i++) + { + DIACTIONFORMATW *user_af = &device->user_afs[i]; + user_af->dwNumActions = data->original_lpdiaf->dwNumActions; + user_af->guidActionMap = data->original_lpdiaf->guidActionMap; + user_af->rgoAction = heap_alloc(sizeof(DIACTIONW) * data->original_lpdiaf->dwNumActions); + memset(user_af->rgoAction, 0, sizeof(DIACTIONW) * data->original_lpdiaf->dwNumActions); + for (j = 0; j < user_af->dwNumActions; j++) + { + user_af->rgoAction[j].dwSemantic = data->original_lpdiaf->rgoAction[j].dwSemantic; + user_af->rgoAction[j].dwFlags = data->original_lpdiaf->rgoAction[j].dwFlags; + user_af->rgoAction[j].u.lptszActionName = data->original_lpdiaf->rgoAction[j].u.lptszActionName; + } + IDirectInputDevice8_BuildActionMap(lpdid, user_af, data->usernames[i], 0); + } + + data->devices_data.ndevices++; return DIENUM_CONTINUE; } @@ -170,10 +193,18 @@ static DeviceData* get_cur_device(HWND dialog) return &data->devices_data.devices[sel]; } -static LPDIACTIONFORMATW get_cur_lpdiaf(HWND dialog) +static DIACTIONFORMATW *get_cur_lpdiaf(HWND dialog) { ConfigureDevicesData *data = (ConfigureDevicesData*) GetWindowLongPtrW(dialog, DWLP_USER); - return data->lpdiaf; + int controller_sel = SendDlgItemMessageW(dialog, IDC_CONTROLLERCOMBO, CB_GETCURSEL, 0, 0); + int player_sel = SendDlgItemMessageW(dialog, IDC_PLAYERCOMBO, CB_GETCURSEL, 0, 0); + return &data->devices_data.devices[controller_sel].user_afs[player_sel]; +} + +static DIACTIONFORMATW *get_original_lpdiaf(HWND dialog) +{ + ConfigureDevicesData *data = (ConfigureDevicesData*) GetWindowLongPtrW(dialog, DWLP_USER); + return data->original_lpdiaf; } static int dialog_display_only(HWND dialog) @@ -182,40 +213,36 @@ static int dialog_display_only(HWND dialog) return data->display_only; } -static void init_devices(HWND dialog, IDirectInput8W *lpDI, DIDevicesData *data, LPDIACTIONFORMATW lpdiaf) +static void init_devices(HWND dialog, ConfigureDevicesData *data) { int i; - /* Count devices */ - data->ndevices = 0; - IDirectInput8_EnumDevicesBySemantics(lpDI, NULL, lpdiaf, count_devices, (LPVOID) data, 0); - - /* Allocate devices */ - data->devices = HeapAlloc(GetProcessHeap(), 0, sizeof(DeviceData) * data->ndevices); - /* Collect and insert */ - data->ndevices = 0; - IDirectInput8_EnumDevicesBySemantics(lpDI, NULL, lpdiaf, collect_devices, (LPVOID) data, 0); + data->devices_data.ndevices = 0; + IDirectInput8_EnumDevicesBySemantics(data->lpDI, NULL, data->original_lpdiaf, collect_devices, (LPVOID) data, 0); - for (i=0; i < data->ndevices; i++) - SendDlgItemMessageW(dialog, IDC_CONTROLLERCOMBO, CB_ADDSTRING, 0, (LPARAM) data->devices[i].ddi.tszProductName ); + for (i = 0; i < data->devices_data.ndevices; i++) + SendDlgItemMessageW(dialog, IDC_CONTROLLERCOMBO, CB_ADDSTRING, 0, (LPARAM) data->devices_data.devices[i].ddi.tszProductName ); + for (i = 0; i < data->nusernames; i++) + SendDlgItemMessageW(dialog, IDC_PLAYERCOMBO, CB_ADDSTRING, 0, (LPARAM) data->usernames[i]); } static void destroy_data(HWND dialog) { - int i; + int i, j; ConfigureDevicesData *data = (ConfigureDevicesData*) GetWindowLongPtrW(dialog, DWLP_USER); DIDevicesData *devices_data = &data->devices_data; /* Free the devices */ for (i=0; i < devices_data->ndevices; i++) + { IDirectInputDevice8_Release(devices_data->devices[i].lpdid); + for (j=0; j < data->nusernames; j++) + heap_free(devices_data->devices[i].user_afs[j].rgoAction); + heap_free(devices_data->devices[i].user_afs); + } HeapFree(GetProcessHeap(), 0, devices_data->devices); - - /* Free the backup LPDIACTIONFORMATW */ - HeapFree(GetProcessHeap(), 0, data->original_lpdiaf->rgoAction); - HeapFree(GetProcessHeap(), 0, data->original_lpdiaf); } static void fill_device_object_list(HWND dialog) @@ -231,6 +258,7 @@ static void fill_device_object_list(HWND dialog) /* Add each object */ for (i=0; i < device->nobjects; i++) { + DWORD ddo_inst, ddo_type; int action = -1; item.mask = LVIF_TEXT | LVIF_PARAM; @@ -241,12 +269,20 @@ static void fill_device_object_list(HWND dialog) /* Add the item */ SendDlgItemMessageW(dialog, IDC_DEVICEOBJECTSLIST, LVM_INSERTITEMW, 0, (LPARAM) &item); + ddo_inst = DIDFT_GETINSTANCE(device->ddo[i].dwType); + ddo_type = DIDFT_GETTYPE(device->ddo[i].dwType); - /* Search for an assigned action for this device */ + /* Search for an assigned action for this device */ for (j=0; j < lpdiaf->dwNumActions; j++) { + DWORD af_inst = DIDFT_GETINSTANCE(lpdiaf->rgoAction[j].dwObjID); + DWORD af_type = DIDFT_GETTYPE(lpdiaf->rgoAction[j].dwObjID); + if (af_type == DIDFT_PSHBUTTON) af_type = DIDFT_BUTTON; + if (af_type == DIDFT_RELAXIS) af_type = DIDFT_AXIS; + /* NOTE previously compared dwType == dwObjId but default buildActionMap actions + * were PSHBUTTON and RELAXS and didnt show up on config */ if (IsEqualGUID(&lpdiaf->rgoAction[j].guidInstance, &device->ddi.guidInstance) && - lpdiaf->rgoAction[j].dwObjID == device->ddo[i].dwType) + ddo_inst == af_inst && ddo_type & af_type) { action = j; break; @@ -260,7 +296,7 @@ static void fill_device_object_list(HWND dialog) static void show_suitable_actions(HWND dialog) { DeviceData *device = get_cur_device(dialog); - LPDIACTIONFORMATW lpdiaf = get_cur_lpdiaf(dialog); + LPDIACTIONFORMATW lpdiaf = get_original_lpdiaf(dialog); int i, added = 0; int obj = lv_get_cur_item(dialog); @@ -298,10 +334,13 @@ static void assign_action(HWND dialog) int obj = lv_get_cur_item(dialog); int old_action = lv_get_item_data(dialog, obj); int used_obj; - - DIDEVICEOBJECTINSTANCEW ddo = device->ddo[obj]; + DWORD type; if (old_action == action) return; + if (obj < 0) return; + if (lpdiaf->rgoAction[old_action].dwFlags & DIA_APPFIXED) return; + + type = device->ddo[obj].dwType; /* Clear old action */ if (old_action != -1) @@ -320,7 +359,7 @@ static void assign_action(HWND dialog) lv_set_action(dialog, used_obj, -1, lpdiaf); /* Set new action */ - lpdiaf->rgoAction[action].dwObjID = ddo.dwType; + lpdiaf->rgoAction[action].dwObjID = type; lpdiaf->rgoAction[action].guidInstance = device->ddi.guidInstance; lpdiaf->rgoAction[action].dwHow = DIAH_USERCONFIG; @@ -328,24 +367,35 @@ static void assign_action(HWND dialog) lv_set_action(dialog, obj, action, lpdiaf); } -static void copy_actions(LPDIACTIONFORMATW to, LPDIACTIONFORMATW from) +static void reset_actions(HWND dialog) { - DWORD i; - for (i=0; i < from->dwNumActions; i++) + ConfigureDevicesData *data = (ConfigureDevicesData*) GetWindowLongPtrW(dialog, DWLP_USER); + DIDevicesData *ddata = (DIDevicesData*) &data->devices_data; + unsigned i, j; + + for (i = 0; i < data->devices_data.ndevices; i++) { - to->rgoAction[i].guidInstance = from->rgoAction[i].guidInstance; - to->rgoAction[i].dwObjID = from->rgoAction[i].dwObjID; - to->rgoAction[i].dwHow = from->rgoAction[i].dwHow; - to->rgoAction[i].u.lptszActionName = from->rgoAction[i].u.lptszActionName; + DeviceData *device = &ddata->devices[i]; + for (j = 0; j < data->nusernames; j++) + IDirectInputDevice8_BuildActionMap(device->lpdid, &device->user_afs[j], data->usernames[j], DIDBAM_HWDEFAULTS); } } -static void reset_actions(HWND dialog) -{ +static void save_actions(HWND dialog) { ConfigureDevicesData *data = (ConfigureDevicesData*) GetWindowLongPtrW(dialog, DWLP_USER); - LPDIACTIONFORMATW to = data->lpdiaf, from = data->original_lpdiaf; - - copy_actions(to, from); + DIDevicesData *ddata = (DIDevicesData*) &data->devices_data; + unsigned i, j; + if (!data->display_only) { + for (i = 0; i < ddata->ndevices; i++) + { + DeviceData *device = &ddata->devices[i]; + for (j = 0; j < data->nusernames; j++) + { + if (save_mapping_settings(device->lpdid, &device->user_afs[j], data->usernames[j]) != DI_OK) + MessageBoxA(dialog, "Could not save settings", 0, MB_ICONERROR); + } + } + } } static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -357,26 +407,27 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM w ConfigureDevicesData *data = (ConfigureDevicesData*) lParam; /* Initialize action format and enumerate devices */ - init_devices(dialog, data->lpDI, &data->devices_data, data->lpdiaf); + init_devices(dialog, data); /* Store information in the window */ SetWindowLongPtrW(dialog, DWLP_USER, (LONG_PTR) data); init_listview_columns(dialog); - /* Create a backup action format for CANCEL and RESET operations */ - data->original_lpdiaf = HeapAlloc(GetProcessHeap(), 0, sizeof(*data->original_lpdiaf)); - data->original_lpdiaf->dwNumActions = data->lpdiaf->dwNumActions; - data->original_lpdiaf->rgoAction = HeapAlloc(GetProcessHeap(), 0, sizeof(DIACTIONW)*data->lpdiaf->dwNumActions); - copy_actions(data->original_lpdiaf, data->lpdiaf); - /* Select the first device and show its actions */ SendDlgItemMessageW(dialog, IDC_CONTROLLERCOMBO, CB_SETCURSEL, 0, 0); + SendDlgItemMessageW(dialog, IDC_PLAYERCOMBO, CB_SETCURSEL, 0, 0); fill_device_object_list(dialog); + ShowCursor(TRUE); + break; } + case WM_DESTROY: + ShowCursor(FALSE); + break; + case WM_NOTIFY: switch (((LPNMHDR)lParam)->code) @@ -407,6 +458,7 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM w break; case IDC_CONTROLLERCOMBO: + case IDC_PLAYERCOMBO: switch (HIWORD(wParam)) { @@ -417,12 +469,12 @@ static INT_PTR CALLBACK ConfigureDevicesDlgProc(HWND dialog, UINT uMsg, WPARAM w break; case IDOK: + save_actions(dialog); EndDialog(dialog, 0); destroy_data(dialog); break; case IDCANCEL: - reset_actions(dialog); EndDialog(dialog, 0); destroy_data(dialog); break; @@ -445,15 +497,48 @@ HRESULT _configure_devices(IDirectInput8W *iface, LPVOID pvRefData ) { + int i; + DWORD size; + WCHAR *username = NULL; ConfigureDevicesData data; data.lpDI = iface; - data.lpdiaf = lpdiCDParams->lprgFormats; + data.original_lpdiaf = lpdiCDParams->lprgFormats; data.display_only = !(dwFlags & DICD_EDIT); + data.nusernames = lpdiCDParams->dwcUsers; + if (lpdiCDParams->lptszUserNames == NULL) + { + /* Get default user name */ + GetUserNameW(NULL, &size); + username = heap_alloc(size * sizeof(WCHAR) ); + GetUserNameW(username, &size); + data.nusernames = 1; + data.usernames = heap_alloc(sizeof(WCHAR *)); + data.usernames[0] = username; + } + else + { + WCHAR *p = lpdiCDParams->lptszUserNames; + data.usernames = heap_alloc(sizeof(WCHAR *) * data.nusernames); + for (i = 0; i < data.nusernames; i++) + { + if (*p) + { + data.usernames[i] = p; + while (*(p++)); + } + else + /* Return if there is an empty string */ + return DIERR_INVALIDPARAM; + } + } InitCommonControls(); DialogBoxParamW(DINPUT_instance, (const WCHAR *)MAKEINTRESOURCE(IDD_CONFIGUREDEVICES), lpdiCDParams->hwnd, ConfigureDevicesDlgProc, (LPARAM)&data); + heap_free(username); + heap_free(data.usernames); + return DI_OK; } diff --git a/dll/directx/wine/dinput/device.c b/dll/directx/wine/dinput/device.c index 6c446163d16..df7a22a303b 100644 --- a/dll/directx/wine/dinput/device.c +++ b/dll/directx/wine/dinput/device.c @@ -30,6 +30,7 @@ #include <string.h> #include "wine/debug.h" #include "wine/unicode.h" +#include "wine/heap.h" #include "windef.h" #include "winbase.h" #include "winreg.h" @@ -643,12 +644,29 @@ static DWORD semantic_to_obj_id(IDirectInputDeviceImpl* This, DWORD dwSemantic) return type | (0x0000ff00 & (obj_instance << 8)); } +static void del_mapping_key(const WCHAR *device, const WCHAR *username, const WCHAR *guid) { + static const WCHAR subkey[] = { + 'S','o','f','t','w','a','r','e','\\', + 'W','i','n','e','\\', + 'D','i','r','e','c','t','I','n','p','u','t','\\', + 'M','a','p','p','i','n','g','s','\\','%','s','\\','%','s','\\','%','s','\0'}; + WCHAR *keyname; + + keyname = heap_alloc(sizeof(WCHAR) * (lstrlenW(subkey) + strlenW(username) + strlenW(device) + strlenW(guid))); + sprintfW(keyname, subkey, username, device, guid); + + /* Remove old key mappings so there will be no overlapping mappings */ + RegDeleteKeyW(HKEY_CURRENT_USER, keyname); + + heap_free(keyname); +} + /* * get_mapping_key * Retrieves an open registry key to save the mapping, parametrized for an username, * specific device and specific action mapping guid. */ -static HKEY get_mapping_key(const WCHAR *device, const WCHAR *username, const WCHAR *guid) +static HKEY get_mapping_key(const WCHAR *device, const WCHAR *username, const WCHAR *guid, BOOL create) { static const WCHAR subkey[] = { 'S','o','f','t','w','a','r','e','\\', @@ -663,15 +681,18 @@ static HKEY get_mapping_key(const WCHAR *device, const WCHAR *username, const WC sprintfW(keyname, subkey, username, device, guid); /* The key used is HKCU\Software\Wine\DirectInput\Mappings\[username]\[device]\[mapping_guid] */ - if (RegCreateKeyW(HKEY_CURRENT_USER, keyname, &hkey)) - hkey = 0; + if (create) { + if (RegCreateKeyW(HKEY_CURRENT_USER, keyname, &hkey)) + hkey = 0; + } else if (RegOpenKeyW(HKEY_CURRENT_USER, keyname, &hkey)) + hkey = 0; HeapFree(GetProcessHeap(), 0, keyname); return hkey; } -static HRESULT save_mapping_settings(IDirectInputDevice8W *iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUsername) +HRESULT save_mapping_settings(IDirectInputDevice8W *iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUsername) { WCHAR *guid_str = NULL; DIDEVICEINSTANCEW didev; @@ -684,7 +705,9 @@ static HRESULT save_mapping_settings(IDirectInputDevice8W *iface, LPDIACTIONFORM if (StringFromCLSID(&lpdiaf->guidActionMap, &guid_str) != S_OK) return DI_SETTINGSNOTSAVED; - hkey = get_mapping_key(didev.tszInstanceName, lpszUsername, guid_str); + del_mapping_key(didev.tszInstanceName, lpszUsername, guid_str); + + hkey = get_mapping_key(didev.tszInstanceName, lpszUsername, guid_str, TRUE); if (!hkey) { @@ -714,12 +737,12 @@ static HRESULT save_mapping_settings(IDirectInputDevice8W *iface, LPDIACTIONFORM return DI_OK; } -static BOOL load_mapping_settings(IDirectInputDeviceImpl *This, LPDIACTIONFORMATW lpdiaf, const WCHAR *username) +BOOL load_mapping_settings(IDirectInputDeviceImpl *This, LPDIACTIONFORMATW lpdiaf, const WCHAR *username) { HKEY hkey; WCHAR *guid_str; DIDEVICEINSTANCEW didev; - int i, mapped = 0; + int i; didev.dwSize = sizeof(didev); IDirectInputDevice8_GetDeviceInfo(&This->IDirectInputDevice8W_iface, &didev); @@ -727,7 +750,7 @@ static BOOL load_mapping_settings(IDirectInputDeviceImpl *This, LPDIACTIONFORMAT if (StringFromCLSID(&lpdiaf->guidActionMap, &guid_str) != S_OK) return FALSE; - hkey = get_mapping_key(didev.tszInstanceName, username, guid_str); + hkey = get_mapping_key(didev.tszInstanceName, username, guid_str, FALSE); if (!hkey) { @@ -748,15 +771,21 @@ static BOOL load_mapping_settings(IDirectInputDeviceImpl *This, LPDIACTIONFORMAT { lpdiaf->rgoAction[i].dwObjID = id; lpdiaf->rgoAction[i].guidInstance = didev.guidInstance; - lpdiaf->rgoAction[i].dwHow = DIAH_DEFAULT; - mapped += 1; + lpdiaf->rgoAction[i].dwHow = DIAH_USERCONFIG; + } + else + { + memset(&lpdiaf->rgoAction[i].guidInstance, 0, sizeof(GUID)); + lpdiaf->rgoAction[i].dwHow = DIAH_UNMAPPED; } + } RegCloseKey(hkey); CoTaskMemFree(guid_str); - return mapped > 0; + /* On Windows BuildActionMap can open empty mapping, so always return TRUE if get_mapping_key is success */ + return TRUE; } HRESULT _build_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags, DWORD devMask, LPCDIDATAFORMAT df) @@ -779,13 +808,18 @@ HRESULT _build_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, load_success = load_mapping_settings(This, lpdiaf, username); } - if (load_success) return DI_OK; + if (load_success) { + /* Update dwCRC to track if action format has changed */ + for (i=0; i < lpdiaf->dwNumActions; i++) + { + lpdiaf->dwCRC ^= (lpdiaf->rgoAction[i].dwObjID << i * 2) | (lpdiaf->rgoAction[i].dwObjID >> (sizeof(lpdiaf->dwCRC) * 8 - i * 2)); + lpdiaf->dwCRC ^= (lpdiaf->rgoAction[i].dwSemantic << (i * 2 + 5)) | (lpdiaf->rgoAction[i].dwSemantic >> (sizeof(lpdiaf->dwCRC) * 8 - (i * 2 + 5))); + } + return DI_OK; + } for (i=0; i < lpdiaf->dwNumActions; i++) { - /* Don't touch a user configured action */ - if (lpdiaf->rgoAction[i].dwHow == DIAH_USERCONFIG) continue; - if ((lpdiaf->rgoAction[i].dwSemantic & devMask) == devMask) { DWORD obj_id = semantic_to_obj_id(This, lpdiaf->rgoAction[i].dwSemantic); @@ -816,6 +850,14 @@ HRESULT _build_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, } } + /* Update dwCRC to track if action format has changed */ + lpdiaf->dwCRC = 0; + for (i=0; i < lpdiaf->dwNumActions; i++) + { + lpdiaf->dwCRC ^= (lpdiaf->rgoAction[i].dwObjID << i * 2) | (lpdiaf->rgoAction[i].dwObjID >> (sizeof(lpdiaf->dwCRC) * 8 - i * 2)); + lpdiaf->dwCRC ^= (lpdiaf->rgoAction[i].dwSemantic << (i * 2 + 5)) | (lpdiaf->rgoAction[i].dwSemantic >> (sizeof(lpdiaf->dwCRC) * 8 - (i * 2 + 5))); + } + if (!has_actions) return DI_NOEFFECT; return IDirectInputDevice8WImpl_BuildActionMap(iface, lpdiaf, lpszUserName, dwFlags); @@ -831,6 +873,7 @@ HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, L DIPROPSTRING dps; WCHAR username[MAX_PATH]; DWORD username_size = MAX_PATH; + DWORD new_crc = 0; int i, action = 0, num_actions = 0; unsigned int offset = 0; @@ -841,12 +884,30 @@ HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, L data_format.dwFlags = DIDF_RELAXIS; data_format.dwDataSize = lpdiaf->dwDataSize; + /* Calculate checksum for actionformat */ + for (i=0; i < lpdiaf->dwNumActions; i++) + { + new_crc ^= (lpdiaf->rgoAction[i].dwObjID << i * 2) | (lpdiaf->rgoAction[i].dwObjID >> (sizeof(lpdiaf->dwCRC) * 8 - i * 2)); + new_crc ^= (lpdiaf->rgoAction[i].dwSemantic << (i * 2 + 5)) | (lpdiaf->rgoAction[i].dwSemantic >> (sizeof(lpdiaf->dwCRC) * 8 - (i * 2 + 5))); + } + /* Count the actions */ for (i=0; i < lpdiaf->dwNumActions; i++) - if (IsEqualGUID(&This->guid, &lpdiaf->rgoAction[i].guidInstance)) + { + if (IsEqualGUID(&This->guid, &lpdiaf->rgoAction[i].guidInstance) || + (IsEqualGUID(&IID_NULL, &lpdiaf->rgoAction[i].guidInstance) && + ((lpdiaf->rgoAction[i].dwSemantic & lpdiaf->dwGenre) == lpdiaf->dwGenre || + (lpdiaf->rgoAction[i].dwSemantic & 0xff000000) == 0xff000000 /* Any Axis */) )) + { num_actions++; + } + } - if (num_actions == 0) return DI_NOEFFECT; + /* Should return DI_NOEFFECT if we dont have any actions and actionformat has not changed */ + if (num_actions == 0 && lpdiaf->dwCRC == new_crc && !(dwFlags & DIDSAM_FORCESAVE)) return DI_NOEFFECT; + + /* update dwCRC to track if action format has changed */ + lpdiaf->dwCRC = new_crc; This->num_actions = num_actions; @@ -880,7 +941,39 @@ HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, L action++; } + else if ((lpdiaf->rgoAction[i].dwSemantic & lpdiaf->dwGenre) == lpdiaf->dwGenre || + (lpdiaf->rgoAction[i].dwSemantic & 0xff000000) == 0xff000000 /* Any Axis */) + { + DWORD obj_id = semantic_to_obj_id(This, lpdiaf->rgoAction[i].dwSemantic); + DWORD type = DIDFT_GETTYPE(obj_id); + DWORD inst = DIDFT_GETINSTANCE(obj_id); + LPDIOBJECTDATAFORMAT obj; + + if (type == DIDFT_PSHBUTTON) type = DIDFT_BUTTON; + else if (type == DIDFT_RELAXIS) type = DIDFT_AXIS; + + obj = dataformat_to_odf_by_type(df, inst, type); + TRACE("obj %p, inst 0x%08x, type 0x%08x\n", obj, inst, type); + if(obj) + { + memcpy(&obj_df[action], obj, df->dwObjSize); + + This->action_map[action].uAppData = lpdiaf->rgoAction[i].uAppData; + This->action_map[action].offset = offset; + obj_df[action].dwOfs = offset; + offset += (type & DIDFT_BUTTON) ? 1 : 4; + + action++; + } + } + } + + if (action == 0) + { + HeapFree(GetProcessHeap(), 0, obj_df); + return DI_NOEFFECT; } + data_format.dwNumObjs = action; IDirectInputDevice8_SetDataFormat(iface, &data_format); @@ -1140,7 +1233,7 @@ ULONG WINAPI IDirectInputDevice2WImpl_Release(LPDIRECTINPUTDEVICE8W iface) IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); ULONG ref = InterlockedDecrement(&(This->ref)); - TRACE("(%p) releasing from %d\n", This, ref + 1); + TRACE("(%p) ref %d\n", This, ref); if (ref) return ref; @@ -1168,7 +1261,7 @@ ULONG WINAPI IDirectInputDevice2WImpl_Release(LPDIRECTINPUTDEVICE8W iface) HeapFree(GetProcessHeap(), 0, This); - return DI_OK; + return ref; } ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface) @@ -1181,7 +1274,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_QueryInterface(LPDIRECTINPUTDEVICE8W ifa { IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); - TRACE("(%p this=%p,%s,%p)\n", iface, This, debugstr_guid(riid), ppobj); + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppobj); if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IDirectInputDeviceA, riid) || IsEqualGUID(&IID_IDirectInputDevice2A, riid) || @@ -1203,7 +1296,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_QueryInterface(LPDIRECTINPUTDEVICE8W ifa } WARN("Unsupported interface!\n"); - return E_FAIL; + return E_NOINTERFACE; } HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(LPDIRECTINPUTDEVICE8A iface, REFIID riid, LPVOID *ppobj) @@ -1215,7 +1308,9 @@ HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(LPDIRECTINPUTDEVICE8A ifa ULONG WINAPI IDirectInputDevice2WImpl_AddRef(LPDIRECTINPUTDEVICE8W iface) { IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); - return InterlockedIncrement(&This->ref); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE( "(%p) ref %d\n", This, ref ); + return ref; } ULONG WINAPI IDirectInputDevice2AImpl_AddRef(LPDIRECTINPUTDEVICE8A iface) @@ -1231,7 +1326,7 @@ HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(LPDIRECTINPUTDEVICE8A iface, DIDEVICEOBJECTINSTANCEA ddoi; int i; - TRACE("(%p) %p,%p flags:%08x)\n", iface, lpCallback, lpvRef, dwFlags); + TRACE("(%p)->(%p,%p flags:%08x)\n", This, lpCallback, lpvRef, dwFlags); TRACE(" - flags = "); _dump_EnumObjects_flags(dwFlags); TRACE("\n"); @@ -1261,7 +1356,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects(LPDIRECTINPUTDEVICE8W iface, DIDEVICEOBJECTINSTANCEW ddoi; int i; - TRACE("(%p) %p,%p flags:%08x)\n", iface, lpCallback, lpvRef, dwFlags); + TRACE("(%p)->(%p,%p flags:%08x)\n", This, lpCallback, lpvRef, dwFlags); TRACE(" - flags = "); _dump_EnumObjects_flags(dwFlags); TRACE("\n"); @@ -1292,7 +1387,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, { IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); - TRACE("(%p) %s,%p\n", iface, debugstr_guid(rguid), pdiph); + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph); _dump_DIPROPHEADER(pdiph); if (!IS_DIPROP(rguid)) return DI_OK; @@ -1357,7 +1452,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty( { IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); - TRACE("(%p) %s,%p\n", iface, debugstr_guid(rguid), pdiph); + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph); _dump_DIPROPHEADER(pdiph); if (!IS_DIPROP(rguid)) return DI_OK; @@ -1596,7 +1691,8 @@ HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A ifac HRESULT WINAPI IDirectInputDevice2WImpl_RunControlPanel(LPDIRECTINPUTDEVICE8W iface, HWND hwndOwner, DWORD dwFlags) { - FIXME("(this=%p,%p,0x%08x): stub!\n", iface, hwndOwner, dwFlags); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("%p)->(%p,0x%08x): stub!\n", This, hwndOwner, dwFlags); return DI_OK; } @@ -1610,7 +1706,8 @@ HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(LPDIRECTINPUTDEVICE8A if HRESULT WINAPI IDirectInputDevice2WImpl_Initialize(LPDIRECTINPUTDEVICE8W iface, HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) { - FIXME("(this=%p,%p,%d,%s): stub!\n", iface, hinst, dwVersion, debugstr_guid(rguid)); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%p,%d,%s): stub!\n", This, hinst, dwVersion, debugstr_guid(rguid)); return DI_OK; } @@ -1628,7 +1725,8 @@ HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(LPDIRECTINPUTDEVICE8A iface, HRESULT WINAPI IDirectInputDevice2WImpl_CreateEffect(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdef, LPUNKNOWN pUnkOuter) { - FIXME("(this=%p,%s,%p,%p,%p): stub!\n", iface, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%s,%p,%p,%p): stub!\n", This, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter); FIXME("not available in the generic implementation\n"); *ppdef = NULL; @@ -1648,9 +1746,9 @@ HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects( LPVOID lpvRef, DWORD dwFlags) { - FIXME("(this=%p,%p,%p,0x%08x): stub!\n", - iface, lpCallback, lpvRef, dwFlags); - + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface); + FIXME("%p)->(%p,%p,0x%08x): stub!\n", This, lpCallback, lpvRef, dwFlags); + return DI_OK; } @@ -1660,9 +1758,9 @@ HRESULT WINAPI IDirectInputDevice2WImpl_EnumEffects( LPVOID lpvRef, DWORD dwFlags) { - FIXME("(this=%p,%p,%p,0x%08x): stub!\n", - iface, lpCallback, lpvRef, dwFlags); - + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%p,%p,0x%08x): stub!\n", This, lpCallback, lpvRef, dwFlags); + return DI_OK; } @@ -1671,8 +1769,8 @@ HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo( LPDIEFFECTINFOA lpdei, REFGUID rguid) { - FIXME("(this=%p,%p,%s): stub!\n", - iface, lpdei, debugstr_guid(rguid)); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface); + FIXME("(%p)->(%p,%s): stub!\n", This, lpdei, debugstr_guid(rguid)); return DI_OK; } @@ -1681,14 +1779,15 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetEffectInfo( LPDIEFFECTINFOW lpdei, REFGUID rguid) { - FIXME("(this=%p,%p,%s): stub!\n", - iface, lpdei, debugstr_guid(rguid)); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%p,%s): stub!\n", This, lpdei, debugstr_guid(rguid)); return DI_OK; } HRESULT WINAPI IDirectInputDevice2WImpl_GetForceFeedbackState(LPDIRECTINPUTDEVICE8W iface, LPDWORD pdwOut) { - FIXME("(this=%p,%p): stub!\n", iface, pdwOut); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%p): stub!\n", This, pdwOut); return DI_OK; } @@ -1700,7 +1799,8 @@ HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(LPDIRECTINPUTDEVIC HRESULT WINAPI IDirectInputDevice2WImpl_SendForceFeedbackCommand(LPDIRECTINPUTDEVICE8W iface, DWORD dwFlags) { - TRACE("(%p) 0x%08x:\n", iface, dwFlags); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + TRACE("(%p)->(0x%08x)\n", This, dwFlags); return DI_NOEFFECT; } @@ -1713,7 +1813,8 @@ HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(LPDIRECTINPUTDE HRESULT WINAPI IDirectInputDevice2WImpl_EnumCreatedEffectObjects(LPDIRECTINPUTDEVICE8W iface, LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID lpvRef, DWORD dwFlags) { - FIXME("(this=%p,%p,%p,0x%08x): stub!\n", iface, lpCallback, lpvRef, dwFlags); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)0>(%p,%p,0x%08x): stub!\n", This, lpCallback, lpvRef, dwFlags); return DI_OK; } @@ -1726,7 +1827,8 @@ HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(LPDIRECTINPUTDE HRESULT WINAPI IDirectInputDevice2WImpl_Escape(LPDIRECTINPUTDEVICE8W iface, LPDIEFFESCAPE lpDIEEsc) { - FIXME("(this=%p,%p): stub!\n", iface, lpDIEEsc); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%p): stub!\n", This, lpDIEEsc); return DI_OK; } @@ -1756,7 +1858,8 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SendDeviceData(LPDIRECTINPUTDEVICE8W ifa LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) { - FIXME("(this=%p,0x%08x,%p,%p,0x%08x): stub!\n", iface, cbObjectData, rgdod, pdwInOut, dwFlags); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(0x%08x,%p,%p,0x%08x): stub!\n", This, cbObjectData, rgdod, pdwInOut, dwFlags); return DI_OK; } @@ -1776,7 +1879,8 @@ HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8A LPVOID pvRef, DWORD dwFlags) { - FIXME("(%p)->(%s,%p,%p,%08x): stub !\n", iface, lpszFileName, pec, pvRef, dwFlags); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface); + FIXME("(%p)->(%s,%p,%p,%08x): stub !\n", This, lpszFileName, pec, pvRef, dwFlags); return DI_OK; } @@ -1787,7 +1891,8 @@ HRESULT WINAPI IDirectInputDevice7WImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8W LPVOID pvRef, DWORD dwFlags) { - FIXME("(%p)->(%s,%p,%p,%08x): stub !\n", iface, debugstr_w(lpszFileName), pec, pvRef, dwFlags); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%s,%p,%p,%08x): stub !\n", This, debugstr_w(lpszFileName), pec, pvRef, dwFlags); return DI_OK; } @@ -1798,7 +1903,8 @@ HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8A LPDIFILEEFFECT rgDiFileEft, DWORD dwFlags) { - FIXME("(%p)->(%s,%08x,%p,%08x): stub !\n", iface, lpszFileName, dwEntries, rgDiFileEft, dwFlags); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface); + FIXME("(%p)->(%s,%08x,%p,%08x): stub !\n", This, lpszFileName, dwEntries, rgDiFileEft, dwFlags); return DI_OK; } @@ -1809,7 +1915,8 @@ HRESULT WINAPI IDirectInputDevice7WImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8W LPDIFILEEFFECT rgDiFileEft, DWORD dwFlags) { - FIXME("(%p)->(%s,%08x,%p,%08x): stub !\n", iface, debugstr_w(lpszFileName), dwEntries, rgDiFileEft, dwFlags); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%s,%08x,%p,%08x): stub !\n", This, debugstr_w(lpszFileName), dwEntries, rgDiFileEft, dwFlags); return DI_OK; } @@ -1819,7 +1926,8 @@ HRESULT WINAPI IDirectInputDevice8WImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W ifa LPCWSTR lpszUserName, DWORD dwFlags) { - FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", This, lpdiaf, debugstr_w(lpszUserName), dwFlags); #define X(x) if (dwFlags & x) FIXME("\tdwFlags =|"#x"\n"); X(DIDBAM_DEFAULT) X(DIDBAM_PRESERVE) @@ -1833,7 +1941,8 @@ HRESULT WINAPI IDirectInputDevice8WImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W ifa HRESULT WINAPI IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface, LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader) { - FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8A(iface); + FIXME("(%p)->(%p): stub !\n", This, lpdiDevImageInfoHeader); return DI_OK; } @@ -1841,7 +1950,8 @@ HRESULT WINAPI IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface HRESULT WINAPI IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader) { - FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader); + IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%p): stub !\n", This, lpdiDevImageInfoHeader); return DI_OK; } diff --git a/dll/directx/wine/dinput/device_private.h b/dll/directx/wine/dinput/device_private.h index d9e2997eaaf..114e3971ed8 100644 --- a/dll/directx/wine/dinput/device_private.h +++ b/dll/directx/wine/dinput/device_private.h @@ -114,6 +114,8 @@ typedef struct LPDIRECTINPUTEFFECT ref; } effect_list_item; +extern const GUID DInput_PIDVID_Product_GUID DECLSPEC_HIDDEN; + /* Various debug tools */ extern void _dump_DIPROPHEADER(LPCDIPROPHEADER diph) DECLSPEC_HIDDEN; extern void _dump_OBJECTINSTANCEA(const DIDEVICEOBJECTINSTANCEA *ddoi) DECLSPEC_HIDDEN; @@ -123,6 +125,9 @@ extern const char *_dump_dinput_GUID(const GUID *guid) DECLSPEC_HIDDEN; extern LPDIOBJECTDATAFORMAT dataformat_to_odf_by_type(LPCDIDATAFORMAT df, int n, DWORD type) DECLSPEC_HIDDEN; +extern HRESULT save_mapping_settings(IDirectInputDevice8W *iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUsername) DECLSPEC_HIDDEN; +extern BOOL load_mapping_settings(IDirectInputDeviceImpl *This, LPDIACTIONFORMATW lpdiaf, const WCHAR *username) DECLSPEC_HIDDEN; + extern HRESULT _build_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags, DWORD devMask, LPCDIDATAFORMAT df) DECLSPEC_HIDDEN; extern HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags, LPCDIDATAFORMAT df) DECLSPEC_HIDDEN; diff --git a/dll/directx/wine/dinput/dinput_main.c b/dll/directx/wine/dinput/dinput_main.c index 4b058891d93..645d29dfd87 100644 --- a/dll/directx/wine/dinput/dinput_main.c +++ b/dll/directx/wine/dinput/dinput_main.c @@ -30,7 +30,6 @@ * - Fallout : works great in X and DGA mode */ -#include "config.h" #include <assert.h> #include <stdarg.h> #include <string.h> @@ -39,7 +38,9 @@ #define NONAMELESSUNION #include "wine/debug.h" +#include "wine/heap.h" #include "wine/unicode.h" +#include "wine/asm.h" #include "windef.h" #include "winbase.h" #include "winuser.h" @@ -47,6 +48,7 @@ #include "objbase.h" #include "rpcproxy.h" #include "initguid.h" +#include "devguid.h" #include "dinput_private.h" #include "device_private.h" #include "dinputd.h" @@ -289,6 +291,20 @@ static void _dump_EnumDevices_dwFlags(DWORD dwFlags) TRACE("\n"); } +static const char *dump_semantic(DWORD semantic) +{ + if((semantic & 0xff000000) == 0xff000000) + return "Any AXIS"; + else if((semantic & 0x82000000) == 0x82000000) + return "Mouse"; + else if((semantic & 0x81000000) == 0x81000000) + return "Keybaord"; + else if((semantic & DIVIRTUAL_FLYING_HELICOPTER) == DIVIRTUAL_FLYING_HELICOPTER) + return "Helicopter"; + + return "Unknown"; +} + static void _dump_diactionformatA(LPDIACTIONFORMATA lpdiActionFormat) { unsigned int i; @@ -311,7 +327,7 @@ static void _dump_diactionformatA(LPDIACTIONFORMATA lpdiActionFormat) { TRACE("diaf.rgoAction[%u]:\n", i); TRACE("\tuAppData=0x%lx\n", lpdiActionFormat->rgoAction[i].uAppData); - TRACE("\tdwSemantic=0x%08x\n", lpdiActionFormat->rgoAction[i].dwSemantic); + TRACE("\tdwSemantic=0x%08x (%s)\n", lpdiActionFormat->rgoAction[i].dwSemantic, dump_semantic(lpdiActionFormat->rgoAction[i].dwSemantic)); TRACE("\tdwFlags=0x%x\n", lpdiActionFormat->rgoAction[i].dwFlags); TRACE("\tszActionName=%s\n", debugstr_a(lpdiActionFormat->rgoAction[i].u.lptszActionName)); TRACE("\tguidInstance=%s\n", debugstr_guid(&lpdiActionFormat->rgoAction[i].guidInstance)); @@ -467,9 +483,10 @@ static HRESULT WINAPI IDirectInputAImpl_EnumDevices( for (i = 0; i < ARRAY_SIZE(dinput_devices); i++) { if (!dinput_devices[i]->enum_deviceA) continue; + + TRACE(" Checking device %u ('%s')\n", i, dinput_devices[i]->name); for (j = 0, r = S_OK; SUCCEEDED(r); j++) { devInstance.dwSize = sizeof(devInstance); - TRACE(" - checking device %u ('%s')\n", i, dinput_devices[i]->name); r = dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->dwVersion, j); if (r == S_OK) if (enum_callback_wrapper(lpCallback, &devInstance, pvRef) == DIENUM_STOP) @@ -525,7 +542,7 @@ static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUT7A iface) IDirectInputImpl *This = impl_from_IDirectInput7A( iface ); ULONG ref = InterlockedIncrement(&This->ref); - TRACE( "(%p) incrementing from %d\n", This, ref - 1); + TRACE( "(%p) ref %d\n", This, ref ); return ref; } @@ -540,7 +557,7 @@ static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUT7A iface) IDirectInputImpl *This = impl_from_IDirectInput7A( iface ); ULONG ref = InterlockedDecrement( &This->ref ); - TRACE( "(%p) releasing from %d\n", This, ref + 1 ); + TRACE( "(%p) ref %d\n", This, ref ); if (ref == 0) { @@ -566,53 +583,39 @@ static HRESULT WINAPI IDirectInputAImpl_QueryInterface(LPDIRECTINPUT7A iface, RE if (!riid || !ppobj) return E_POINTER; + *ppobj = NULL; + +#if DIRECTINPUT_VERSION == 0x0700 if (IsEqualGUID( &IID_IUnknown, riid ) || - IsEqualGUID( &IID_IDirectInputA, riid ) || - IsEqualGUID( &IID_IDirectInput2A, riid ) || - IsEqualGUID( &IID_IDirectInput7A, riid )) - { + IsEqualGUID( &IID_IDirectInputA, riid ) || + IsEqualGUID( &IID_IDirectInput2A, riid ) || + IsEqualGUID( &IID_IDirectInput7A, riid )) *ppobj = &This->IDirectInput7A_iface; - IUnknown_AddRef( (IUnknown*)*ppobj ); - - return DI_OK; - } - - if (IsEqualGUID( &IID_IDirectInputW, riid ) || - IsEqualGUID( &IID_IDirectInput2W, riid ) || - IsEqualGUID( &IID_IDirectInput7W, riid )) - { + else if (IsEqualGUID( &IID_IDirectInputW, riid ) || + IsEqualGUID( &IID_IDirectInput2W, riid ) || + IsEqualGUID( &IID_IDirectInput7W, riid )) *ppobj = &This->IDirectInput7W_iface; - IUnknown_AddRef( (IUnknown*)*ppobj ); - - return DI_OK; - } - if (IsEqualGUID( &IID_IDirectInput8A, riid )) - { +#else + if (IsEqualGUID( &IID_IUnknown, riid ) || + IsEqualGUID( &IID_IDirectInput8A, riid )) *ppobj = &This->IDirectInput8A_iface; - IUnknown_AddRef( (IUnknown*)*ppobj ); - - return DI_OK; - } - if (IsEqualGUID( &IID_IDirectInput8W, riid )) - { + else if (IsEqualGUID( &IID_IDirectInput8W, riid )) *ppobj = &This->IDirectInput8W_iface; - IUnknown_AddRef( (IUnknown*)*ppobj ); - return DI_OK; - } +#endif if (IsEqualGUID( &IID_IDirectInputJoyConfig8, riid )) - { *ppobj = &This->IDirectInputJoyConfig8_iface; - IUnknown_AddRef( (IUnknown*)*ppobj ); + if(*ppobj) + { + IUnknown_AddRef( (IUnknown*)*ppobj ); return DI_OK; } - FIXME( "Unsupported interface: %s\n", debugstr_guid(riid)); - *ppobj = NULL; + WARN( "Unsupported interface: %s\n", debugstr_guid(riid)); return E_NOINTERFACE; } @@ -690,7 +693,7 @@ static HRESULT WINAPI IDirectInputAImpl_Initialize(LPDIRECTINPUT7A iface, HINSTA { IDirectInputImpl *This = impl_from_IDirectInput7A( iface ); - TRACE("(%p)->(%p, 0x%04x)\n", iface, hinst, version); + TRACE("(%p)->(%p, 0x%04x)\n", This, hinst, version); if (!hinst) return DIERR_INVALIDPARAM; @@ -947,7 +950,7 @@ static HRESULT WINAPI IDirectInput8AImpl_Initialize(LPDIRECTINPUT8A iface, HINST { IDirectInputImpl *This = impl_from_IDirectInput8A( iface ); - TRACE("(%p)->(%p, 0x%04x)\n", iface, hinst, version); + TRACE("(%p)->(%p, 0x%04x)\n", This, hinst, version); if (!hinst) return DIERR_INVALIDPARAM; @@ -1104,10 +1107,12 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics( if (lpCallback(&didevis[i], lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP) { + IDirectInputDevice_Release(lpdid); HeapFree(GetProcessHeap(), 0, didevis); HeapFree(GetProcessHeap(), 0, username_w); return DI_OK; } + IDirectInputDevice_Release(lpdid); } HeapFree(GetProcessHeap(), 0, didevis); @@ -1130,9 +1135,11 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics( if (lpCallback(&didevi, lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP) { + IDirectInputDevice_Release(lpdid); HeapFree(GetProcessHeap(), 0, username_w); return DI_OK; } + IDirectInputDevice_Release(lpdid); } } @@ -1260,9 +1267,34 @@ static HRESULT WINAPI IDirectInput8AImpl_ConfigureDevices( /* Copy parameters */ diCDParamsW.dwSize = sizeof(DICONFIGUREDEVICESPARAMSW); + diCDParamsW.dwcUsers = lpdiCDParams->dwcUsers; diCDParamsW.dwcFormats = lpdiCDParams->dwcFormats; diCDParamsW.lprgFormats = &diafW; diCDParamsW.hwnd = lpdiCDParams->hwnd; + diCDParamsW.lptszUserNames = NULL; + + if (lpdiCDParams->lptszUserNames) { + char *start = lpdiCDParams->lptszUserNames; + WCHAR *to = NULL; + int total_len = 0; + for (i = 0; i < lpdiCDParams->dwcUsers; i++) + { + char *end = start + 1; + int len; + while (*(end++)); + len = MultiByteToWideChar(CP_ACP, 0, start, end - start, NULL, 0); + total_len += len + 2; /* length of string and two null char */ + if (to) + to = HeapReAlloc(GetProcessHeap(), 0, to, sizeof(WCHAR) * total_len); + else + to = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * total_len); + + MultiByteToWideChar(CP_ACP, 0, start, end - start, to + (total_len - len - 2), len); + to[total_len] = 0; + to[total_len - 1] = 0; + } + diCDParamsW.lptszUserNames = to; + } diafW.rgoAction = HeapAlloc(GetProcessHeap(), 0, sizeof(DIACTIONW)*lpdiCDParams->lprgFormats->dwNumActions); _copy_diactionformatAtoW(&diafW, lpdiCDParams->lprgFormats); @@ -1290,6 +1322,8 @@ static HRESULT WINAPI IDirectInput8AImpl_ConfigureDevices( HeapFree(GetProcessHeap(), 0, diafW.rgoAction); + heap_free((void*) diCDParamsW.lptszUserNames); + return hr; } @@ -1777,7 +1811,7 @@ static DWORD WINAPI hook_thread_proc(void *param) DispatchMessageW(&msg); } - return 0; + FreeLibraryAndExitThread(DINPUT_instance, 0); } static DWORD hook_thread_id; @@ -1794,15 +1828,16 @@ static CRITICAL_SECTION dinput_hook_crit = { &dinput_critsect_debug, -1, 0, 0, 0 static BOOL check_hook_thread(void) { static HANDLE hook_thread; + HMODULE module; EnterCriticalSection(&dinput_hook_crit); TRACE("IDirectInputs left: %d\n", list_count(&direct_input_list)); if (!list_empty(&direct_input_list) && !hook_thread) { + GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const WCHAR*)DINPUT_instance, &module); hook_thread_event = CreateEventW(NULL, FALSE, FALSE, NULL); hook_thread = CreateThread(NULL, 0, hook_thread_proc, hook_thread_event, 0, &hook_thread_id); - LeaveCriticalSection(&dinput_hook_crit); } else if (list_empty(&direct_input_list) && hook_thread) { @@ -1817,16 +1852,11 @@ static BOOL check_hook_thread(void) hook_thread_id = 0; PostThreadMessageW(tid, WM_USER+0x10, 0, 0); - LeaveCriticalSection(&dinput_hook_crit); - - /* wait for hook thread to exit */ - WaitForSingleObject(hook_thread, INFINITE); CloseHandle(hook_thread); hook_thread = NULL; } - else - LeaveCriticalSection(&dinput_hook_crit); + LeaveCriticalSection(&dinput_hook_crit); return hook_thread_id != 0; } diff --git a/dll/directx/wine/dinput/dinput_private.h b/dll/directx/wine/dinput/dinput_private.h index acda6c80485..289b2f1f63d 100644 --- a/dll/directx/wine/dinput/dinput_private.h +++ b/dll/directx/wine/dinput/dinput_private.h @@ -81,6 +81,7 @@ extern void _copy_diactionformatWtoA(LPDIACTIONFORMATA, LPDIACTIONFORMATW) DECLS extern HRESULT _configure_devices(IDirectInput8W *iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) DECLSPEC_HIDDEN; extern WCHAR* get_mapping_path(const WCHAR *device, const WCHAR *username) DECLSPEC_HIDDEN; +extern DWORD get_device_type(DWORD version, BOOL is_joystick) DECLSPEC_HIDDEN; #define IS_DIPROP(x) (((ULONG_PTR)(x) >> 16) == 0) diff --git a/dll/directx/wine/dinput/effect_linuxinput.c b/dll/directx/wine/dinput/effect_linuxinput.c index 7477bc757da..4b2f317ce37 100644 --- a/dll/directx/wine/dinput/effect_linuxinput.c +++ b/dll/directx/wine/dinput/effect_linuxinput.c @@ -167,7 +167,9 @@ static ULONG WINAPI LinuxInputEffectImpl_AddRef( LPDIRECTINPUTEFFECT iface) { LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface); - return InterlockedIncrement(&(This->ref)); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE( "(%p) ref %d\n", This, ref ); + return ref; } static HRESULT WINAPI LinuxInputEffectImpl_Download( @@ -759,6 +761,8 @@ static ULONG WINAPI LinuxInputEffectImpl_Release(LPDIRECTINPUTEFFECT iface) LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface); ULONG ref = InterlockedDecrement(&(This->ref)); + TRACE( "(%p) ref %d\n", This, ref ); + if (ref == 0) { LinuxInputEffectImpl_Stop(iface); diff --git a/dll/directx/wine/dinput/joystick.c b/dll/directx/wine/dinput/joystick.c index 0ec1ceb2497..9d7baf411a4 100644 --- a/dll/directx/wine/dinput/joystick.c +++ b/dll/directx/wine/dinput/joystick.c @@ -28,12 +28,40 @@ #include <stdio.h> +#include "device_private.h" #include "joystick_private.h" #include "wine/debug.h" +#include "wine/heap.h" #include "winreg.h" WINE_DEFAULT_DEBUG_CHANNEL(dinput); +#define VID_MICROSOFT 0x045e + +static const WORD PID_XBOX_CONTROLLERS[] = { + 0x0202, /* Xbox Controller */ + 0x0285, /* Xbox Controller S */ + 0x0289, /* Xbox Controller S */ + 0x028e, /* Xbox360 Controller */ + 0x028f, /* Xbox360 Wireless Controller */ + 0x02d1, /* Xbox One Controller */ + 0x02dd, /* Xbox One Controller (Covert Forces/Firmware 2015) */ + 0x02e0, /* Xbox One X Controller */ + 0x02e3, /* Xbox One Elite Controller */ + 0x02e6, /* Wireless XBox Controller Dongle */ + 0x02ea, /* Xbox One S Controller */ + 0x02fd, /* Xbox One S Controller (Firmware 2017) */ + 0x0719, /* Xbox 360 Wireless Adapter */ +}; + +/* Windows uses this GUID for guidProduct on non-keyboard/mouse devices. + * Data1 contains the device VID (low word) and PID (high word). + * Data4 ends with the ASCII bytes "PIDVID". + */ +const GUID DInput_PIDVID_Product_GUID = { /* device_pidvid-0000-0000-0000-504944564944 */ + 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44} +}; + static inline JoystickGenericImpl *impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface) { return CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8A_iface), JoystickGenericImpl, base); @@ -76,6 +104,16 @@ DWORD typeFromGUID(REFGUID guid) } } +DWORD get_device_type(DWORD version, BOOL is_joystick) +{ + if (is_joystick) + return version >= 0x0800 ? DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8) : + DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); + + return version >= 0x0800 ? DI8DEVTYPE_GAMEPAD | (DI8DEVTYPEJOYSTICK_STANDARD << 8) : + DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_GAMEPAD << 8); +} + static void _dump_DIEFFECT_flags(DWORD dwFlags) { if (TRACE_ON(dinput)) { @@ -271,6 +309,89 @@ BOOL device_disabled_registry(const char* name) return do_disable; } +BOOL is_xinput_device(const DIDEVCAPS *devcaps, WORD vid, WORD pid) +{ + int i; + + if (vid == VID_MICROSOFT) + { + for (i = 0; i < ARRAY_SIZE(PID_XBOX_CONTROLLERS); i++) + if (pid == PID_XBOX_CONTROLLERS[i]) return TRUE; + } + + return (devcaps->dwAxes == 6 && devcaps->dwButtons >= 14); +} + +static void remap_init(JoystickGenericImpl *This, int obj, ObjProps *remap_props) +{ + /* Configure as if nothing changed so the helper functions can only change + * what they need, thus reducing code duplication. */ + remap_props->lDevMin = remap_props->lMin = This->props[obj].lMin; + remap_props->lDevMax = remap_props->lMax = This->props[obj].lMax; + + remap_props->lDeadZone = This->props[obj].lDeadZone; + remap_props->lSaturation = This->props[obj].lSaturation; +} + +static void remap_apply(JoystickGenericImpl *This, int obj, ObjProps *remap_props) +{ + /* Many games poll the joystick immediately after setting the range + * for calibration purposes, so the old values need to be remapped + * to the new range before it does so */ + switch (This->base.data_format.wine_df->rgodf[obj].dwOfs){ + case DIJOFS_X : This->js.lX = joystick_map_axis(remap_props, This->js.lX); break; + case DIJOFS_Y : This->js.lY = joystick_map_axis(remap_props, This->js.lY); break; + case DIJOFS_Z : This->js.lZ = joystick_map_axis(remap_props, This->js.lZ); break; + case DIJOFS_RX : This->js.lRx = joystick_map_axis(remap_props, This->js.lRx); break; + case DIJOFS_RY : This->js.lRy = joystick_map_axis(remap_props, This->js.lRy); break; + case DIJOFS_RZ : This->js.lRz = joystick_map_axis(remap_props, This->js.lRz); break; + case DIJOFS_SLIDER(0): This->js.rglSlider[0] = joystick_map_axis(remap_props, This->js.rglSlider[0]); break; + case DIJOFS_SLIDER(1): This->js.rglSlider[1] = joystick_map_axis(remap_props, This->js.rglSlider[1]); break; + default: break; + } +} + +static void remap_range(JoystickGenericImpl *This, int obj, LPCDIPROPRANGE pr) +{ + ObjProps remap_props; + remap_init(This, obj, &remap_props); + + remap_props.lMin = pr->lMin; + remap_props.lMax = pr->lMax; + + remap_apply(This, obj, &remap_props); + + /* Store new values */ + This->props[obj].lMin = pr->lMin; + This->props[obj].lMax = pr->lMax; +} + +static void remap_deadzone(JoystickGenericImpl *This, int obj, LPCDIPROPDWORD pd) +{ + ObjProps remap_props; + remap_init(This, obj, &remap_props); + + remap_props.lDeadZone = pd->dwData; + + remap_apply(This, obj, &remap_props); + + /* Store new value */ + This->props[obj].lDeadZone = pd->dwData; +} + +static void remap_saturation(JoystickGenericImpl *This, int obj, LPCDIPROPDWORD pd) +{ + ObjProps remap_props; + remap_init(This, obj, &remap_props); + + remap_props.lSaturation = pd->dwData; + + remap_apply(This, obj, &remap_props); + + /* Store new value */ + This->props[obj].lSaturation = pd->dwData; +} + /****************************************************************************** * SetProperty : change input device properties */ @@ -278,7 +399,6 @@ HRESULT WINAPI JoystickWGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REF { JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface); DWORD i; - ObjProps remap_props; TRACE("(%p,%s,%p)\n",This,debugstr_guid(rguid),ph); @@ -295,69 +415,15 @@ HRESULT WINAPI JoystickWGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REF case (DWORD_PTR)DIPROP_RANGE: { LPCDIPROPRANGE pr = (LPCDIPROPRANGE)ph; if (ph->dwHow == DIPH_DEVICE) { - - /* Many games poll the joystick immediately after setting the range - * for calibration purposes, so the old values need to be remapped - * to the new range before it does so */ - TRACE("proprange(%d,%d) all\n", pr->lMin, pr->lMax); - for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++) { - - remap_props.lDevMin = This->props[i].lMin; - remap_props.lDevMax = This->props[i].lMax; - - remap_props.lDeadZone = This->props[i].lDeadZone; - remap_props.lSaturation = This->props[i].lSaturation; - - remap_props.lMin = pr->lMin; - remap_props.lMax = pr->lMax; - - switch (This->base.data_format.wine_df->rgodf[i].dwOfs) { - case DIJOFS_X : This->js.lX = joystick_map_axis(&remap_props, This->js.lX); break; - case DIJOFS_Y : This->js.lY = joystick_map_axis(&remap_props, This->js.lY); break; - case DIJOFS_Z : This->js.lZ = joystick_map_axis(&remap_props, This->js.lZ); break; - case DIJOFS_RX : This->js.lRx = joystick_map_axis(&remap_props, This->js.lRx); break; - case DIJOFS_RY : This->js.lRy = joystick_map_axis(&remap_props, This->js.lRy); break; - case DIJOFS_RZ : This->js.lRz = joystick_map_axis(&remap_props, This->js.lRz); break; - case DIJOFS_SLIDER(0): This->js.rglSlider[0] = joystick_map_axis(&remap_props, This->js.rglSlider[0]); break; - case DIJOFS_SLIDER(1): This->js.rglSlider[1] = joystick_map_axis(&remap_props, This->js.rglSlider[1]); break; - default: break; - } - - This->props[i].lMin = pr->lMin; - This->props[i].lMax = pr->lMax; - } + for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++) + remap_range(This, i, pr); } else { int obj = find_property(&This->base.data_format, ph); TRACE("proprange(%d,%d) obj=%d\n", pr->lMin, pr->lMax, obj); - if (obj >= 0) { - - remap_props.lDevMin = This->props[obj].lMin; - remap_props.lDevMax = This->props[obj].lMax; - - remap_props.lDeadZone = This->props[obj].lDeadZone; - remap_props.lSaturation = This->props[obj].lSaturation; - - remap_props.lMin = pr->lMin; - remap_props.lMax = pr->lMax; - - switch (This->base.data_format.wine_df->rgodf[obj].dwOfs) { - case DIJOFS_X : This->js.lX = joystick_map_axis(&remap_props, This->js.lX); break; - case DIJOFS_Y : This->js.lY = joystick_map_axis(&remap_props, This->js.lY); break; - case DIJOFS_Z : This->js.lZ = joystick_map_axis(&remap_props, This->js.lZ); break; - case DIJOFS_RX : This->js.lRx = joystick_map_axis(&remap_props, This->js.lRx); break; - case DIJOFS_RY : This->js.lRy = joystick_map_axis(&remap_props, This->js.lRy); break; - case DIJOFS_RZ : This->js.lRz = joystick_map_axis(&remap_props, This->js.lRz); break; - case DIJOFS_SLIDER(0): This->js.rglSlider[0] = joystick_map_axis(&remap_props, This->js.rglSlider[0]); break; - case DIJOFS_SLIDER(1): This->js.rglSlider[1] = joystick_map_axis(&remap_props, This->js.rglSlider[1]); break; - default: break; - } - - This->props[obj].lMin = pr->lMin; - This->props[obj].lMax = pr->lMax; - return DI_OK; - } + if (obj >= 0) + remap_range(This, obj, pr); } break; } @@ -366,15 +432,13 @@ HRESULT WINAPI JoystickWGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REF if (ph->dwHow == DIPH_DEVICE) { TRACE("deadzone(%d) all\n", pd->dwData); for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++) - This->props[i].lDeadZone = pd->dwData; + remap_deadzone(This, i, pd); } else { int obj = find_property(&This->base.data_format, ph); TRACE("deadzone(%d) obj=%d\n", pd->dwData, obj); - if (obj >= 0) { - This->props[obj].lDeadZone = pd->dwData; - return DI_OK; - } + if (obj >= 0) + remap_deadzone(This, obj, pd); } break; } @@ -383,18 +447,21 @@ HRESULT WINAPI JoystickWGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REF if (ph->dwHow == DIPH_DEVICE) { TRACE("saturation(%d) all\n", pd->dwData); for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++) - This->props[i].lSaturation = pd->dwData; + remap_saturation(This, i, pd); } else { int obj = find_property(&This->base.data_format, ph); TRACE("saturation(%d) obj=%d\n", pd->dwData, obj); - if (obj >= 0) { - This->props[obj].lSaturation = pd->dwData; - return DI_OK; - } + if (obj >= 0) + remap_saturation(This, obj, pd); } break; } + case (DWORD_PTR)DIPROP_CALIBRATIONMODE: { + LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; + FIXME("DIPROP_CALIBRATIONMODE(%d)\n", pd->dwData); + break; + } default: return IDirectInputDevice2WImpl_SetProperty(iface, rguid, ph); } @@ -461,7 +528,7 @@ HRESULT WINAPI JoystickWGenericImpl_GetCapabilities(LPDIRECTINPUTDEVICE8W iface, JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface); int size; - TRACE("%p->(%p)\n",iface,lpDIDevCaps); + TRACE("%p->(%p)\n",This,lpDIDevCaps); if (lpDIDevCaps == NULL) { WARN("invalid pointer\n"); @@ -544,7 +611,7 @@ HRESULT WINAPI JoystickWGenericImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REF { JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(rguid), pdiph); + TRACE("(%p,%s,%p)\n", This, debugstr_guid(rguid), pdiph); if (TRACE_ON(dinput)) _dump_DIPROPHEADER(pdiph); @@ -627,7 +694,7 @@ HRESULT WINAPI JoystickAGenericImpl_GetDeviceInfo( DIPROPDWORD pd; DWORD index = 0; - TRACE("(%p,%p)\n", iface, pdidi); + TRACE("(%p,%p)\n", This, pdidi); if (pdidi == NULL) { WARN("invalid pointer\n"); @@ -654,7 +721,7 @@ HRESULT WINAPI JoystickAGenericImpl_GetDeviceInfo( /* we only support traditional joysticks for now */ pdidi->dwDevType = This->devcaps.dwDevType; snprintf(pdidi->tszInstanceName, MAX_PATH, "Joystick %d", index); - strcpy(pdidi->tszProductName, This->name); + lstrcpynA(pdidi->tszProductName, This->name, MAX_PATH); if (pdidi->dwSize > sizeof(DIDEVICEINSTANCE_DX3A)) { pdidi->guidFFDriver = GUID_NULL; pdidi->wUsagePage = 0; @@ -771,8 +838,31 @@ HRESULT WINAPI JoystickWGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface, JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface); unsigned int i, j; BOOL has_actions = FALSE; + WCHAR *username; + DWORD size; + BOOL load_success = FALSE; + + FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", This, lpdiaf, debugstr_w(lpszUserName), dwFlags); - FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); + /* Unless asked the contrary by these flags, try to load a previous mapping */ + if (!(dwFlags & DIDBAM_HWDEFAULTS)) + { + if (!lpszUserName) + GetUserNameW(NULL, &size); + else + size = lstrlenW(lpszUserName) + 1; + + username = heap_alloc(size * sizeof(WCHAR)); + if (!lpszUserName) + GetUserNameW(username, &size); + else + lstrcpynW(username, lpszUserName, size); + + load_success = load_mapping_settings(&This->base, lpdiaf, username); + heap_free(username); + } + + if (load_success) return DI_OK; for (i=0; i < lpdiaf->dwNumActions; i++) { @@ -850,7 +940,7 @@ HRESULT WINAPI JoystickWGenericImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface, { JoystickGenericImpl *This = impl_from_IDirectInputDevice8W(iface); - FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); + FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", This, lpdiaf, debugstr_w(lpszUserName), dwFlags); return _set_action_map(iface, lpdiaf, lpszUserName, dwFlags, This->base.data_format.wine_df); } @@ -878,6 +968,8 @@ HRESULT WINAPI JoystickAGenericImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface, hr = JoystickWGenericImpl_SetActionMap(&This->base.IDirectInputDevice8W_iface, &diafW, lpszUserNameW, dwFlags); + lpdiaf->dwCRC = diafW.dwCRC; + HeapFree(GetProcessHeap(), 0, diafW.rgoAction); HeapFree(GetProcessHeap(), 0, lpszUserNameW); @@ -950,6 +1042,7 @@ HRESULT setup_dinput_options(JoystickGenericImpl *This, const int *default_axis_ int tokens = 0; int axis = 0; int pov = 0; + int button; get_app_key(&hkey, &appkey); @@ -961,6 +1054,34 @@ HRESULT setup_dinput_options(JoystickGenericImpl *This, const int *default_axis_ TRACE("setting default deadzone to: \"%s\" %d\n", buffer, This->deadzone); } + for (button = 0; button < MAX_MAP_BUTTONS; button++) + This->button_map[button] = button; + + if (!get_config_key(hkey, appkey, "ButtonMap", buffer, sizeof(buffer))) + { + static const char *delim = ","; + int button = 0; + char *token; + + TRACE("ButtonMap = \"%s\"\n", buffer); + for (token = strtok(buffer, delim); + token != NULL && button < MAX_MAP_BUTTONS; + token = strtok(NULL, delim), button++) + { + char *s; + int value = strtol(token, &s, 10); + if (value < 0 || *s != '\0') + { + ERR("invalid button number: \"%s\"", token); + } + else + { + TRACE("mapping physical button %d to DInput button %d", value, button); + This->button_map[value] = button; + } + } + } + This->axis_map = HeapAlloc(GetProcessHeap(), 0, This->device_axis_count * sizeof(int)); if (!This->axis_map) return DIERR_OUTOFMEMORY; diff --git a/dll/directx/wine/dinput/joystick_linux.c b/dll/directx/wine/dinput/joystick_linux.c index 963e62f017c..3ecbf441aad 100644 --- a/dll/directx/wine/dinput/joystick_linux.c +++ b/dll/directx/wine/dinput/joystick_linux.c @@ -59,6 +59,7 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" +#include "devguid.h" #include "dinput.h" #include "dinput_private.h" @@ -84,6 +85,8 @@ struct JoyDev int *dev_axes_map; WORD vendor_id, product_id, bus_type; + + BOOL is_joystick; }; typedef struct JoystickImpl JoystickImpl; @@ -123,19 +126,6 @@ static const GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7} }; -/* - * Construct the GUID in the same way of Windows doing this. - * Data1 is concatenation of productid and vendorid. - * Data2 and Data3 are NULL. - * Data4 seems to be a constant. - */ -static const GUID DInput_Wine_Joystick_Constant_Part_GUID = { - 0x000000000, - 0x0000, - 0x0000, - {0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44} -}; - #define MAX_JOYSTICKS 64 static INT joystick_devices_count = -1; static struct JoyDev *joystick_devices; @@ -177,6 +167,8 @@ static INT find_joystick_devices(void) int fd; struct JoyDev joydev, *new_joydevs; BYTE axes_map[ABS_MAX + 1]; + SHORT btn_map[KEY_MAX - BTN_MISC + 1]; + BOOL is_stylus = FALSE; snprintf(joydev.device, sizeof(joydev.device), "%s%d", JOYDEV_NEW, i); if ((fd = open(joydev.device, O_RDONLY)) == -1) @@ -220,6 +212,52 @@ static INT find_joystick_devices(void) joydev.button_count = 2; #endif + joydev.is_joystick = FALSE; + if (ioctl(fd, JSIOCGBTNMAP, btn_map) < 0) + { + WARN("ioctl(%s,JSIOCGBTNMAP) failed: %s\n", joydev.device, strerror(errno)); + } + else + { + INT j; + /* in lieu of properly reporting HID usage, detect presence of + * "joystick buttons" and report those devices as joysticks instead of + * gamepads */ + for (j = 0; !joydev.is_joystick && j < joydev.button_count; j++) + { + switch (btn_map[j]) + { + case BTN_TRIGGER: + case BTN_THUMB: + case BTN_THUMB2: + case BTN_TOP: + case BTN_TOP2: + case BTN_PINKIE: + case BTN_BASE: + case BTN_BASE2: + case BTN_BASE3: + case BTN_BASE4: + case BTN_BASE5: + case BTN_BASE6: + case BTN_DEAD: + joydev.is_joystick = TRUE; + break; + case BTN_STYLUS: + is_stylus = TRUE; + break; + default: + break; + } + } + } + + if(is_stylus) + { + TRACE("Stylus detected. Skipping\n"); + close(fd); + continue; + } + if (ioctl(fd, JSIOCGAXMAP, axes_map) < 0) { WARN("ioctl(%s,JSIOCGAXMAP) failed: %s\n", joydev.device, strerror(errno)); @@ -239,6 +277,14 @@ static INT find_joystick_devices(void) joydev.dev_axes_map[j] = j; found_axes++; } + else if (axes_map[j] <= 10) + { + /* Axes 8 through 10 are Wheel, Gas and Brake, + * remap to 0, 1 and 2 + */ + joydev.dev_axes_map[j] = axes_map[j] - 8; + found_axes++; + } else if (axes_map[j] == 16 || axes_map[j] == 17) { @@ -279,7 +325,7 @@ static INT find_joystick_devices(void) else { /* Concatenate product_id with vendor_id to mimic Windows behaviour */ - joydev.guid_product = DInput_Wine_Joystick_Constant_Part_GUID; + joydev.guid_product = DInput_PIDVID_Product_GUID; joydev.guid_product.Data1 = MAKELONG(joydev.vendor_id, joydev.product_id); } @@ -314,11 +360,7 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver lpddi->guidInstance = DInput_Wine_Joystick_GUID; lpddi->guidInstance.Data3 = id; lpddi->guidProduct = joystick_devices[id].guid_product; - /* we only support traditional joysticks for now */ - if (version >= 0x0800) - lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); - else - lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); + lpddi->dwDevType = get_device_type(version, joystick_devices[id].is_joystick); /* Assume the joystick as HID if it is attached to USB bus and has a valid VID/PID */ if (joystick_devices[id].bus_type == BUS_USB && @@ -326,7 +368,7 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver { lpddi->dwDevType |= DIDEVTYPE_HID; lpddi->wUsagePage = 0x01; /* Desktop */ - if (lpddi->dwDevType == DI8DEVTYPE_JOYSTICK || lpddi->dwDevType == DIDEVTYPE_JOYSTICK) + if (joystick_devices[id].is_joystick) lpddi->wUsage = 0x04; /* Joystick */ else lpddi->wUsage = 0x05; /* Game Pad */ @@ -372,7 +414,7 @@ static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS } if ((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) || + ((dwDevType == DIDEVTYPE_JOYSTICK) && (version >= 0x0300 && version < 0x0800)) || (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) { /* check whether we have a joystick */ if ((fd = open(joystick_devices[id].device, O_RDONLY)) == -1) @@ -401,7 +443,7 @@ static HRESULT joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS } if ((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) || + ((dwDevType == DIDEVTYPE_JOYSTICK) && (version >= 0x0300 && version < 0x0800)) || (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) { /* check whether we have a joystick */ if ((fd = open(joystick_devices[id].device, O_RDONLY)) == -1) @@ -673,7 +715,7 @@ static HRESULT WINAPI JoystickLinuxWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface { JoystickImpl *This = impl_from_IDirectInputDevice8W(iface); - TRACE("(this=%p,%s,%p)\n", iface, debugstr_guid(rguid), pdiph); + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph); _dump_DIPROPHEADER(pdiph); if (!IS_DIPROP(rguid)) return DI_OK; @@ -699,6 +741,29 @@ static HRESULT WINAPI JoystickLinuxWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface break; } + case (DWORD_PTR) DIPROP_GUIDANDPATH: + { + static const WCHAR formatW[] = {'\\','\\','?','\\','h','i','d','#','v','i','d','_','%','0','4','x','&', + 'p','i','d','_','%','0','4','x','&','%','s','_','%','h','u',0}; + static const WCHAR miW[] = {'m','i',0}; + static const WCHAR igW[] = {'i','g',0}; + + BOOL is_gamepad; + LPDIPROPGUIDANDPATH pd = (LPDIPROPGUIDANDPATH)pdiph; + WORD vid = This->joydev->vendor_id; + WORD pid = This->joydev->product_id; + + if (!pid || !vid) + return DIERR_UNSUPPORTED; + + is_gamepad = is_xinput_device(&This->generic.devcaps, vid, pid); + pd->guidClass = GUID_DEVCLASS_HIDCLASS; + sprintfW(pd->wszPath, formatW, vid, pid, is_gamepad ? igW : miW, get_joystick_index(&This->generic.base.guid)); + + TRACE("DIPROP_GUIDANDPATH(%s, %s): returning fake path\n", debugstr_guid(&pd->guidClass), debugstr_w(pd->wszPath)); + break; + } + default: return JoystickWGenericImpl_GetProperty(iface, rguid, pdiph); } @@ -807,10 +872,13 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface) jse.type,jse.number,jse.value); if (jse.type & JS_EVENT_BUTTON) { + int button; if (jse.number >= This->generic.devcaps.dwButtons) return; - inst_id = DIDFT_MAKEINSTANCE(jse.number) | DIDFT_PSHBUTTON; - This->generic.js.rgbButtons[jse.number] = value = jse.value ? 0x80 : 0x00; + button = This->generic.button_map[jse.number]; + + inst_id = DIDFT_MAKEINSTANCE(button) | DIDFT_PSHBUTTON; + This->generic.js.rgbButtons[button] = value = jse.value ? 0x80 : 0x00; } else if (jse.type & JS_EVENT_AXIS) { diff --git a/dll/directx/wine/dinput/joystick_linuxinput.c b/dll/directx/wine/dinput/joystick_linuxinput.c index 910e755d3ed..8865532d9d1 100644 --- a/dll/directx/wine/dinput/joystick_linuxinput.c +++ b/dll/directx/wine/dinput/joystick_linuxinput.c @@ -57,6 +57,7 @@ #include "winbase.h" #include "winerror.h" #include "winreg.h" +#include "devguid.h" #include "dinput.h" #include "dinput_private.h" @@ -83,6 +84,13 @@ struct wine_input_absinfo { LONG flat; }; +enum wine_joystick_linuxinput_fd_state { + WINE_FD_STATE_CLOSED = 0, /* No device has been opened yet */ + WINE_FD_STATE_OK, /* File descriptor is open and ready for reading */ + WINE_FD_STATE_DISCONNECTED, /* Read error occurred; might be able to reopen later */ + WINE_FD_STATE_INVALID, /* Device is no longer available at original pathname */ +}; + /* implemented in effect_linuxinput.c */ HRESULT linuxinput_create_effect(int* fd, REFGUID rguid, struct list *parent_list_entry, LPDIRECTINPUTEFFECT* peff); HRESULT linuxinput_get_info_A(int fd, REFGUID rguid, LPDIEFFECTINFOA info); @@ -100,7 +108,7 @@ struct JoyDev { GUID guid; GUID guid_product; - BOOL has_ff; + BOOL has_ff, is_joystick; int num_effects; /* data returned by EVIOCGBIT for caps, EV_ABS, EV_KEY, and EV_FF */ @@ -122,6 +130,7 @@ struct JoystickImpl /* joystick private */ int joyfd; + enum wine_joystick_linuxinput_fd_state joyfd_state; int dev_axes_to_di[ABS_MAX]; POINTL povs[4]; @@ -164,19 +173,6 @@ static const GUID DInput_Wine_Joystick_Base_GUID = { /* 9e573eda-7734-11d2-8d4a- {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7} }; -/* - * Construct the GUID in the same way of Windows doing this. - * Data1 is concatenation of productid and vendorid. - * Data2 and Data3 are NULL. - * Data4 seems to be a constant. - */ -static const GUID DInput_Wine_Joystick_Constant_Part_GUID = { - 0x000000000, - 0x0000, - 0x0000, - {0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44} -}; - #define test_bit(arr,bit) (((BYTE*)(arr))[(bit)>>3]&(1<<((bit)&7))) #define MAX_JOYDEV 64 @@ -211,10 +207,7 @@ static void find_joydevs(void) } if (fd == -1) - { - WARN("Failed to open \"%s\": %d %s\n", buf, errno, strerror(errno)); continue; - } if (ioctl(fd, EVIOCGBIT(0, sizeof(joydev.evbits)), joydev.evbits) == -1) { @@ -237,15 +230,41 @@ static void find_joydevs(void) /* A true joystick has at least axis X and Y, and at least 1 * button. copied from linux/drivers/input/joydev.c */ - if (!test_bit(joydev.absbits, ABS_X) || !test_bit(joydev.absbits, ABS_Y) || + if (((!test_bit(joydev.absbits, ABS_X) || !test_bit(joydev.absbits, ABS_Y)) && + !test_bit(joydev.absbits, ABS_WHEEL) && + !test_bit(joydev.absbits, ABS_GAS) && + !test_bit(joydev.absbits, ABS_BRAKE)) || !(test_bit(joydev.keybits, BTN_TRIGGER) || test_bit(joydev.keybits, BTN_A) || - test_bit(joydev.keybits, BTN_1))) + test_bit(joydev.keybits, BTN_1) || + test_bit(joydev.keybits, BTN_BASE) || + test_bit(joydev.keybits, BTN_GEAR_UP) || + test_bit(joydev.keybits, BTN_GEAR_DOWN))) { close(fd); continue; } + /* in lieu of properly reporting HID usage, detect presence of + * "joystick buttons" and report those devices as joysticks instead of + * gamepads */ + joydev.is_joystick = + test_bit(joydev.keybits, BTN_TRIGGER) || + test_bit(joydev.keybits, BTN_THUMB) || + test_bit(joydev.keybits, BTN_THUMB2) || + test_bit(joydev.keybits, BTN_TOP) || + test_bit(joydev.keybits, BTN_TOP2) || + test_bit(joydev.keybits, BTN_PINKIE) || + test_bit(joydev.keybits, BTN_BASE) || + test_bit(joydev.keybits, BTN_BASE2) || + test_bit(joydev.keybits, BTN_BASE3) || + test_bit(joydev.keybits, BTN_BASE4) || + test_bit(joydev.keybits, BTN_BASE5) || + test_bit(joydev.keybits, BTN_BASE6) || + test_bit(joydev.keybits, BTN_GEAR_UP) || + test_bit(joydev.keybits, BTN_GEAR_DOWN) || + test_bit(joydev.keybits, BTN_DEAD); + if (!(joydev.device = HeapAlloc(GetProcessHeap(), 0, strlen(buf) + 1))) { close(fd); @@ -320,7 +339,7 @@ static void find_joydevs(void) joydev.bus_type = device_id.bustype; /* Concatenate product_id with vendor_id to mimic Windows behaviour */ - joydev.guid_product = DInput_Wine_Joystick_Constant_Part_GUID; + joydev.guid_product = DInput_PIDVID_Product_GUID; joydev.guid_product.Data1 = MAKELONG(joydev.vendor_id, joydev.product_id); } @@ -353,11 +372,7 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver lpddi->guidInstance = joydevs[id].guid; lpddi->guidProduct = joydevs[id].guid_product; lpddi->guidFFDriver = GUID_NULL; - - if (version >= 0x0800) - lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); - else - lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); + lpddi->dwDevType = get_device_type(version, joydevs[id].is_joystick); /* Assume the joystick as HID if it is attached to USB bus and has a valid VID/PID */ if (joydevs[id].bus_type == BUS_USB && @@ -365,7 +380,7 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver { lpddi->dwDevType |= DIDEVTYPE_HID; lpddi->wUsagePage = 0x01; /* Desktop */ - if (lpddi->dwDevType == DI8DEVTYPE_JOYSTICK || lpddi->dwDevType == DIDEVTYPE_JOYSTICK) + if (joydevs[id].is_joystick) lpddi->wUsage = 0x04; /* Joystick */ else lpddi->wUsage = 0x05; /* Game Pad */ @@ -391,8 +406,8 @@ static void fill_joystick_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD ver lpddi->guidInstance = lpddiW.guidInstance; lpddi->guidProduct = lpddiW.guidProduct; lpddi->dwDevType = lpddiW.dwDevType; - strcpy(lpddi->tszInstanceName, joydevs[id].name); - strcpy(lpddi->tszProductName, joydevs[id].name); + lstrcpynA(lpddi->tszInstanceName, joydevs[id].name, MAX_PATH); + lstrcpynA(lpddi->tszProductName, joydevs[id].name, MAX_PATH); lpddi->guidFFDriver = lpddiW.guidFFDriver; lpddi->wUsagePage = lpddiW.wUsagePage; lpddi->wUsage = lpddiW.wUsage; @@ -407,7 +422,7 @@ static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS } if (!((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) || + ((dwDevType == DIDEVTYPE_JOYSTICK) && (version >= 0x0300 && version < 0x0800)) || (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800)))) return S_FALSE; @@ -432,7 +447,7 @@ static HRESULT joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS } if (!((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) || + ((dwDevType == DIDEVTYPE_JOYSTICK) && (version >= 0x0300 && version < 0x0800)) || (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800)))) return S_FALSE; @@ -466,6 +481,7 @@ static JoystickImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput, unsig newDevice->generic.base.dinput = dinput; newDevice->generic.joy_polldev = joy_polldev; newDevice->joyfd = -1; + newDevice->joyfd_state = WINE_FD_STATE_CLOSED; newDevice->joydev = &joydevs[index]; newDevice->generic.name = newDevice->joydev->name; list_init(&newDevice->ff_effects); @@ -483,14 +499,18 @@ static JoystickImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput, unsig /* Count number of available axes - supported Axis & POVs */ for (i = 0; i < ABS_MAX; i++) { - if (i < WINE_JOYSTICK_MAX_AXES && + if (idx < WINE_JOYSTICK_MAX_AXES && + i < ABS_HAT0X && test_bit(newDevice->joydev->absbits, i)) { newDevice->generic.device_axis_count++; newDevice->dev_axes_to_di[i] = idx; newDevice->generic.props[idx].lDevMin = newDevice->joydev->axes[i].minimum; newDevice->generic.props[idx].lDevMax = newDevice->joydev->axes[i].maximum; - default_axis_map[idx] = i; + if (i >= 8 && i <= 10) /* If it's a wheel axis... */ + default_axis_map[idx] = i - 8; /* ... remap to X/Y/Z */ + else + default_axis_map[idx] = i; idx++; } else @@ -669,38 +689,15 @@ static HRESULT joydev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REF return DIERR_DEVICENOTREG; } - -const struct dinput_device joystick_linuxinput_device = { - "Wine Linux-input joystick driver", - joydev_enum_deviceA, - joydev_enum_deviceW, - joydev_create_device -}; - -/****************************************************************************** - * Acquire : gets exclusive control of the joystick - */ -static HRESULT WINAPI JoystickWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface) +static int joydev_open_evdev(JoystickImpl *This) { - JoystickImpl *This = impl_from_IDirectInputDevice8W(iface); - HRESULT res; + int fd; - TRACE("(this=%p)\n",This); - - if ((res = IDirectInputDevice2WImpl_Acquire(iface)) != DI_OK) - { - WARN("Failed to acquire: %x\n", res); - return res; - } - - if ((This->joyfd = open(This->joydev->device, O_RDWR)) == -1) + if ((fd = open(This->joydev->device, O_RDWR)) == -1) { - if ((This->joyfd = open(This->joydev->device, O_RDONLY)) == -1) + if ((fd = open(This->joydev->device, O_RDONLY)) == -1) { /* Couldn't open the device at all */ - ERR("Failed to open device %s: %d %s\n", This->joydev->device, errno, strerror(errno)); - IDirectInputDevice2WImpl_Unacquire(iface); - return DIERR_NOTFOUND; } else { @@ -715,18 +712,53 @@ static HRESULT WINAPI JoystickWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface) event.type = EV_FF; event.code = FF_GAIN; event.value = This->ff_gain; - if (write(This->joyfd, &event, sizeof(event)) == -1) + if (write(fd, &event, sizeof(event)) == -1) ERR("Failed to set gain (%i): %d %s\n", This->ff_gain, errno, strerror(errno)); if (!This->ff_autocenter) { /* Disable autocenter. */ event.code = FF_AUTOCENTER; event.value = 0; - if (write(This->joyfd, &event, sizeof(event)) == -1) + if (write(fd, &event, sizeof(event)) == -1) ERR("Failed disabling autocenter: %d %s\n", errno, strerror(errno)); } } + return fd; +} + + +const struct dinput_device joystick_linuxinput_device = { + "Wine Linux-input joystick driver", + joydev_enum_deviceA, + joydev_enum_deviceW, + joydev_create_device +}; + +/****************************************************************************** + * Acquire : gets exclusive control of the joystick + */ +static HRESULT WINAPI JoystickWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface) +{ + JoystickImpl *This = impl_from_IDirectInputDevice8W(iface); + HRESULT res; + + TRACE("(this=%p)\n",This); + + if ((res = IDirectInputDevice2WImpl_Acquire(iface)) != DI_OK) + { + WARN("Failed to acquire: %x\n", res); + return res; + } + + if ((This->joyfd = joydev_open_evdev(This)) == -1) + { + ERR("Failed to open device %s: %d %s\n", This->joydev->device, errno, strerror(errno)); + IDirectInputDevice2WImpl_Unacquire(iface); + return DIERR_NOTFOUND; + } + + This->joyfd_state = WINE_FD_STATE_OK; return DI_OK; } @@ -764,6 +796,7 @@ static HRESULT WINAPI JoystickWImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface) close(This->joyfd); This->joyfd = -1; + This->joyfd_state = WINE_FD_STATE_CLOSED; } return res; } @@ -808,23 +841,79 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface) struct input_event ie; JoystickImpl *This = impl_from_IDirectInputDevice8A(iface); - if (This->joyfd==-1) - return; + if (This->joyfd == -1) + { + int fd; + char namebuf[MAX_PATH + 8]; /* 8 == strlen(EVDEVDRIVER) */ + + if (This->joyfd_state != WINE_FD_STATE_DISCONNECTED) + return; + /* Try to reconnect to the device. */ + fd = joydev_open_evdev(This); + if (fd == -1) + return; + namebuf[sizeof(namebuf) - strlen(EVDEVDRIVER) - 1] = 0; + if (ioctl(fd, EVIOCGNAME(sizeof(namebuf) - strlen(EVDEVDRIVER) - 1), namebuf) == -1) + { + /* Couldn't get the name; assume it's a different device. */ + ERR("EVIOCGNAME(%s) failed: %d %s", This->joydev->device, errno, strerror(errno)); + This->joyfd_state = WINE_FD_STATE_INVALID; + return; + } + strcat(namebuf, EVDEVDRIVER); /* Guaranteed to be safe. */ + if (strcmp(namebuf, This->joydev->name) != 0) + { + ERR("Device %s changed from \"%s\" to \"%s\"! Can't reconnect.\n", This->joydev->device, This->joydev->name, namebuf); + This->joyfd_state = WINE_FD_STATE_INVALID; + return; + } + if (InterlockedCompareExchange(&This->joyfd, fd, -1) == -1) + { + This->joyfd_state = WINE_FD_STATE_OK; + TRACE("Reconnected to \"%s\" on %s", This->joydev->name, This->joydev->device); + } + else + { + /* Somebody beat us to it! Throw away our fd and use theirs. */ + close(fd); + } + } while (1) { LONG value = 0; int inst_id = -1; + int result; plfd.fd = This->joyfd; plfd.events = POLLIN; - if (poll(&plfd,1,0) != 1) - return; + result = poll(&plfd,1,0); + if (result != 1) + { + if (result == -1) + { + ERR("poll failed: %d %s\n", errno, strerror(errno)); + close(This->joyfd); + This->joyfd = -1; + This->joyfd_state = WINE_FD_STATE_DISCONNECTED; + } + return; + } /* we have one event, so we can read */ - if (sizeof(ie)!=read(This->joyfd,&ie,sizeof(ie))) - return; + result = read(This->joyfd,&ie,sizeof(ie)); + if (result != sizeof(ie)) + { + if (result == -1) + { + ERR("read failed: %d %s\n", errno, strerror(errno)); + close(This->joyfd); + This->joyfd = -1; + This->joyfd_state = WINE_FD_STATE_DISCONNECTED; + } + return; + } TRACE("input_event: type %d, code %d, value %d\n",ie.type,ie.code,ie.value); switch (ie.type) { @@ -836,6 +925,8 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface) if (btn & 0x80) { btn &= 0x7F; + btn = This->generic.button_map[btn]; + inst_id = DIDFT_MAKEINSTANCE(btn) | DIDFT_PSHBUTTON; This->generic.js.rgbButtons[btn] = value = ie.value ? 0x80 : 0x00; } @@ -923,11 +1014,6 @@ static HRESULT WINAPI JoystickWImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REF if (IS_DIPROP(rguid)) { switch (LOWORD(rguid)) { - case (DWORD_PTR)DIPROP_CALIBRATIONMODE: { - LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; - FIXME("DIPROP_CALIBRATIONMODE(%d)\n", pd->dwData); - break; - } case (DWORD_PTR)DIPROP_AUTOCENTER: { LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; @@ -973,7 +1059,7 @@ static HRESULT WINAPI JoystickWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REF { JoystickImpl *This = impl_from_IDirectInputDevice8W(iface); - TRACE("(this=%p,%s,%p)\n", iface, debugstr_guid(rguid), pdiph); + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph); _dump_DIPROPHEADER(pdiph); if (!IS_DIPROP(rguid)) return DI_OK; @@ -1016,6 +1102,29 @@ static HRESULT WINAPI JoystickWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REF break; } + case (DWORD_PTR) DIPROP_GUIDANDPATH: + { + static const WCHAR formatW[] = {'\\','\\','?','\\','h','i','d','#','v','i','d','_','%','0','4','x','&', + 'p','i','d','_','%','0','4','x','&','%','s','_','%','h','u',0}; + static const WCHAR miW[] = {'m','i',0}; + static const WCHAR igW[] = {'i','g',0}; + + BOOL is_gamepad; + LPDIPROPGUIDANDPATH pd = (LPDIPROPGUIDANDPATH)pdiph; + WORD vid = This->joydev->vendor_id; + WORD pid = This->joydev->product_id; + + if (!pid || !vid) + return DIERR_UNSUPPORTED; + + is_gamepad = is_xinput_device(&This->generic.devcaps, vid, pid); + pd->guidClass = GUID_DEVCLASS_HIDCLASS; + sprintfW(pd->wszPath, formatW, vid, pid, is_gamepad ? igW : miW, get_joystick_index(&This->generic.base.guid)); + + TRACE("DIPROP_GUIDANDPATH(%s, %s): returning fake path\n", debugstr_guid(&pd->guidClass), debugstr_w(pd->wszPath)); + break; + } + default: return JoystickWGenericImpl_GetProperty(iface, rguid, pdiph); } diff --git a/dll/directx/wine/dinput/joystick_osx.c b/dll/directx/wine/dinput/joystick_osx.c index 0701b9f42cc..061423afaa0 100644 --- a/dll/directx/wine/dinput/joystick_osx.c +++ b/dll/directx/wine/dinput/joystick_osx.c @@ -85,6 +85,7 @@ #include "winbase.h" #include "winerror.h" #include "winreg.h" +#include "devguid.h" #include "dinput.h" #include "dinput_private.h" @@ -124,6 +125,11 @@ static inline JoystickImpl *impl_from_IDirectInputDevice8W(IDirectInputDevice8W JoystickGenericImpl, base), JoystickImpl, generic); } +static inline IDirectInputDevice8W *IDirectInputDevice8W_from_impl(JoystickImpl *This) +{ + return &This->generic.base.IDirectInputDevice8W_iface; +} + typedef struct _EffectImpl { IDirectInputEffect IDirectInputEffect_iface; LONG ref; @@ -801,7 +807,11 @@ static void poll_osx_device_state(LPDIRECTINPUTDEVICE8A iface) TRACE("kIOHIDElementTypeInput_Button\n"); if(button_idx < 128) { - IOHIDDeviceGetValue(hid_device, element, &valueRef); + valueRef = NULL; + if (IOHIDDeviceGetValue(hid_device, element, &valueRef) != kIOReturnSuccess) + return; + if (valueRef == NULL) + return; val = IOHIDValueGetIntegerValue(valueRef); newVal = val ? 0x80 : 0x0; oldVal = device->generic.js.rgbButtons[button_idx]; @@ -809,6 +819,8 @@ static void poll_osx_device_state(LPDIRECTINPUTDEVICE8A iface) TRACE("valueRef %s val %d oldVal %d newVal %d\n", debugstr_cf(valueRef), val, oldVal, newVal); if (oldVal != newVal) { + button_idx = device->generic.button_map[button_idx]; + inst_id = DIDFT_MAKEINSTANCE(button_idx) | DIDFT_PSHBUTTON; queue_event(iface,inst_id,newVal,GetCurrentTime(),device->generic.base.dinput->evsequence++); } @@ -823,7 +835,11 @@ static void poll_osx_device_state(LPDIRECTINPUTDEVICE8A iface) case kHIDUsage_GD_Hatswitch: { TRACE("kIOHIDElementTypeInput_Misc / kHIDUsage_GD_Hatswitch\n"); - IOHIDDeviceGetValue(hid_device, element, &valueRef); + valueRef = NULL; + if (IOHIDDeviceGetValue(hid_device, element, &valueRef) != kIOReturnSuccess) + return; + if (valueRef == NULL) + return; val = IOHIDValueGetIntegerValue(valueRef); oldVal = device->generic.js.rgdwPOV[pov_idx]; if (val >= 8) @@ -850,7 +866,11 @@ static void poll_osx_device_state(LPDIRECTINPUTDEVICE8A iface) { int wine_obj = -1; - IOHIDDeviceGetValue(hid_device, element, &valueRef); + valueRef = NULL; + if (IOHIDDeviceGetValue(hid_device, element, &valueRef) != kIOReturnSuccess) + return; + if (valueRef == NULL) + return; val = IOHIDValueGetIntegerValue(valueRef); newVal = joystick_map_axis(&device->generic.props[idx], val); switch (usage) @@ -945,6 +965,7 @@ static DWORD make_vid_pid(IOHIDDeviceRef device) static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id) { IOHIDDeviceRef device; + BOOL is_joystick; TRACE("dwDevType %u dwFlags 0x%08x version 0x%04x id %d\n", dwDevType, dwFlags, version, id); @@ -953,7 +974,7 @@ static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS device = get_device_ref(id); if ((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) || + ((dwDevType == DIDEVTYPE_JOYSTICK) && (version >= 0x0300 && version < 0x0800)) || (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) { if (dwFlags & DIEDFL_FORCEFEEDBACK) { @@ -962,16 +983,19 @@ static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS if(get_ff(device, NULL) != S_OK) return S_FALSE; } + is_joystick = get_device_property_long(device, CFSTR(kIOHIDDeviceUsageKey)) == kHIDUsage_GD_Joystick; /* Return joystick */ lpddi->guidInstance = DInput_Wine_OsX_Joystick_GUID; lpddi->guidInstance.Data3 = id; - lpddi->guidProduct = DInput_Wine_OsX_Joystick_GUID; + lpddi->guidProduct = DInput_PIDVID_Product_GUID; lpddi->guidProduct.Data1 = make_vid_pid(device); - /* we only support traditional joysticks for now */ - if (version >= 0x0800) - lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); + lpddi->dwDevType = get_device_type(version, is_joystick); + lpddi->dwDevType |= DIDEVTYPE_HID; + lpddi->wUsagePage = 0x01; /* Desktop */ + if (is_joystick) + lpddi->wUsage = 0x04; /* Joystick */ else - lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); + lpddi->wUsage = 0x05; /* Game Pad */ sprintf(lpddi->tszInstanceName, "Joystick %d", id); /* get the device name */ @@ -989,6 +1013,7 @@ static HRESULT joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS char name[MAX_PATH]; char friendly[32]; IOHIDDeviceRef device; + BOOL is_joystick; TRACE("dwDevType %u dwFlags 0x%08x version 0x%04x id %d\n", dwDevType, dwFlags, version, id); @@ -997,7 +1022,7 @@ static HRESULT joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS device = get_device_ref(id); if ((dwDevType == 0) || - ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) || + ((dwDevType == DIDEVTYPE_JOYSTICK) && (version >= 0x0300 && version < 0x0800)) || (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) { if (dwFlags & DIEDFL_FORCEFEEDBACK) { @@ -1006,18 +1031,22 @@ static HRESULT joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINS if(get_ff(device, NULL) != S_OK) return S_FALSE; } + is_joystick = get_device_property_long(device, CFSTR(kIOHIDDeviceUsageKey)) == kHIDUsage_GD_Joystick; /* Return joystick */ lpddi->guidInstance = DInput_Wine_OsX_Joystick_GUID; lpddi->guidInstance.Data3 = id; - lpddi->guidProduct = DInput_Wine_OsX_Joystick_GUID; + lpddi->guidProduct = DInput_PIDVID_Product_GUID; lpddi->guidProduct.Data1 = make_vid_pid(device); - /* we only support traditional joysticks for now */ - if (version >= 0x0800) - lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); + lpddi->dwDevType = get_device_type(version, is_joystick); + lpddi->dwDevType |= DIDEVTYPE_HID; + lpddi->wUsagePage = 0x01; /* Desktop */ + if (is_joystick) + lpddi->wUsage = 0x04; /* Joystick */ else - lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); + lpddi->wUsage = 0x05; /* Game Pad */ sprintf(friendly, "Joystick %d", id); MultiByteToWideChar(CP_ACP, 0, friendly, -1, lpddi->tszInstanceName, MAX_PATH); + /* get the device name */ get_osx_device_name(id, name, MAX_PATH); @@ -1082,7 +1111,7 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput, newDevice->generic.guidInstance = DInput_Wine_OsX_Joystick_GUID; newDevice->generic.guidInstance.Data3 = index; - newDevice->generic.guidProduct = DInput_Wine_OsX_Joystick_GUID; + newDevice->generic.guidProduct = DInput_PIDVID_Product_GUID; newDevice->generic.guidProduct.Data1 = make_vid_pid(device); newDevice->generic.joy_polldev = poll_osx_device_state; @@ -1327,6 +1356,53 @@ static HRESULT joydev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REF return DIERR_DEVICENOTREG; } +static HRESULT WINAPI JoystickWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph) +{ + JoystickImpl *This = impl_from_IDirectInputDevice8W(iface); + + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph); + _dump_DIPROPHEADER(pdiph); + + if (!IS_DIPROP(rguid)) return DI_OK; + + switch (LOWORD(rguid)) { + case (DWORD_PTR) DIPROP_GUIDANDPATH: + { + static const WCHAR formatW[] = {'\\','\\','?','\\','h','i','d','#','v','i','d','_','%','0','4','x','&', + 'p','i','d','_','%','0','4','x','&','%','s','_','%','i',0}; + static const WCHAR miW[] = {'m','i',0}; + static const WCHAR igW[] = {'i','g',0}; + + BOOL is_gamepad; + IOHIDDeviceRef device = get_device_ref(This->id); + LPDIPROPGUIDANDPATH pd = (LPDIPROPGUIDANDPATH)pdiph; + WORD vid = get_device_property_long(device, CFSTR(kIOHIDVendorIDKey)); + WORD pid = get_device_property_long(device, CFSTR(kIOHIDProductIDKey)); + + if (!pid || !vid) + return DIERR_UNSUPPORTED; + + is_gamepad = is_xinput_device(&This->generic.devcaps, vid, pid); + pd->guidClass = GUID_DEVCLASS_HIDCLASS; + sprintfW(pd->wszPath, formatW, vid, pid, is_gamepad ? igW : miW, This->id); + + TRACE("DIPROP_GUIDANDPATH(%s, %s): returning fake path\n", debugstr_guid(&pd->guidClass), debugstr_w(pd->wszPath)); + break; + } + + default: + return JoystickWGenericImpl_GetProperty(iface, rguid, pdiph); + } + + return DI_OK; +} + +static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPDIPROPHEADER pdiph) +{ + JoystickImpl *This = impl_from_IDirectInputDevice8A(iface); + return JoystickWImpl_GetProperty(IDirectInputDevice8W_from_impl(This), rguid, pdiph); +} + static HRESULT osx_set_autocenter(JoystickImpl *This, const DIPROPDWORD *header) { @@ -1418,7 +1494,7 @@ static HRESULT WINAPI JoystickWImpl_CreateEffect(IDirectInputDevice8W *iface, EffectImpl *effect; HRESULT hr; - TRACE("%p %s %p %p %p\n", iface, debugstr_guid(type), params, out, outer); + TRACE("(%p)->(%s %p %p %p)\n", This, debugstr_guid(type), params, out, outer); dump_DIEFFECT(params, type, 0); if(!This->ff){ @@ -1459,7 +1535,7 @@ static HRESULT WINAPI JoystickAImpl_CreateEffect(IDirectInputDevice8A *iface, { JoystickImpl *This = impl_from_IDirectInputDevice8A(iface); - TRACE("%p %s %p %p %p\n", iface, debugstr_guid(type), params, out, outer); + TRACE("(%p)->(%s %p %p %p)\n", This, debugstr_guid(type), params, out, outer); return JoystickWImpl_CreateEffect(&This->generic.base.IDirectInputDevice8W_iface, type, params, out, outer); @@ -1509,7 +1585,7 @@ static const IDirectInputDevice8AVtbl JoystickAvt = IDirectInputDevice2AImpl_Release, JoystickAGenericImpl_GetCapabilities, IDirectInputDevice2AImpl_EnumObjects, - JoystickAGenericImpl_GetProperty, + JoystickAImpl_GetProperty, JoystickAImpl_SetProperty, IDirectInputDevice2AImpl_Acquire, IDirectInputDevice2AImpl_Unacquire, @@ -1545,7 +1621,7 @@ static const IDirectInputDevice8WVtbl JoystickWvt = IDirectInputDevice2WImpl_Release, JoystickWGenericImpl_GetCapabilities, IDirectInputDevice2WImpl_EnumObjects, - JoystickWGenericImpl_GetProperty, + JoystickWImpl_GetProperty, JoystickWImpl_SetProperty, IDirectInputDevice2WImpl_Acquire, IDirectInputDevice2WImpl_Unacquire, diff --git a/dll/directx/wine/dinput/joystick_private.h b/dll/directx/wine/dinput/joystick_private.h index e758cacf6df..545304eabce 100644 --- a/dll/directx/wine/dinput/joystick_private.h +++ b/dll/directx/wine/dinput/joystick_private.h @@ -33,6 +33,9 @@ #define MAX_PROPS 164 struct JoystickGenericImpl; +/* Number of buttons for which to allow remapping */ +#define MAX_MAP_BUTTONS 32 + typedef void joy_polldev_handler(LPDIRECTINPUTDEVICE8A iface); typedef struct JoystickGenericImpl @@ -47,6 +50,7 @@ typedef struct JoystickGenericImpl char *name; int device_axis_count; /* Total number of axes in the device */ int *axis_map; /* User axes remapping */ + int button_map[MAX_MAP_BUTTONS]; /* User button remapping */ LONG deadzone; /* Default dead-zone */ joy_polldev_handler *joy_polldev; @@ -96,5 +100,6 @@ HRESULT WINAPI JoystickWGenericImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface, LP DWORD typeFromGUID(REFGUID guid) DECLSPEC_HIDDEN; void dump_DIEFFECT(LPCDIEFFECT eff, REFGUID guid, DWORD dwFlags) DECLSPEC_HIDDEN; +BOOL is_xinput_device(const DIDEVCAPS *devcaps, WORD vid, WORD pid) DECLSPEC_HIDDEN; #endif /* __WINE_DLLS_DINPUT_JOYSTICK_PRIVATE_H */ diff --git a/dll/directx/wine/dinput/keyboard.c b/dll/directx/wine/dinput/keyboard.c index 642d0c0beb8..0747f5d8c8b 100644 --- a/dll/directx/wine/dinput/keyboard.c +++ b/dll/directx/wine/dinput/keyboard.c @@ -215,6 +215,9 @@ static HRESULT keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVI if (id != 0) return E_FAIL; + if (dwFlags & DIEDFL_FORCEFEEDBACK) + return S_FALSE; + if ((dwDevType == 0) || ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 0x0800)) || (((dwDevType == DI8DEVCLASS_KEYBOARD) || (dwDevType == DI8DEVTYPE_KEYBOARD)) && (version >= 0x0800))) { @@ -233,6 +236,9 @@ static HRESULT keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVI if (id != 0) return E_FAIL; + if (dwFlags & DIEDFL_FORCEFEEDBACK) + return S_FALSE; + if ((dwDevType == 0) || ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 0x0800)) || (((dwDevType == DI8DEVCLASS_KEYBOARD) || (dwDevType == DI8DEVTYPE_KEYBOARD)) && (version >= 0x0800))) { @@ -520,11 +526,6 @@ static HRESULT WINAPI SysKeyboardAImpl_GetDeviceInfo( SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface); TRACE("(this=%p,%p)\n", This, pdidi); - if (pdidi->dwSize != sizeof(DIDEVICEINSTANCEA)) { - WARN(" dinput3 not supported yet...\n"); - return DI_OK; - } - fill_keyboard_dideviceinstanceA(pdidi, This->base.dinput->dwVersion, This->subtype); return DI_OK; @@ -553,7 +554,7 @@ static HRESULT WINAPI SysKeyboardWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, { SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface); - TRACE("(%p) %s,%p\n", iface, debugstr_guid(rguid), pdiph); + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph); _dump_DIPROPHEADER(pdiph); if (!IS_DIPROP(rguid)) return DI_OK; @@ -619,7 +620,8 @@ static HRESULT WINAPI SysKeyboardWImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W ifac LPCWSTR lpszUserName, DWORD dwFlags) { - FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); + SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", This, lpdiaf, debugstr_w(lpszUserName), dwFlags); return _build_action_map(iface, lpdiaf, lpszUserName, dwFlags, DIKEYBOARD_MASK, &c_dfDIKeyboard); } @@ -659,7 +661,8 @@ static HRESULT WINAPI SysKeyboardWImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface, LPCWSTR lpszUserName, DWORD dwFlags) { - FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); + SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", This, lpdiaf, debugstr_w(lpszUserName), dwFlags); return _set_action_map(iface, lpdiaf, lpszUserName, dwFlags, &c_dfDIKeyboard); } @@ -687,6 +690,8 @@ static HRESULT WINAPI SysKeyboardAImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface, hr = SysKeyboardWImpl_SetActionMap(&This->base.IDirectInputDevice8W_iface, &diafW, lpszUserNameW, dwFlags); + lpdiaf->dwCRC = diafW.dwCRC; + HeapFree(GetProcessHeap(), 0, diafW.rgoAction); HeapFree(GetProcessHeap(), 0, lpszUserNameW); diff --git a/dll/directx/wine/dinput/mouse.c b/dll/directx/wine/dinput/mouse.c index 71333593515..ef408bbad5e 100644 --- a/dll/directx/wine/dinput/mouse.c +++ b/dll/directx/wine/dinput/mouse.c @@ -28,6 +28,7 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "wine/winternl.h" #include "winuser.h" #include "winerror.h" #include "winreg.h" @@ -157,6 +158,9 @@ static HRESULT mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEI if (id != 0) return E_FAIL; + if (dwFlags & DIEDFL_FORCEFEEDBACK) + return S_FALSE; + if ((dwDevType == 0) || ((dwDevType == DIDEVTYPE_MOUSE) && (version < 0x0800)) || (((dwDevType == DI8DEVCLASS_POINTER) || (dwDevType == DI8DEVTYPE_MOUSE)) && (version >= 0x0800))) { @@ -175,6 +179,9 @@ static HRESULT mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEI if (id != 0) return E_FAIL; + if (dwFlags & DIEDFL_FORCEFEEDBACK) + return S_FALSE; + if ((dwDevType == 0) || ((dwDevType == DIDEVTYPE_MOUSE) && (version < 0x0800)) || (((dwDevType == DI8DEVCLASS_POINTER) || (dwDevType == DI8DEVTYPE_MOUSE)) && (version >= 0x0800))) { @@ -211,9 +218,9 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput) get_app_key(&hkey, &appkey); if (!get_config_key(hkey, appkey, "MouseWarpOverride", buffer, sizeof(buffer))) { - if (!strcasecmp(buffer, "disable")) + if (!_strnicmp(buffer, "disable", -1)) newDevice->warp_override = WARP_DISABLE; - else if (!strcasecmp(buffer, "force")) + else if (!_strnicmp(buffer, "force", -1)) newDevice->warp_override = WARP_FORCE_ON; } if (appkey) RegCloseKey(appkey); @@ -723,6 +730,9 @@ static HRESULT WINAPI SysMouseWImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface, else if (pdidoi->dwType & DIDFT_BUTTON) wsprintfW(pdidoi->tszName, buttonW, DIDFT_GETINSTANCE(pdidoi->dwType) - 3); + if(pdidoi->dwType & DIDFT_AXIS) + pdidoi->dwFlags |= DIDOI_ASPECTPOSITION; + _dump_OBJECTINSTANCEW(pdidoi); return res; } @@ -758,11 +768,6 @@ static HRESULT WINAPI SysMouseAImpl_GetDeviceInfo( SysMouseImpl *This = impl_from_IDirectInputDevice8A(iface); TRACE("(this=%p,%p)\n", This, pdidi); - if (pdidi->dwSize != sizeof(DIDEVICEINSTANCEA)) { - WARN(" dinput3 not supported yet...\n"); - return DI_OK; - } - fill_mouse_dideviceinstanceA(pdidi, This->base.dinput->dwVersion); return DI_OK; @@ -828,7 +833,8 @@ static HRESULT WINAPI SysMouseWImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface, LPCWSTR lpszUserName, DWORD dwFlags) { - FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); + SysMouseImpl *This = impl_from_IDirectInputDevice8W(iface); + FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", This, lpdiaf, debugstr_w(lpszUserName), dwFlags); return _set_action_map(iface, lpdiaf, lpszUserName, dwFlags, &c_dfDIMouse2); } @@ -856,6 +862,8 @@ static HRESULT WINAPI SysMouseAImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface, hr = SysMouseWImpl_SetActionMap(&This->base.IDirectInputDevice8W_iface, &diafW, lpszUserNameW, dwFlags); + lpdiaf->dwCRC = diafW.dwCRC; + HeapFree(GetProcessHeap(), 0, diafW.rgoAction); HeapFree(GetProcessHeap(), 0, lpszUserNameW); diff --git a/dll/directx/wine/dinput/precomp.h b/dll/directx/wine/dinput/precomp.h index 9504beb6961..d7693306500 100644 --- a/dll/directx/wine/dinput/precomp.h +++ b/dll/directx/wine/dinput/precomp.h @@ -2,8 +2,6 @@ #ifndef __WINE_DINPUT_PRECOMP_H #define __WINE_DINPUT_PRECOMP_H -#include <wine/config.h> - #define WIN32_NO_STATUS #define _INC_WINDOWS #define COM_NO_WINDOWS_H diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 7fc878f7c5c..4146f4e260d 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -30,7 +30,7 @@ dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-4.0 dll/directx/wine/d3dxof # Synced to WineStaging-3.17 dll/directx/wine/ddraw # Synced to WineStaging-3.3 dll/directx/wine/devenum # Synced to WineStaging-4.18 -dll/directx/wine/dinput # Synced to WineStaging-4.0 +dll/directx/wine/dinput # Synced to WineStaging-4.18 dll/directx/wine/dinput8 # Synced to WineStaging-3.3 dll/directx/wine/dmusic # Synced to WineStaging-4.0 dll/directx/wine/dplay # Synced to WineStaging-3.3
5 years, 1 month
1
0
0
0
[reactos] 01/01: [PSDK] Update dinput.h. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1477b2deb78fb2929b5ec…
commit 1477b2deb78fb2929b5ec6175a22921628378029 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Oct 26 13:03:08 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Oct 26 13:03:08 2019 +0100 [PSDK] Update dinput.h. CORE-16441 --- sdk/include/psdk/dinput.h | 57 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/sdk/include/psdk/dinput.h b/sdk/include/psdk/dinput.h index d1d7180c216..cde2f234cb9 100644 --- a/sdk/include/psdk/dinput.h +++ b/sdk/include/psdk/dinput.h @@ -910,8 +910,6 @@ typedef const DIPROPSTRING *LPCDIPROPSTRING; #define DIPROP_INSTANCENAME MAKEDIPROP(13) #define DIPROP_PRODUCTNAME MAKEDIPROP(14) #define DIPROP_JOYSTICKID MAKEDIPROP(15) -#define DIPROP_KEYNAME MAKEDIPROP(20) -#define DIPROP_VIDPID MAKEDIPROP(24) #define DIPROP_KEYNAME MAKEDIPROP(20) #define DIPROP_CPOINTS MAKEDIPROP(21) @@ -2195,6 +2193,61 @@ extern const DIDATAFORMAT c_dfDIJoystick2; #define DIPOV_ANY_4 0xFF004604 #define DIBUTTON_ANY(instance) (0xFF004400 | (instance)) +#define DIVIRTUAL_FLYING_HELICOPTER 0x06000000 +#define DIBUTTON_FLYINGH_MENU 0x060004fd +#define DIBUTTON_FLYINGH_FIRE 0x06001401 +#define DIBUTTON_FLYINGH_WEAPONS 0x06001402 +#define DIBUTTON_FLYINGH_TARGET 0x06001403 +#define DIBUTTON_FLYINGH_DEVICE 0x060044fe +#define DIBUTTON_FLYINGH_PAUSE 0x060044fc +#define DIHATSWITCH_FLYINGH_GLANCE 0x06004601 +#define DIBUTTON_FLYINGH_FIRESECONDARY 0x06004c07 +#define DIBUTTON_FLYINGH_COUNTER 0x06005404 +#define DIBUTTON_FLYINGH_VIEW 0x06006405 +#define DIBUTTON_FLYINGH_GEAR 0x06006406 +#define DIAXIS_FLYINGH_BANK 0x06008a01 +#define DIAXIS_FLYINGH_PITCH 0x06010a02 +#define DIAXIS_FLYINGH_COLLECTIVE 0x06018a03 +#define DIAXIS_FLYINGH_TORQUE 0x06025a04 +#define DIAXIS_FLYINGH_THROTTLE 0x0603da05 +#define DIBUTTON_FLYINGH_FASTER_LINK 0x0603dce0 +#define DIBUTTON_FLYINGH_SLOWER_LINK 0x0603dce8 +#define DIBUTTON_FLYINGH_GLANCE_LEFT_LINK 0x0607c4e4 +#define DIBUTTON_FLYINGH_GLANCE_RIGHT_LINK 0x0607c4ec +#define DIBUTTON_FLYINGH_GLANCE_UP_LINK 0x0607c4e0 +#define DIBUTTON_FLYINGH_GLANCE_DOWN_LINK 0x0607c4e8 + +#define DIVIRTUAL_SPACESIM 0x07000000 +#define DIBUTTON_SPACESIM_FIRE 0x07000401 +#define DIBUTTON_SPACESIM_WEAPONS 0x07000402 +#define DIBUTTON_SPACESIM_TARGET 0x07000403 +#define DIBUTTON_SPACESIM_MENU 0x070004fd +#define DIBUTTON_SPACESIM_VIEW 0x07004404 +#define DIBUTTON_SPACESIM_DISPLAY 0x07004405 +#define DIBUTTON_SPACESIM_RAISE 0x07004406 +#define DIBUTTON_SPACESIM_LOWER 0x07004407 +#define DIBUTTON_SPACESIM_GEAR 0x07004408 +#define DIBUTTON_SPACESIM_FIRESECONDARY 0x07004409 +#define DIBUTTON_SPACESIM_PAUSE 0x070044fc +#define DIBUTTON_SPACESIM_DEVICE 0x070044fe +#define DIHATSWITCH_SPACESIM_GLANCE 0x07004601 +#define DIBUTTON_SPACESIM_LEFT_LINK 0x0700c4e4 +#define DIBUTTON_SPACESIM_RIGHT_LINK 0x0700c4ec +#define DIAXIS_SPACESIM_LATERAL 0x07008201 +#define DIAXIS_SPACESIM_MOVE 0x07010202 +#define DIBUTTON_SPACESIM_FORWARD_LINK 0x070144e0 +#define DIBUTTON_SPACESIM_BACKWARD_LINK 0x070144e8 +#define DIAXIS_SPACESIM_CLIMB 0x0701c204 +#define DIAXIS_SPACESIM_ROTATE 0x07024205 +#define DIBUTTON_SPACESIM_TURN_LEFT_LINK 0x070244e4 +#define DIBUTTON_SPACESIM_TURN_RIGHT_LINK 0x070244ec +#define DIAXIS_SPACESIM_THROTTLE 0x07038203 +#define DIBUTTON_SPACESIM_FASTER_LINK 0x0703c4e0 +#define DIBUTTON_SPACESIM_SLOWER_LINK 0x0703c4e8 +#define DIBUTTON_SPACESIM_GLANCE_UP_LINK 0x0707c4e0 +#define DIBUTTON_SPACESIM_GLANCE_LEFT_LINK 0x0707c4e4 +#define DIBUTTON_SPACESIM_GLANCE_DOWN_LINK 0x0707c4e8 +#define DIBUTTON_SPACESIM_GLANCE_RIGHT_LINK 0x0707c4ec /***************************************************************************** * IDirectInputA interface
5 years, 1 month
1
0
0
0
[reactos] 01/01: [INCLUDE/WINE] Import asm.h from Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=476c99b6439c388aebb5a…
commit 476c99b6439c388aebb5ae6ec98ad88c04cb0c0d Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Oct 26 13:02:43 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Oct 26 13:02:43 2019 +0100 [INCLUDE/WINE] Import asm.h from Wine Staging 4.18. CORE-16441 --- sdk/include/reactos/wine/asm.h | 146 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/sdk/include/reactos/wine/asm.h b/sdk/include/reactos/wine/asm.h new file mode 100644 index 00000000000..41a5de32026 --- /dev/null +++ b/sdk/include/reactos/wine/asm.h @@ -0,0 +1,146 @@ +/* + * Inline assembly support + * + * Copyright 2019 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINE_ASM_H +#define __WINE_WINE_ASM_H + +#if defined(__APPLE__) || (defined(_WIN32) && defined(__i386__)) +# define __ASM_NAME(name) "_" name +#else +# define __ASM_NAME(name) name +#endif + +#if defined(_WIN32) && defined(__i386__) +# define __ASM_STDCALL(name,args) __ASM_NAME(name) "@" #args +#else +# define __ASM_STDCALL(name,args) __ASM_NAME(name) +#endif + +#if defined(__GCC_HAVE_DWARF2_CFI_ASM) || defined(__APPLE__) +# define __ASM_CFI(str) str +#else +# define __ASM_CFI(str) +#endif + +#ifdef __SEH__ +# define __ASM_SEH(str) str +#else +# define __ASM_SEH(str) +#endif + +#ifdef _WIN32 +# define __ASM_FUNC_TYPE(name) ".def " name "; .scl 2; .type 32; .endef" +#elif defined(__APPLE__) +# define __ASM_FUNC_TYPE(name) "" +#elif defined(__arm__) || defined(__arm64__) +# define __ASM_FUNC_TYPE(name) ".type " name ",%function" +#else +# define __ASM_FUNC_TYPE(name) ".type " name ",@function" +#endif + +/* ReactOS */ +#if defined(_MSC_VER) +# define __ASM_DEFINE_FUNC(name,code) +#elif defined(__GNUC__) +# define __ASM_DEFINE_FUNC(name,code) \ + asm(".text\n\t.align 4\n\t.globl " name "\n\t" __ASM_FUNC_TYPE(name) __ASM_SEH("\n\t.seh_proc " name) "\n" name ":\n\t" \ + __ASM_CFI(".cfi_startproc\n\t") code __ASM_CFI("\n\t.cfi_endproc") __ASM_SEH("\n\t.seh_endproc") ); +#else +# define __ASM_DEFINE_FUNC(name,code) void __asm_dummy_##__LINE__(void) { \ + asm(".text\n\t.align 4\n\t.globl " name "\n\t" __ASM_FUNC_TYPE(name) __ASM_SEH("\n\t.seh_proc " name) "\n" name ":\n\t" \ + __ASM_CFI(".cfi_startproc\n\t") code __ASM_CFI("\n\t.cfi_endproc") __ASM_SEH("\n\t.seh_endproc") ); } +#endif + +#define __ASM_GLOBAL_FUNC(name,code) __ASM_DEFINE_FUNC(__ASM_NAME(#name),code) + +#define __ASM_STDCALL_FUNC(name,args,code) __ASM_DEFINE_FUNC(__ASM_STDCALL(#name,args),code) + +/* fastcall support */ + +#if defined(__i386__) && !defined(_WIN32) + +# define DEFINE_FASTCALL1_WRAPPER(func) \ + __ASM_STDCALL_FUNC( __fastcall_ ## func, 4, \ + "popl %eax\n\t" \ + "pushl %ecx\n\t" \ + "pushl %eax\n\t" \ + "jmp " __ASM_STDCALL(#func,4) ) +# define DEFINE_FASTCALL_WRAPPER(func,args) \ + __ASM_STDCALL_FUNC( __fastcall_ ## func, args, \ + "popl %eax\n\t" \ + "pushl %edx\n\t" \ + "pushl %ecx\n\t" \ + "pushl %eax\n\t" \ + "jmp " __ASM_STDCALL(#func,args) ) + +#else /* __i386__ */ + +# define DEFINE_FASTCALL1_WRAPPER(func) /* nothing */ +# define DEFINE_FASTCALL_WRAPPER(func,args) /* nothing */ + +#endif /* __i386__ */ + +/* thiscall support */ + +#if defined(__i386__) && !defined(__MINGW32__) + +# ifdef _MSC_VER + +#ifdef __REACTOS__ +# define DEFINE_THISCALL_WRAPPER(func,args) \ + __declspec(naked) void __thiscall_##func(void) \ + { \ + __asm pop eax \ + __asm push ecx \ + __asm push eax \ + __asm jmp func \ + } +#else +# define DEFINE_THISCALL_WRAPPER(func,args) \ + __declspec(naked) void __thiscall_##func(void) \ + { __asm { \ + pop eax \ + push ecx \ + push eax \ + jmp func \ + } } +#endif +# else /* _MSC_VER */ +# define DEFINE_THISCALL_WRAPPER(func,args) \ + extern void __thiscall_ ## func(void); \ + __ASM_STDCALL_FUNC( __thiscall_ ## func, args, \ + "popl %eax\n\t" \ + "pushl %ecx\n\t" \ + "pushl %eax\n\t" \ + "jmp " __ASM_STDCALL(#func,args) ) +# endif /* _MSC_VER */ + +# define THISCALL(func) (void *)__thiscall_ ## func +# define THISCALL_NAME(func) __ASM_NAME("__thiscall_" #func) + +#else /* __i386__ */ + +# define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */ +# define THISCALL(func) func +# define THISCALL_NAME(func) __ASM_NAME(#func) + +#endif /* __i386__ */ + +#endif /* __WINE_WINE_ASM_H */
5 years, 1 month
1
0
0
0
[reactos] 01/01: [D3DRM_WINETEST] Sync with Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8015bf9f475a78c4981f9…
commit 8015bf9f475a78c4981f98f86756638e96a841cd Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Oct 26 13:02:11 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Oct 26 13:02:11 2019 +0100 [D3DRM_WINETEST] Sync with Wine Staging 4.18. CORE-16441 --- modules/rostests/winetests/d3drm/d3drm.c | 697 +++++++++++++++++++++++++++++-- 1 file changed, 663 insertions(+), 34 deletions(-) diff --git a/modules/rostests/winetests/d3drm/d3drm.c b/modules/rostests/winetests/d3drm/d3drm.c index 5157952d63d..0f9f9cd6ed6 100644 --- a/modules/rostests/winetests/d3drm/d3drm.c +++ b/modules/rostests/winetests/d3drm/d3drm.c @@ -22,10 +22,12 @@ #include <limits.h> #define COBJMACROS +#define _USE_MATH_DEFINES #include <d3d.h> #include <initguid.h> #include <d3drm.h> #include <d3drmwin.h> +#include <math.h> #include "wine/test.h" @@ -58,21 +60,47 @@ static BOOL compare_float(float f, float g, unsigned int ulps) return TRUE; } -#define check_vector(a, b, c, d, e) check_vector_(__LINE__, a, b, c, d, e) -static void check_vector_(unsigned int line, const D3DVECTOR *v, float x, float y, float z, unsigned int ulps) +#define expect_matrix(m, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44, u) \ + expect_matrix_(__LINE__, m, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44, u) +static void expect_matrix_(unsigned int line, D3DRMMATRIX4D m, + float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, + float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44, + unsigned int ulps) { - BOOL ret = compare_float(U1(v)->x, x, ulps) - && compare_float(U2(v)->y, y, ulps) - && compare_float(U3(v)->z, z, ulps); + BOOL equal = compare_float(m[0][0], m11, ulps) && compare_float(m[0][1], m12, ulps) + && compare_float(m[0][2], m13, ulps) && compare_float(m[0][3], m14, ulps) + && compare_float(m[1][0], m21, ulps) && compare_float(m[1][1], m22, ulps) + && compare_float(m[1][2], m23, ulps) && compare_float(m[1][3], m24, ulps) + && compare_float(m[2][0], m31, ulps) && compare_float(m[2][1], m32, ulps) + && compare_float(m[2][2], m33, ulps) && compare_float(m[2][3], m34, ulps) + && compare_float(m[3][0], m41, ulps) && compare_float(m[3][1], m42, ulps) + && compare_float(m[3][2], m43, ulps) && compare_float(m[3][3], m44, ulps); + + ok_(__FILE__, line)(equal, + "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, " + "%.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e}, " + "expected {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, " + "%.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n", + m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3], + m[2][0], m[2][1], m[2][2], m[2][3], m[3][0], m[3][1], m[3][2], m[3][3], + m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44); +} + +#define expect_vector(v, x, y, z, u) expect_vector_(__LINE__, v, x, y, z, u) +static void expect_vector_(unsigned int line, const D3DVECTOR *v, float x, float y, float z, unsigned int ulps) +{ + BOOL equal = compare_float(U1(*v).x, x, ulps) + && compare_float(U2(*v).y, y, ulps) + && compare_float(U3(*v).z, z, ulps); - ok_(__FILE__, line)(ret, "Got unexpected vector {%.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e}.\n", - U1(v)->x, U2(v)->y, U3(v)->z, x, y, z); + ok_(__FILE__, line)(equal, "Got unexpected vector {%.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e}.\n", + U1(*v).x, U2(*v).y, U3(*v).z, x, y, z); } #define vector_eq(a, b) vector_eq_(__LINE__, a, b) static void vector_eq_(unsigned int line, const D3DVECTOR *left, const D3DVECTOR *right) { - check_vector_(line, left, U1(right)->x, U2(right)->y, U3(right)->z, 0); + expect_vector_(line, left, U1(*right).x, U2(*right).y, U3(*right).z, 0); } static D3DRMMATRIX4D identity = { @@ -82,6 +110,42 @@ static D3DRMMATRIX4D identity = { { 0.0f, 0.0f, 0.0f, 1.0f } }; +static void frame_set_transform(IDirect3DRMFrame *frame, + float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, + float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44) +{ + D3DRMMATRIX4D matrix = + { + {m11, m12, m13, m14}, + {m21, m22, m23, m24}, + {m31, m32, m33, m34}, + {m41, m42, m43, m44}, + }; + + IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, matrix); +} + +static void set_vector(D3DVECTOR *v, float x, float y, float z) +{ + U1(*v).x = x; + U2(*v).y = y; + U3(*v).z = z; +} + +static void matrix_sanitise(D3DRMMATRIX4D m) +{ + unsigned int i, j; + + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + if (m[i][j] > -1e-7f && m[i][j] < 1e-7f) + m[i][j] = 0.0f; + } + } +} + static HWND create_window(void) { RECT r = {0, 0, 640, 480}; @@ -458,10 +522,10 @@ static void test_MeshBuilder(void) /* Check that Load method generated default normals */ hr = IDirect3DRMMeshBuilder_GetVertices(pMeshBuilder, NULL, NULL, &val2, n, NULL, NULL); ok(hr == D3DRM_OK, "Cannot get vertices information (hr = %x)\n", hr); - check_vector(&n[0], 0.577350f, 0.577350f, 0.577350f, 32); - check_vector(&n[1], -0.229416f, 0.688247f, 0.688247f, 32); - check_vector(&n[2], -0.229416f, 0.688247f, 0.688247f, 32); - check_vector(&n[3], -0.577350f, 0.577350f, 0.577350f, 32); + expect_vector(&n[0], 0.577350f, 0.577350f, 0.577350f, 32); + expect_vector(&n[1], -0.229416f, 0.688247f, 0.688247f, 32); + expect_vector(&n[2], -0.229416f, 0.688247f, 0.688247f, 32); + expect_vector(&n[3], -0.577350f, 0.577350f, 0.577350f, 32); /* Check that Load method generated default texture coordinates (0.0f, 0.0f) for each vertex */ valu = 1.23f; @@ -557,12 +621,12 @@ static void test_MeshBuilder(void) ok(val1 == 3, "Wrong number of vertices %d (must be 3)\n", val1); ok(val2 == 3, "Wrong number of normals %d (must be 3)\n", val2); ok(val3 == 8, "Wrong number of face data bytes %d (must be 8)\n", val3); - check_vector(&v[0], 0.1f, 0.2f, 0.3f, 32); - check_vector(&v[1], 0.4f, 0.5f, 0.6f, 32); - check_vector(&v[2], 0.7f, 0.8f, 0.9f, 32); - check_vector(&n[0], 1.1f, 1.2f, 1.3f, 32); - check_vector(&n[1], 1.4f, 1.5f, 1.6f, 32); - check_vector(&n[2], 1.7f, 1.8f, 1.9f, 32); + expect_vector(&v[0], 0.1f, 0.2f, 0.3f, 32); + expect_vector(&v[1], 0.4f, 0.5f, 0.6f, 32); + expect_vector(&v[2], 0.7f, 0.8f, 0.9f, 32); + expect_vector(&n[0], 1.1f, 1.2f, 1.3f, 32); + expect_vector(&n[1], 1.4f, 1.5f, 1.6f, 32); + expect_vector(&n[2], 1.7f, 1.8f, 1.9f, 32); ok(f[0] == 3 , "Wrong component f[0] = %d (expected 3)\n", f[0]); ok(f[1] == 0 , "Wrong component f[1] = %d (expected 0)\n", f[1]); ok(f[2] == 0 , "Wrong component f[2] = %d (expected 0)\n", f[2]); @@ -626,13 +690,13 @@ static void test_MeshBuilder(void) ok(val2 == 3, "Wrong number of normals %d (must be 3)\n", val2); ok(val1 == 3, "Wrong number of vertices %d (must be 3)\n", val1); - check_vector(&v[0], 0.1f * 2, 0.2f * 3, 0.3f * 4, 32); - check_vector(&v[1], 0.4f * 2, 0.5f * 3, 0.6f * 4, 32); - check_vector(&v[2], 0.7f * 2, 0.8f * 3, 0.9f * 4, 32); + expect_vector(&v[0], 0.1f * 2, 0.2f * 3, 0.3f * 4, 32); + expect_vector(&v[1], 0.4f * 2, 0.5f * 3, 0.6f * 4, 32); + expect_vector(&v[2], 0.7f * 2, 0.8f * 3, 0.9f * 4, 32); /* Normals are not affected by Scale */ - check_vector(&n[0], 1.1f, 1.2f, 1.3f, 32); - check_vector(&n[1], 1.4f, 1.5f, 1.6f, 32); - check_vector(&n[2], 1.7f, 1.8f, 1.9f, 32); + expect_vector(&n[0], 1.1f, 1.2f, 1.3f, 32); + expect_vector(&n[1], 1.4f, 1.5f, 1.6f, 32); + expect_vector(&n[2], 1.7f, 1.8f, 1.9f, 32); IDirect3DRMMeshBuilder_Release(pMeshBuilder); @@ -1648,6 +1712,9 @@ static void test_object(void) static void test_Viewport(void) { + IDirect3DRMFrame3 *frame3, *d3drm_frame3, *tmp_frame3; + IDirect3DRMFrame *frame, *d3drm_frame, *tmp_frame1; + float field, left, top, right, bottom, front, back; IDirectDrawClipper *clipper; HRESULT hr; IDirect3DRM *d3drm1; @@ -1655,8 +1722,6 @@ static void test_Viewport(void) IDirect3DRM3 *d3drm3; IDirect3DRMDevice *device1, *d3drm_device1; IDirect3DRMDevice3 *device3, *d3drm_device3; - IDirect3DRMFrame *frame; - IDirect3DRMFrame3 *frame3; IDirect3DRMViewport *viewport; IDirect3DRMViewport2 *viewport2; IDirect3DViewport *d3d_viewport; @@ -1696,8 +1761,12 @@ static void test_Viewport(void) hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame); ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr); + hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &tmp_frame1); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &frame3); ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface (hr = %x).\n", hr); + hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &tmp_frame3); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); ref1 = get_refcount((IUnknown *)d3drm1); ref2 = get_refcount((IUnknown *)d3drm2); @@ -1723,6 +1792,20 @@ static void test_Viewport(void) ok(device1 == d3drm_device1, "Expected device returned = %p, got %p.\n", device1, d3drm_device1); IDirect3DRMDevice_Release(d3drm_device1); + hr = IDirect3DRMViewport_SetCamera(viewport, NULL); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + ok(frame == d3drm_frame, "Expected frame returned = %p, got %p.\n", frame, d3drm_frame); + IDirect3DRMFrame_Release(d3drm_frame); + + hr = IDirect3DRMViewport_SetCamera(viewport, tmp_frame1); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + ok(d3drm_frame == tmp_frame1, "Got unexpected frame %p, expected %p.\n", d3drm_frame, tmp_frame1); + IDirect3DRMFrame_Release(d3drm_frame); + IDirect3DRMViewport_Release(viewport); ref4 = get_refcount((IUnknown *)d3drm1); ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4); @@ -1753,6 +1836,20 @@ static void test_Viewport(void) ok(device1 == d3drm_device1, "Expected device returned = %p, got %p.\n", device1, d3drm_device1); IDirect3DRMDevice_Release(d3drm_device1); + hr = IDirect3DRMViewport_SetCamera(viewport, NULL); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + ok(frame == d3drm_frame, "Expected frame returned = %p, got %p.\n", frame, d3drm_frame); + IDirect3DRMFrame_Release(d3drm_frame); + + hr = IDirect3DRMViewport_SetCamera(viewport, tmp_frame1); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + ok(d3drm_frame == tmp_frame1, "Got unexpected frame %p, expected %p.\n", d3drm_frame, tmp_frame1); + IDirect3DRMFrame_Release(d3drm_frame); + IDirect3DRMViewport_Release(viewport); ref4 = get_refcount((IUnknown *)d3drm1); ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4); @@ -1786,6 +1883,20 @@ static void test_Viewport(void) ok(device3 == d3drm_device3, "Expected device returned = %p, got %p.\n", device3, d3drm_device3); IDirect3DRMDevice3_Release(d3drm_device3); + hr = IDirect3DRMViewport2_SetCamera(viewport2, NULL); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport2_GetCamera(viewport2, &d3drm_frame3); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + ok(frame3 == d3drm_frame3, "Expected frame returned = %p, got %p.\n", frame3, d3drm_frame3); + IDirect3DRMFrame3_Release(d3drm_frame3); + + hr = IDirect3DRMViewport2_SetCamera(viewport2, tmp_frame3); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport2_GetCamera(viewport2, &d3drm_frame3); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + ok(d3drm_frame3 == tmp_frame3, "Got unexpected frame %p, expected %p.\n", d3drm_frame3, tmp_frame3); + IDirect3DRMFrame3_Release(d3drm_frame3); + IDirect3DRMViewport2_Release(viewport2); ref4 = get_refcount((IUnknown *)d3drm1); ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4); @@ -1799,42 +1910,72 @@ static void test_Viewport(void) ok(ref4 == frame_ref2, "Expected ref4 == frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4); /* Test all failures together */ + viewport = (IDirect3DRMViewport *)0xdeadbeef; hr = IDirect3DRM_CreateViewport(d3drm1, NULL, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport); + viewport = (IDirect3DRMViewport *)0xdeadbeef; hr = IDirect3DRM_CreateViewport(d3drm1, device1, NULL, rc.left, rc.top, rc.right, rc.bottom, &viewport); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport); + viewport = (IDirect3DRMViewport *)0xdeadbeef; hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1, &viewport); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport); + viewport = (IDirect3DRMViewport *)0xdeadbeef; hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom, &viewport); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport); + viewport = (IDirect3DRMViewport *)0xdeadbeef; hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right, rc.bottom + 1, &viewport); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport); hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right, rc.bottom, NULL); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + viewport = (IDirect3DRMViewport *)0xdeadbeef; hr = IDirect3DRM2_CreateViewport(d3drm2, NULL, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport); + viewport = (IDirect3DRMViewport *)0xdeadbeef; hr = IDirect3DRM2_CreateViewport(d3drm2, device1, NULL, rc.left, rc.top, rc.right, rc.bottom, &viewport); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport); + viewport = (IDirect3DRMViewport *)0xdeadbeef; hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1, &viewport); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport); + viewport = (IDirect3DRMViewport *)0xdeadbeef; hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom, &viewport); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport); + viewport = (IDirect3DRMViewport *)0xdeadbeef; hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right, rc.bottom + 1, &viewport); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + ok(!viewport, "Expected viewport returned == NULL, got %p.\n", viewport); hr = IDirect3DRM2_CreateViewport(d3drm2, device1, frame, rc.left, rc.top, rc.right, rc.bottom, NULL); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef; hr = IDirect3DRM3_CreateViewport(d3drm3, NULL, frame3, rc.left, rc.top, rc.right, rc.bottom, &viewport2); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2); + viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef; hr = IDirect3DRM3_CreateViewport(d3drm3, device3, NULL, rc.left, rc.top, rc.right, rc.bottom, &viewport2); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2); + viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef; hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom + 1, &viewport2); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2); + viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef; hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom, &viewport2); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2); + viewport2 = (IDirect3DRMViewport2 *)0xdeadbeef; hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right, rc.bottom + 1, &viewport2); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + ok(!viewport2, "Expected viewport returned == NULL, got %p.\n", viewport2); hr = IDirect3DRM3_CreateViewport(d3drm3, device3, frame3, rc.left, rc.top, rc.right, rc.bottom, NULL); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); @@ -1994,6 +2135,32 @@ static void test_Viewport(void) ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); hr = IDirect3DRMViewport_GetDevice(viewport, &d3drm_device1); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + hr = IDirect3DRMViewport_GetCamera(viewport, &d3drm_frame); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + field = IDirect3DRMViewport_GetField(viewport); + ok(field == -1.0f, "Got unexpected field %.8e.\n", field); + left = right = bottom = top = 10.0f; + hr = IDirect3DRMViewport_GetPlane(viewport, &left, &right, &bottom, &top); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + ok(left == 10.0f, "Got unexpected left %.8e.\n", left); + ok(right == 10.0f, "Got unexpected right %.8e.\n", right); + ok(bottom == 10.0f, "Got unexpected bottom %.8e.\n", bottom); + ok(top == 10.0f, "Got unexpected top %.8e.\n", top); + front = IDirect3DRMViewport_GetFront(viewport); + ok(front == -1.0f, "Got unexpected front %.8e\n", front); + back = IDirect3DRMViewport_GetBack(viewport); + ok(back == -1.0f, "Got unexpected back %.8e\n", back); + + hr = IDirect3DRMViewport_SetCamera(viewport, frame); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport_SetField(viewport, 0.5f); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport_SetPlane(viewport, -0.5f, 0.5f, -0.5f, 0.5f); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport_SetFront(viewport, 1.0f); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport_SetBack(viewport, 100.0f); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); /* Test all failures together */ hr = IDirect3DRMViewport_Init(viewport, NULL, frame, rc.left, rc.top, rc.right, rc.bottom); @@ -2057,8 +2224,70 @@ static void test_Viewport(void) ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY); IDirect3DViewport_Release(d3d_viewport); + field = IDirect3DRMViewport_GetField(viewport); + ok(field == 0.5f, "Got unexpected field %.8e.\n", field); + hr = IDirect3DRMViewport_GetPlane(viewport, &left, &right, &bottom, &top); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + ok(left == -0.5f, "Got unexpected left %.8e.\n", left); + ok(right == 0.5f, "Got unexpected right %.8e.\n", right); + ok(bottom == -0.5f, "Got unexpected bottom %.8e.\n", bottom); + ok(top == 0.5f, "Got unexpected top %.8e.\n", top); + front = IDirect3DRMViewport_GetFront(viewport); + ok(front == 1.0f, "Got unexpected front %.8e.\n", front); + back = IDirect3DRMViewport_GetBack(viewport); + ok(back == 100.0f, "Got unexpected back %.8e.\n", back); + + hr = IDirect3DRMViewport_SetField(viewport, 1.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + field = IDirect3DRMViewport_GetField(viewport); + ok(field == 1.0f, "Got unexpected field %.8e.\n", field); + hr = IDirect3DRMViewport_GetPlane(viewport, &left, &right, &bottom, &top); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + ok(left == -1.0f, "Got unexpected left %.8e.\n", left); + ok(right == 1.0f, "Got unexpected right %.8e.\n", right); + ok(bottom == -1.0f, "Got unexpected bottom %.8e.\n", bottom); + ok(top == 1.0f, "Got unexpected top %.8e.\n", top); + + hr = IDirect3DRMViewport_SetPlane(viewport, 5.0f, 3.0f, 2.0f, 0.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + field = IDirect3DRMViewport_GetField(viewport); + ok(field == -1.0f, "Got unexpected field %.8e.\n", field); + hr = IDirect3DRMViewport_GetPlane(viewport, &left, &right, &bottom, &top); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + ok(left == 5.0f, "Got unexpected left %.8e.\n", left); + ok(right == 3.0f, "Got unexpected right %.8e.\n", right); + ok(bottom == 2.0f, "Got unexpected bottom %.8e.\n", bottom); + ok(top == 0.0f, "Got unexpected top %.8e.\n", top); + hr = IDirect3DRMViewport_SetFront(viewport, 2.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + front = IDirect3DRMViewport_GetFront(viewport); + ok(front == 2.0f, "Got unexpected front %.8e.\n", front); + hr = IDirect3DRMViewport_SetBack(viewport, 200.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + back = IDirect3DRMViewport_GetBack(viewport); + ok(back == 200.0f, "Got unexpected back %.8e.\n", back); + hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right, rc.bottom); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + hr = IDirect3DRMViewport_GetDevice(viewport, NULL); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + hr = IDirect3DRMViewport_GetDirect3DViewport(viewport, NULL); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + hr = IDirect3DRMViewport_GetCamera(viewport, NULL); + ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport_SetField(viewport, 0.0f); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + hr = IDirect3DRMViewport_SetField(viewport, -1.0f); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + hr = IDirect3DRMViewport_SetFront(viewport, 0.0f); + ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport_SetFront(viewport, -1.0f); + ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr); + front = IDirect3DRMViewport_GetFront(viewport); + hr = IDirect3DRMViewport_SetBack(viewport, front); + ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport_SetBack(viewport, front / 2.0f); + ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr); IDirect3DRMViewport_Release(viewport); ref4 = get_refcount((IUnknown *)d3drm1); @@ -2089,6 +2318,32 @@ static void test_Viewport(void) ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); hr = IDirect3DRMViewport2_GetDevice(viewport2, &d3drm_device3); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + hr = IDirect3DRMViewport2_GetCamera(viewport2, &d3drm_frame3); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + field = IDirect3DRMViewport2_GetField(viewport2); + ok(field == -1.0f, "Got unexpected field %.8e.\n", field); + left = right = bottom = top = 10.0f; + hr = IDirect3DRMViewport2_GetPlane(viewport2, &left, &right, &bottom, &top); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + ok(left == 10.0f, "Got unexpected left %.8e.\n", left); + ok(right == 10.0f, "Got unexpected right %.8e.\n", right); + ok(bottom == 10.0f, "Got unexpected bottom %.8e.\n", bottom); + ok(top == 10.0f, "Got unexpected top %.8e.\n", top); + front = IDirect3DRMViewport2_GetFront(viewport2); + ok(front == -1.0f, "Got unexpected front %.8e\n", front); + back = IDirect3DRMViewport2_GetBack(viewport2); + ok(back == -1.0f, "Got unexpected back %.8e\n", back); + + hr = IDirect3DRMViewport2_SetCamera(viewport2, frame3); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport2_SetField(viewport2, 0.5f); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport2_SetPlane(viewport2, -0.5f, 0.5f, -0.5f, 0.5f); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport2_SetFront(viewport2, 1.0f); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport2_SetBack(viewport2, 100.0f); + ok(hr == D3DRMERR_BADOBJECT, "Got unexpected hr %#x.\n", hr); hr = IDirect3DRMViewport2_Init(viewport2, NULL, frame3, rc.left, rc.top, rc.right, rc.bottom); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); @@ -2145,8 +2400,70 @@ static void test_Viewport(void) ok(vp.dvMaxY == expected_val, "Expected dvMaxY = %f, got %f.\n", expected_val, vp.dvMaxY); IDirect3DViewport_Release(d3d_viewport); + field = IDirect3DRMViewport2_GetField(viewport2); + ok(field == 0.5f, "Got unexpected field %.8e.\n", field); + hr = IDirect3DRMViewport2_GetPlane(viewport2, &left, &right, &bottom, &top); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + ok(left == -0.5f, "Got unexpected left %.8e.\n", left); + ok(right == 0.5f, "Got unexpected right %.8e.\n", right); + ok(bottom == -0.5f, "Got unexpected bottom %.8e.\n", bottom); + ok(top == 0.5f, "Got unexpected top %.8e.\n", top); + front = IDirect3DRMViewport2_GetFront(viewport2); + ok(front == 1.0f, "Got unexpected front %.8e.\n", front); + back = IDirect3DRMViewport2_GetBack(viewport2); + ok(back == 100.0f, "Got unexpected back %.8e.\n", back); + + hr = IDirect3DRMViewport2_SetField(viewport2, 1.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + field = IDirect3DRMViewport2_GetField(viewport2); + ok(field == 1.0f, "Got unexpected field %.8e.\n", field); + hr = IDirect3DRMViewport2_GetPlane(viewport2, &left, &right, &bottom, &top); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + ok(left == -1.0f, "Got unexpected left %.8e.\n", left); + ok(right == 1.0f, "Got unexpected right %.8e.\n", right); + ok(bottom == -1.0f, "Got unexpected bottom %.8e.\n", bottom); + ok(top == 1.0f, "Got unexpected top %.8e.\n", top); + + hr = IDirect3DRMViewport2_SetPlane(viewport2, 5.0f, 3.0f, 2.0f, 0.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + field = IDirect3DRMViewport2_GetField(viewport2); + ok(field == -1.0f, "Got unexpected field %.8e.\n", field); + hr = IDirect3DRMViewport2_GetPlane(viewport2, &left, &right, &bottom, &top); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + ok(left == 5.0f, "Got unexpected left %.8e.\n", left); + ok(right == 3.0f, "Got unexpected right %.8e.\n", right); + ok(bottom == 2.0f, "Got unexpected bottom %.8e.\n", bottom); + ok(top == 0.0f, "Got unexpected top %.8e.\n", top); + hr = IDirect3DRMViewport2_SetFront(viewport2, 2.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + front = IDirect3DRMViewport2_GetFront(viewport2); + ok(front == 2.0f, "Got unexpected front %.8e.\n", front); + hr = IDirect3DRMViewport2_SetBack(viewport2, 200.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + back = IDirect3DRMViewport2_GetBack(viewport2); + ok(back == 200.0f, "Got unexpected back %.8e.\n", back); + hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + hr = IDirect3DRMViewport2_GetDevice(viewport2, NULL); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, NULL); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + hr = IDirect3DRMViewport2_GetCamera(viewport2, NULL); + ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport2_SetField(viewport2, 0.0f); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + hr = IDirect3DRMViewport2_SetField(viewport2, -1.0f); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + hr = IDirect3DRMViewport2_SetFront(viewport2, 0.0f); + ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport2_SetFront(viewport2, -1.0f); + ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr); + front = IDirect3DRMViewport2_GetFront(viewport2); + hr = IDirect3DRMViewport2_SetBack(viewport2, front); + ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMViewport2_SetBack(viewport2, front / 2.0f); + ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr); IDirect3DRMViewport2_Release(viewport2); ref4 = get_refcount((IUnknown *)d3drm1); @@ -2173,6 +2490,7 @@ static void test_Viewport(void) ref4 = get_refcount((IUnknown *)frame3); ok(ref4 == frame_ref2, "Expected ref4 == frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4); + IDirect3DRMFrame3_Release(tmp_frame3); IDirect3DRMFrame3_Release(frame3); ref4 = get_refcount((IUnknown *)d3drm1); ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4); @@ -2181,6 +2499,7 @@ static void test_Viewport(void) ref4 = get_refcount((IUnknown *)d3drm3); ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %u, ref4 = %u.\n", initial_ref3, ref4); + IDirect3DRMFrame3_Release(tmp_frame1); IDirect3DRMFrame_Release(frame); ref4 = get_refcount((IUnknown *)d3drm1); ok(ref4 == initial_ref1, "Expected ref4 == initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4); @@ -2711,21 +3030,262 @@ cleanup: static void test_frame_transform(void) { - HRESULT hr; + IDirect3DRMFrame *frame, *subframe; + D3DRMMATRIX4D matrix, add_matrix; IDirect3DRM *d3drm; - IDirect3DRMFrame *frame; - D3DRMMATRIX4D matrix; + D3DVECTOR v1, v2; + HRESULT hr; hr = Direct3DRMCreate(&d3drm); - ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DRM_CreateFrame(d3drm, NULL, &frame); - ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DRMFrame_GetTransform(frame, matrix); - ok(hr == D3DRM_OK, "IDirect3DRMFrame_GetTransform returned hr = %x\n", hr); - ok(!memcmp(matrix, identity, sizeof(D3DRMMATRIX4D)), "Returned matrix is not identity\n"); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + expect_matrix(matrix, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, 0); + + memcpy(add_matrix, identity, sizeof(add_matrix)); + add_matrix[3][0] = 3.0f; + add_matrix[3][1] = 3.0f; + add_matrix[3][2] = 3.0f; + + frame_set_transform(frame, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, add_matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + expect_matrix(matrix, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 3.0f, 3.0f, 3.0f, 1.0f, 1); + + frame_set_transform(frame, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_BEFORE, add_matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + expect_matrix(matrix, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 6.0f, 6.0f, 6.0f, 1.0f, 1); + + frame_set_transform(frame, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_AFTER, add_matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + expect_matrix(matrix, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 3.0f, 3.0f, 3.0f, 1.0f, 1); + + add_matrix[3][3] = 2.0f; + hr = IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, add_matrix); + ok(hr == D3DRMERR_BADVALUE, "Got unexpected hr %#x.\n", hr); + frame_set_transform(frame, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + hr = IDirect3DRMFrame_AddTranslation(frame, D3DRMCOMBINE_REPLACE, 3.0f, 3.0f, 3.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + expect_matrix(matrix, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 3.0f, 3.0f, 3.0f, 1.0f, 1); + + frame_set_transform(frame, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + hr = IDirect3DRMFrame_AddTranslation(frame, D3DRMCOMBINE_BEFORE, 3.0f, 3.0f, 3.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + expect_matrix(matrix, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 6.0f, 6.0f, 6.0f, 1.0f, 1); + + frame_set_transform(frame, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + hr = IDirect3DRMFrame_AddTranslation(frame, D3DRMCOMBINE_AFTER, 3.0f, 3.0f, 3.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + expect_matrix(matrix, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 3.0f, 3.0f, 3.0f, 1.0f, 1); + + frame_set_transform(frame, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 3.0f, 3.0f, 3.0f, 1.0f); + hr = IDirect3DRMFrame_AddScale(frame, D3DRMCOMBINE_REPLACE, 2.0f, 2.0f, 2.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + expect_matrix(matrix, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, 1); + + frame_set_transform(frame, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 3.0f, 3.0f, 3.0f, 1.0f); + hr = IDirect3DRMFrame_AddScale(frame, D3DRMCOMBINE_BEFORE, 2.0f, 2.0f, 2.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + expect_matrix(matrix, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 3.0f, 3.0f, 3.0f, 1.0f, 1); + + frame_set_transform(frame, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 3.0f, 3.0f, 3.0f, 1.0f); + hr = IDirect3DRMFrame_AddScale(frame, D3DRMCOMBINE_AFTER, 2.0f, 2.0f, 2.0f); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + expect_matrix(matrix, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 2.0f, 0.0f, + 6.0f, 6.0f, 6.0f, 1.0f, 1); + + frame_set_transform(frame, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 3.0f, 3.0f, 3.0f, 1.0f); + hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 1.0f, 0.0f, 0.0f, M_PI_2); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + matrix_sanitise(matrix); + expect_matrix(matrix, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, 1); + + frame_set_transform(frame, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 3.0f, 3.0f, 3.0f, 1.0f); + hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_BEFORE, 1.0f, 0.0f, 0.0f, M_PI_2); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + matrix_sanitise(matrix); + expect_matrix(matrix, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, + 3.0f, 3.0f, 3.0f, 1.0f, 1); + + frame_set_transform(frame, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 3.0f, 3.0f, 3.0f, 1.0f); + hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_AFTER, 1.0f, 0.0f, 0.0f, M_PI_2); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + matrix_sanitise(matrix); + expect_matrix(matrix, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, + 3.0f, -3.0f, 3.0f, 1.0f, 1); + + hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 0.0f, 0.0f, 1.0f, M_PI_2); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + matrix_sanitise(matrix); + expect_matrix(matrix, + 0.0f, 1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, 1); + + hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 0.0f, 0.0f, 0.0f, M_PI_2); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DRMFrame_GetTransform(frame, matrix); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + matrix_sanitise(matrix); + expect_matrix(matrix, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, 1); + + frame_set_transform(frame, + 2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 4.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 8.0f, 0.0f, + 64.0f, 64.0f, 64.0f, 1.0f); + hr = IDirect3DRM_CreateFrame(d3drm, frame, &subframe); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + frame_set_transform(subframe, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 11.0f, 11.0f, 11.0f, 1.0f); + set_vector(&v1, 3.0f, 5.0f, 7.0f); + + hr = IDirect3DRMFrame_Transform(frame, &v2, &v1); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + expect_vector(&v2, 70.0f, 84.0f, 120.0f, 1); + + hr = IDirect3DRMFrame_Transform(subframe, &v2, &v1); + ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr); + expect_vector(&v2, 92.0f, 128.0f, 208.0f, 1); + + IDirect3DRMFrame_Release(subframe); IDirect3DRMFrame_Release(frame); IDirect3DRM_Release(d3drm); } @@ -3268,7 +3828,7 @@ static void test_device_qi(void) ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr); hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, rc.right, rc.bottom, &device3); ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice3 interface (hr = %x)\n", hr); - IDirect3DRMDevice3_QueryInterface(device3, &IID_IUnknown, (void **)&unknown); + hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IUnknown, (void **)&unknown); ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMDevice3 (hr = %x)\n", hr); IDirect3DRMDevice3_Release(device3); test_qi("device3_qi", unknown, &IID_IUnknown, tests, ARRAY_SIZE(tests)); @@ -5370,6 +5930,68 @@ static void test_create_device_from_d3d3(void) DestroyWindow(window); } +static void test_create_device_1(void) +{ + IDirect3DRM *d3drm = NULL; + IDirect3DRMDevice *device = (IDirect3DRMDevice *)0xdeadbeef; + HRESULT hr; + + hr = Direct3DRMCreate(&d3drm); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr); + + hr = IDirect3DRM_CreateDevice(d3drm, 640, 480, &device); + ok(hr == D3DRMERR_BADDEVICE, "Expected hr == D3DRMERR_BADDEVICE, got %x.\n", hr); + ok(device == NULL, "Expected device returned == NULL, got %p.\n", device); + hr = IDirect3DRM_CreateDevice(d3drm, 640, 480, NULL); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); + + IDirect3DRM_Release(d3drm); +} + +static void test_create_device_2(void) +{ + IDirect3DRM *d3drm = NULL; + IDirect3DRM2 *d3drm2 = NULL; + IDirect3DRMDevice2 *device2 = (IDirect3DRMDevice2 *)0xdeadbeef; + HRESULT hr; + + hr = Direct3DRMCreate(&d3drm); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr); + hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM2, (void **)&d3drm2); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr); + + hr = IDirect3DRM2_CreateDevice(d3drm2, 640, 480, &device2); + ok(hr == D3DRMERR_BADDEVICE, "Expected hr == D3DRMERR_BADDEVICE, got %x.\n", hr); + ok(device2 == NULL, "Expected device returned == NULL, got %p.\n", device2); + hr = IDirect3DRM2_CreateDevice(d3drm2, 640, 480, NULL); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); + + IDirect3DRM2_Release(d3drm2); + IDirect3DRM_Release(d3drm); +} + +static void test_create_device_3(void) +{ + IDirect3DRM *d3drm = NULL; + IDirect3DRM3 *d3drm3 = NULL; + IDirect3DRMDevice3 *device3 = (IDirect3DRMDevice3 *)0xdeadbeef; + HRESULT hr; + + hr = Direct3DRMCreate(&d3drm); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x).\n", hr); + hr = IDirect3DRM_QueryInterface(d3drm, &IID_IDirect3DRM3, (void **)&d3drm3); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface (hr = %x).\n", hr); + + hr = IDirect3DRM3_CreateDevice(d3drm3, 640, 480, &device3); + ok(hr == D3DRMERR_BADDEVICE, "Expected hr == D3DRMERR_BADDEVICE, got %x.\n", hr); + ok(device3 == NULL, "Expected device returned == NULL, got %p.\n", device3); + hr = IDirect3DRM3_CreateDevice(d3drm3, 640, 480, NULL); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); + + IDirect3DRM3_Release(d3drm3); + IDirect3DRM_Release(d3drm); +} + static char *create_bitmap(unsigned int w, unsigned int h, BOOL palettized) { unsigned int bpp = palettized ? 8 : 24; @@ -6342,10 +6964,12 @@ static void test_viewport_clear1(void) ret_color = IDirect3DRMFrame_GetSceneBackground(camera1); ok(ret_color == 0xff00ff00, "Expected scene color returned == 0xff00ff00, got %#x.\n", ret_color); + CHECK_REFCOUNT(frame1, 1); hr = IDirect3DRMViewport_Clear(viewport1); ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr); ret_color = get_surface_color(surface, 320, 240); ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", ret_color); + CHECK_REFCOUNT(frame1, 1); hr = IDirect3DRMFrame_SetSceneBackgroundRGB(frame1, 0.0f, 0.0f, 1.0f); ok(SUCCEEDED(hr), "Cannot set scene background RGB (hr = %#x)\n", hr); @@ -6545,10 +7169,12 @@ static void test_viewport_clear2(void) ret_color = IDirect3DRMFrame3_GetSceneBackground(camera3); ok(ret_color == 0xff00ff00, "Expected scene color returned == 0xff00ff00, got %#x.\n", ret_color); + CHECK_REFCOUNT(frame3, 1); hr = IDirect3DRMViewport2_Clear(viewport2, D3DRMCLEAR_ALL); ok(SUCCEEDED(hr), "Cannot clear viewport (hr = %#x).\n", hr); ret_color = get_surface_color(surface, 320, 240); ok(compare_color(ret_color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", ret_color); + CHECK_REFCOUNT(frame3, 1); hr = IDirect3DRMViewport2_GetDirect3DViewport(viewport2, &d3d_viewport); ok(SUCCEEDED(hr), "Cannot get IDirect3DViewport interface (hr = %#x).\n", hr); @@ -7432,6 +8058,9 @@ START_TEST(d3drm) test_create_device_from_d3d1(); test_create_device_from_d3d2(); test_create_device_from_d3d3(); + test_create_device_1(); + test_create_device_2(); + test_create_device_3(); test_load_texture(); test_texture_qi(); test_viewport_qi();
5 years, 1 month
1
0
0
0
[reactos] 01/01: [D3DRM] Sync with Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3d017d715063905f01f5f…
commit 3d017d715063905f01f5fb6f6bb1b0ac5a19c2f2 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Oct 26 13:01:38 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Oct 26 13:01:38 2019 +0100 [D3DRM] Sync with Wine Staging 4.18. CORE-16441 --- dll/directx/wine/d3drm/d3drm.c | 65 ++++---- dll/directx/wine/d3drm/d3drm_main.c | 3 - dll/directx/wine/d3drm/d3drm_private.h | 31 +++- dll/directx/wine/d3drm/device.c | 3 - dll/directx/wine/d3drm/face.c | 3 - dll/directx/wine/d3drm/frame.c | 282 ++++++++++++++++++++++++++++----- dll/directx/wine/d3drm/light.c | 3 - dll/directx/wine/d3drm/material.c | 3 - dll/directx/wine/d3drm/math.c | 3 - dll/directx/wine/d3drm/meshbuilder.c | 3 - dll/directx/wine/d3drm/texture.c | 3 - dll/directx/wine/d3drm/viewport.c | 155 +++++++++++++++--- media/doc/README.WINE | 2 +- 13 files changed, 423 insertions(+), 136 deletions(-) diff --git a/dll/directx/wine/d3drm/d3drm.c b/dll/directx/wine/d3drm/d3drm.c index d0f20235a8f..0b3af02a5ab 100644 --- a/dll/directx/wine/d3drm/d3drm.c +++ b/dll/directx/wine/d3drm/d3drm.c @@ -20,9 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "d3drm_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3drm); @@ -416,17 +413,13 @@ static HRESULT WINAPI d3drm1_CreateMaterial(IDirect3DRM *iface, static HRESULT WINAPI d3drm1_CreateDevice(IDirect3DRM *iface, DWORD width, DWORD height, IDirect3DRMDevice **device) { - struct d3drm_device *object; - HRESULT hr; - - FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device); - - if (FAILED(hr = d3drm_device_create(&object, iface))) - return hr; + TRACE("iface %p, width %u, height %u, device %p.\n", iface, width, height, device); - *device = &object->IDirect3DRMDevice_iface; + if (!device) + return D3DRMERR_BADVALUE; + *device = NULL; - return D3DRM_OK; + return D3DRMERR_BADDEVICE; } static HRESULT WINAPI d3drm1_CreateDeviceFromSurface(IDirect3DRM *iface, GUID *guid, @@ -575,10 +568,12 @@ static HRESULT WINAPI d3drm1_CreateViewport(IDirect3DRM *iface, IDirect3DRMDevic TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n", iface, device, camera, x, y, width, height, viewport); - if (!device || !camera) - return D3DRMERR_BADOBJECT; if (!viewport) return D3DRMERR_BADVALUE; + *viewport = NULL; + + if (!device || !camera) + return D3DRMERR_BADOBJECT; if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMDevice3, (void **)&device3))) return hr; @@ -972,18 +967,13 @@ static HRESULT WINAPI d3drm2_CreateMaterial(IDirect3DRM2 *iface, static HRESULT WINAPI d3drm2_CreateDevice(IDirect3DRM2 *iface, DWORD width, DWORD height, IDirect3DRMDevice2 **device) { - struct d3drm *d3drm = impl_from_IDirect3DRM2(iface); - struct d3drm_device *object; - HRESULT hr; - - FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device); - - if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface))) - return hr; + TRACE("iface %p, width %u, height %u, device %p.\n", iface, width, height, device); - *device = &object->IDirect3DRMDevice2_iface; + if (!device) + return D3DRMERR_BADVALUE; + *device = NULL; - return D3DRM_OK; + return D3DRMERR_BADDEVICE; } static HRESULT WINAPI d3drm2_CreateDeviceFromSurface(IDirect3DRM2 *iface, GUID *guid, @@ -1102,10 +1092,12 @@ static HRESULT WINAPI d3drm2_CreateViewport(IDirect3DRM2 *iface, IDirect3DRMDevi TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n", iface, device, camera, x, y, width, height, viewport); - if (!device || !camera) - return D3DRMERR_BADOBJECT; if (!viewport) return D3DRMERR_BADVALUE; + *viewport = NULL; + + if (!device || !camera) + return D3DRMERR_BADOBJECT; if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMDevice3, (void **)&device3))) return hr; @@ -1611,18 +1603,13 @@ static HRESULT WINAPI d3drm3_CreateMaterial(IDirect3DRM3 *iface, static HRESULT WINAPI d3drm3_CreateDevice(IDirect3DRM3 *iface, DWORD width, DWORD height, IDirect3DRMDevice3 **device) { - struct d3drm *d3drm = impl_from_IDirect3DRM3(iface); - struct d3drm_device *object; - HRESULT hr; - - FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device); + TRACE("iface %p, width %u, height %u, device %p.\n", iface, width, height, device); - if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface))) - return hr; - - *device = &object->IDirect3DRMDevice3_iface; + if (!device) + return D3DRMERR_BADVALUE; + *device = NULL; - return D3DRM_OK; + return D3DRMERR_BADDEVICE; } static HRESULT WINAPI d3drm3_CreateDeviceFromSurface(IDirect3DRM3 *iface, GUID *guid, @@ -1778,10 +1765,12 @@ static HRESULT WINAPI d3drm3_CreateViewport(IDirect3DRM3 *iface, IDirect3DRMDevi TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n", iface, device, camera, x, y, width, height, viewport); - if (!device || !camera) - return D3DRMERR_BADOBJECT; if (!viewport) return D3DRMERR_BADVALUE; + *viewport = NULL; + + if (!device || !camera) + return D3DRMERR_BADOBJECT; if (FAILED(hr = d3drm_viewport_create(&object, &d3drm->IDirect3DRM_iface))) return hr; diff --git a/dll/directx/wine/d3drm/d3drm_main.c b/dll/directx/wine/d3drm/d3drm_main.c index 1abfe6f46ef..075b331e051 100644 --- a/dll/directx/wine/d3drm/d3drm_main.c +++ b/dll/directx/wine/d3drm/d3drm_main.c @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "initguid.h" #include "d3drm_private.h" diff --git a/dll/directx/wine/d3drm/d3drm_private.h b/dll/directx/wine/d3drm/d3drm_private.h index 858911f3507..b5d60e518f8 100644 --- a/dll/directx/wine/d3drm/d3drm_private.h +++ b/dll/directx/wine/d3drm/d3drm_private.h @@ -33,6 +33,19 @@ #include "wine/heap.h" #include "wine/list.h" +struct d3drm_matrix +{ + float _11, _12, _13, _14; + float _21, _22, _23, _24; + float _31, _32, _33, _34; + float _41, _42, _43, _44; +}; + +static inline struct d3drm_matrix *d3drm_matrix(D3DRMMATRIX4D m) +{ + return (struct d3drm_matrix *)m; +} + struct d3drm_object { LONG ref; @@ -71,11 +84,21 @@ struct d3drm_frame SIZE_T nb_lights; SIZE_T lights_size; IDirect3DRMLight **lights; - D3DRMMATRIX4D transform; + struct d3drm_matrix transform; D3DCOLOR scenebackground; DWORD traversal_options; }; +struct d3drm_box +{ + float left; + float top; + float right; + float bottom; + float front; + float back; +}; + struct d3drm_viewport { struct d3drm_object obj; @@ -86,9 +109,7 @@ struct d3drm_viewport IDirect3DViewport *d3d_viewport; IDirect3DMaterial *material; IDirect3DRM *d3drm; - D3DVALUE back; - D3DVALUE front; - D3DVALUE field; + struct d3drm_box clip; D3DRMPROJECTIONTYPE projection; }; @@ -260,6 +281,8 @@ HRESULT d3drm_object_set_name(struct d3drm_object *object, const char *name) DEC void d3drm_object_cleanup(IDirect3DRMObject *iface, struct d3drm_object *object) DECLSPEC_HIDDEN; struct d3drm_frame *unsafe_impl_from_IDirect3DRMFrame(IDirect3DRMFrame *iface) DECLSPEC_HIDDEN; +struct d3drm_frame *unsafe_impl_from_IDirect3DRMFrame3(IDirect3DRMFrame3 *iface) DECLSPEC_HIDDEN; + struct d3drm_device *unsafe_impl_from_IDirect3DRMDevice3(IDirect3DRMDevice3 *iface) DECLSPEC_HIDDEN; HRESULT d3drm_texture_create(struct d3drm_texture **texture, IDirect3DRM *d3drm) DECLSPEC_HIDDEN; diff --git a/dll/directx/wine/d3drm/device.c b/dll/directx/wine/d3drm/device.c index 2aa7e48086b..2e1b5f2d24f 100644 --- a/dll/directx/wine/d3drm/device.c +++ b/dll/directx/wine/d3drm/device.c @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "d3drm_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3drm); diff --git a/dll/directx/wine/d3drm/face.c b/dll/directx/wine/d3drm/face.c index 324b1de1bcb..1799ad98cf4 100644 --- a/dll/directx/wine/d3drm/face.c +++ b/dll/directx/wine/d3drm/face.c @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "d3drm_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3drm); diff --git a/dll/directx/wine/d3drm/frame.c b/dll/directx/wine/d3drm/frame.c index 11105db4032..265afdf3d63 100644 --- a/dll/directx/wine/d3drm/frame.c +++ b/dll/directx/wine/d3drm/frame.c @@ -19,18 +19,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "d3drm_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3drm); -static D3DRMMATRIX4D identity = { - { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f } +static const struct d3drm_matrix identity = +{ + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, }; struct d3drm_frame_array @@ -72,8 +70,6 @@ static inline struct d3drm_frame *impl_from_IDirect3DRMFrame3(IDirect3DRMFrame3 return CONTAINING_RECORD(iface, struct d3drm_frame, IDirect3DRMFrame3_iface); } -static inline struct d3drm_frame *unsafe_impl_from_IDirect3DRMFrame3(IDirect3DRMFrame3 *iface); - static inline struct d3drm_frame_array *impl_from_IDirect3DRMFrameArray(IDirect3DRMFrameArray *iface) { return CONTAINING_RECORD(iface, struct d3drm_frame_array, IDirect3DRMFrameArray_iface); @@ -99,6 +95,75 @@ static inline struct d3drm_animation *impl_from_IDirect3DRMAnimation2(IDirect3DR return CONTAINING_RECORD(iface, struct d3drm_animation, IDirect3DRMAnimation2_iface); } +static void d3drm_matrix_multiply_affine(struct d3drm_matrix *dst, + const struct d3drm_matrix *src1, const struct d3drm_matrix *src2) +{ + struct d3drm_matrix tmp; + + tmp._11 = src1->_11 * src2->_11 + src1->_12 * src2->_21 + src1->_13 * src2->_31; + tmp._12 = src1->_11 * src2->_12 + src1->_12 * src2->_22 + src1->_13 * src2->_32; + tmp._13 = src1->_11 * src2->_13 + src1->_12 * src2->_23 + src1->_13 * src2->_33; + tmp._14 = 0.0f; + + tmp._21 = src1->_21 * src2->_11 + src1->_22 * src2->_21 + src1->_23 * src2->_31; + tmp._22 = src1->_21 * src2->_12 + src1->_22 * src2->_22 + src1->_23 * src2->_32; + tmp._23 = src1->_21 * src2->_13 + src1->_22 * src2->_23 + src1->_23 * src2->_33; + tmp._24 = 0.0f; + + tmp._31 = src1->_31 * src2->_11 + src1->_32 * src2->_21 + src1->_33 * src2->_31; + tmp._32 = src1->_31 * src2->_12 + src1->_32 * src2->_22 + src1->_33 * src2->_32; + tmp._33 = src1->_31 * src2->_13 + src1->_32 * src2->_23 + src1->_33 * src2->_33; + tmp._34 = 0.0f; + + tmp._41 = src1->_41 * src2->_11 + src1->_42 * src2->_21 + src1->_43 * src2->_31 + src2->_41; + tmp._42 = src1->_41 * src2->_12 + src1->_42 * src2->_22 + src1->_43 * src2->_32 + src2->_42; + tmp._43 = src1->_41 * src2->_13 + src1->_42 * src2->_23 + src1->_43 * src2->_33 + src2->_43; + tmp._44 = 1.0f; + + *dst = tmp; +} + +static void d3drm_matrix_set_rotation(struct d3drm_matrix *matrix, D3DVECTOR *axis, float theta) +{ + float sin_theta, cos_theta, vers_theta; + + D3DRMVectorNormalize(axis); + sin_theta = sinf(theta); + cos_theta = cosf(theta); + vers_theta = 1.0f - cos_theta; + + matrix->_11 = vers_theta * axis->u1.x * axis->u1.x + cos_theta; + matrix->_21 = vers_theta * axis->u1.x * axis->u2.y - sin_theta * axis->u3.z; + matrix->_31 = vers_theta * axis->u1.x * axis->u3.z + sin_theta * axis->u2.y; + matrix->_41 = 0.0f; + + matrix->_12 = vers_theta * axis->u2.y * axis->u1.x + sin_theta * axis->u3.z; + matrix->_22 = vers_theta * axis->u2.y * axis->u2.y + cos_theta; + matrix->_32 = vers_theta * axis->u2.y * axis->u3.z - sin_theta * axis->u1.x; + matrix->_42 = 0.0f; + + matrix->_13 = vers_theta * axis->u3.z * axis->u1.x - sin_theta * axis->u2.y; + matrix->_23 = vers_theta * axis->u3.z * axis->u2.y + sin_theta * axis->u1.x; + matrix->_33 = vers_theta * axis->u3.z * axis->u3.z + cos_theta; + matrix->_43 = 0.0f; + + matrix->_14 = 0.0f; + matrix->_24 = 0.0f; + matrix->_34 = 0.0f; + matrix->_44 = 1.0f; +} + +static void d3drm_vector_transform_affine(D3DVECTOR *dst, const D3DVECTOR *v, const struct d3drm_matrix *m) +{ + D3DVECTOR tmp; + + tmp.u1.x = v->u1.x * m->_11 + v->u2.y * m->_21 + v->u3.z * m->_31 + m->_41; + tmp.u2.y = v->u1.x * m->_12 + v->u2.y * m->_22 + v->u3.z * m->_32 + m->_42; + tmp.u3.z = v->u1.x * m->_13 + v->u2.y * m->_23 + v->u3.z * m->_33 + m->_43; + + *dst = tmp; +} + static HRESULT WINAPI d3drm_frame_array_QueryInterface(IDirect3DRMFrameArray *iface, REFIID riid, void **out) { TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); @@ -944,25 +1009,29 @@ static HRESULT WINAPI d3drm_frame3_AddTransform(IDirect3DRMFrame3 *iface, D3DRMCOMBINETYPE type, D3DRMMATRIX4D matrix) { struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); + const struct d3drm_matrix *m = d3drm_matrix(matrix); TRACE("iface %p, type %#x, matrix %p.\n", iface, type, matrix); + if (m->_14 != 0.0f || m->_24 != 0.0f || m->_34 != 0.0f || m->_44 != 1.0f) + return D3DRMERR_BADVALUE; + switch (type) { case D3DRMCOMBINE_REPLACE: - memcpy(frame->transform, matrix, sizeof(D3DRMMATRIX4D)); + frame->transform = *m; break; case D3DRMCOMBINE_BEFORE: - FIXME("D3DRMCOMBINE_BEFORE not supported yet\n"); + d3drm_matrix_multiply_affine(&frame->transform, m, &frame->transform); break; case D3DRMCOMBINE_AFTER: - FIXME("D3DRMCOMBINE_AFTER not supported yet\n"); + d3drm_matrix_multiply_affine(&frame->transform, &frame->transform, m); break; default: - WARN("Unknown Combine Type %u\n", type); + FIXME("Unhandled type %#x.\n", type); return D3DRMERR_BADVALUE; } @@ -992,74 +1061,185 @@ static HRESULT WINAPI d3drm_frame1_AddTransform(IDirect3DRMFrame *iface, static HRESULT WINAPI d3drm_frame3_AddTranslation(IDirect3DRMFrame3 *iface, D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z) { - FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e stub!\n", iface, type, x, y, z); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); - return E_NOTIMPL; + TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e.\n", iface, type, x, y, z); + + switch (type) + { + case D3DRMCOMBINE_REPLACE: + frame->transform = identity; + frame->transform._41 = x; + frame->transform._42 = y; + frame->transform._43 = z; + break; + + case D3DRMCOMBINE_BEFORE: + frame->transform._41 += x * frame->transform._11 + y * frame->transform._21 + z * frame->transform._31; + frame->transform._42 += x * frame->transform._12 + y * frame->transform._22 + z * frame->transform._32; + frame->transform._43 += x * frame->transform._13 + y * frame->transform._23 + z * frame->transform._33; + break; + + case D3DRMCOMBINE_AFTER: + frame->transform._41 += x; + frame->transform._42 += y; + frame->transform._43 += z; + break; + + default: + FIXME("Unhandled type %#x.\n", type); + return D3DRMERR_BADVALUE; + } + + return D3DRM_OK; } static HRESULT WINAPI d3drm_frame2_AddTranslation(IDirect3DRMFrame2 *iface, D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z) { - FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e stub!\n", iface, type, x, y, z); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); - return E_NOTIMPL; + TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e.\n", iface, type, x, y, z); + + return d3drm_frame3_AddTranslation(&frame->IDirect3DRMFrame3_iface, type, x, y, z); } static HRESULT WINAPI d3drm_frame1_AddTranslation(IDirect3DRMFrame *iface, D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z) { - FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e stub!\n", iface, type, x, y, z); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface); - return E_NOTIMPL; + TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e.\n", iface, type, x, y, z); + + return d3drm_frame3_AddTranslation(&frame->IDirect3DRMFrame3_iface, type, x, y, z); } static HRESULT WINAPI d3drm_frame3_AddScale(IDirect3DRMFrame3 *iface, D3DRMCOMBINETYPE type, D3DVALUE sx, D3DVALUE sy, D3DVALUE sz) { - FIXME("iface %p, type %#x, sx %.8e, sy %.8e, sz %.8e stub!\n", iface, type, sx, sy, sz); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); - return E_NOTIMPL; + TRACE("iface %p, type %#x, sx %.8e, sy %.8e, sz %.8e.\n", iface, type, sx, sy, sz); + + switch (type) + { + case D3DRMCOMBINE_REPLACE: + frame->transform = identity; + frame->transform._11 = sx; + frame->transform._22 = sy; + frame->transform._33 = sz; + break; + + case D3DRMCOMBINE_BEFORE: + frame->transform._11 *= sx; + frame->transform._12 *= sx; + frame->transform._13 *= sx; + frame->transform._21 *= sy; + frame->transform._22 *= sy; + frame->transform._23 *= sy; + frame->transform._31 *= sz; + frame->transform._32 *= sz; + frame->transform._33 *= sz; + break; + + case D3DRMCOMBINE_AFTER: + frame->transform._11 *= sx; + frame->transform._12 *= sy; + frame->transform._13 *= sz; + frame->transform._21 *= sx; + frame->transform._22 *= sy; + frame->transform._23 *= sz; + frame->transform._31 *= sx; + frame->transform._32 *= sy; + frame->transform._33 *= sz; + frame->transform._41 *= sx; + frame->transform._42 *= sy; + frame->transform._43 *= sz; + break; + + default: + FIXME("Unhandled type %#x.\n", type); + return D3DRMERR_BADVALUE; + } + + return D3DRM_OK; } static HRESULT WINAPI d3drm_frame2_AddScale(IDirect3DRMFrame2 *iface, D3DRMCOMBINETYPE type, D3DVALUE sx, D3DVALUE sy, D3DVALUE sz) { - FIXME("iface %p, type %#x, sx %.8e, sy %.8e, sz %.8e stub!\n", iface, type, sx, sy, sz); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); - return E_NOTIMPL; + TRACE("iface %p, type %#x, sx %.8e, sy %.8e, sz %.8e.\n", iface, type, sx, sy, sz); + + return d3drm_frame3_AddScale(&frame->IDirect3DRMFrame3_iface, type, sx, sy, sz); } static HRESULT WINAPI d3drm_frame1_AddScale(IDirect3DRMFrame *iface, D3DRMCOMBINETYPE type, D3DVALUE sx, D3DVALUE sy, D3DVALUE sz) { - FIXME("iface %p, type %#x, sx %.8e, sy %.8e, sz %.8e stub!\n", iface, type, sx, sy, sz); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface); - return E_NOTIMPL; + TRACE("iface %p, type %#x, sx %.8e, sy %.8e, sz %.8e.\n", iface, type, sx, sy, sz); + + return d3drm_frame3_AddScale(&frame->IDirect3DRMFrame3_iface, type, sx, sy, sz); } static HRESULT WINAPI d3drm_frame3_AddRotation(IDirect3DRMFrame3 *iface, D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z, D3DVALUE theta) { - FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e stub!\n", - iface, type, x, y, z, theta); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); + struct d3drm_matrix m; + D3DVECTOR axis; - return E_NOTIMPL; + TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e.\n", iface, type, x, y, z, theta); + + axis.u1.x = x; + axis.u2.y = y; + axis.u3.z = z; + + switch (type) + { + case D3DRMCOMBINE_REPLACE: + d3drm_matrix_set_rotation(&frame->transform, &axis, theta); + break; + + case D3DRMCOMBINE_BEFORE: + d3drm_matrix_set_rotation(&m, &axis, theta); + d3drm_matrix_multiply_affine(&frame->transform, &m, &frame->transform); + break; + + case D3DRMCOMBINE_AFTER: + d3drm_matrix_set_rotation(&m, &axis, theta); + d3drm_matrix_multiply_affine(&frame->transform, &frame->transform, &m); + break; + + default: + FIXME("Unhandled type %#x.\n", type); + return D3DRMERR_BADVALUE; + } + + return D3DRM_OK; } static HRESULT WINAPI d3drm_frame2_AddRotation(IDirect3DRMFrame2 *iface, D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z, D3DVALUE theta) { - FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e stub!\n", iface, type, x, y, z, theta); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); - return E_NOTIMPL; + TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e.\n", iface, type, x, y, z, theta); + + return d3drm_frame3_AddRotation(&frame->IDirect3DRMFrame3_iface, type, x, y, z, theta); } static HRESULT WINAPI d3drm_frame1_AddRotation(IDirect3DRMFrame *iface, D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z, D3DVALUE theta) { - FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e stub!\n", iface, type, x, y, z, theta); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface); - return E_NOTIMPL; + TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e.\n", iface, type, x, y, z, theta); + + return d3drm_frame3_AddRotation(&frame->IDirect3DRMFrame3_iface, type, x, y, z, theta); } static HRESULT WINAPI d3drm_frame3_AddVisual(IDirect3DRMFrame3 *iface, IUnknown *visual) @@ -1418,13 +1598,14 @@ static HRESULT WINAPI d3drm_frame3_GetTransform(IDirect3DRMFrame3 *iface, IDirect3DRMFrame3 *reference, D3DRMMATRIX4D matrix) { struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); + struct d3drm_matrix *m = d3drm_matrix(matrix); TRACE("iface %p, reference %p, matrix %p.\n", iface, reference, matrix); if (reference) - FIXME("Specifying a frame as the root of the scene different from the current root frame is not supported yet\n"); + FIXME("Ignoring reference frame %p.\n", reference); - memcpy(matrix, frame->transform, sizeof(D3DRMMATRIX4D)); + *m = frame->transform; return D3DRM_OK; } @@ -1432,10 +1613,11 @@ static HRESULT WINAPI d3drm_frame3_GetTransform(IDirect3DRMFrame3 *iface, static HRESULT WINAPI d3drm_frame2_GetTransform(IDirect3DRMFrame2 *iface, D3DRMMATRIX4D matrix) { struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); + struct d3drm_matrix *m = d3drm_matrix(matrix); TRACE("iface %p, matrix %p.\n", iface, matrix); - memcpy(matrix, frame->transform, sizeof(D3DRMMATRIX4D)); + *m = frame->transform; return D3DRM_OK; } @@ -2419,23 +2601,35 @@ static HRESULT WINAPI d3drm_frame1_SetZbufferMode(IDirect3DRMFrame *iface, D3DRM static HRESULT WINAPI d3drm_frame3_Transform(IDirect3DRMFrame3 *iface, D3DVECTOR *d, D3DVECTOR *s) { - FIXME("iface %p, d %p, s %p stub!\n", iface, d, s); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); - return E_NOTIMPL; + TRACE("iface %p, d %p, s %p.\n", iface, d, s); + + d3drm_vector_transform_affine(d, s, &frame->transform); + while ((frame = frame->parent)) + { + d3drm_vector_transform_affine(d, d, &frame->transform); + } + + return D3DRM_OK; } static HRESULT WINAPI d3drm_frame2_Transform(IDirect3DRMFrame2 *iface, D3DVECTOR *d, D3DVECTOR *s) { - FIXME("iface %p, d %p, s %p stub!\n", iface, d, s); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); - return E_NOTIMPL; + TRACE("iface %p, d %p, s %p.\n", iface, d, s); + + return d3drm_frame3_Transform(&frame->IDirect3DRMFrame3_iface, d, s); } static HRESULT WINAPI d3drm_frame1_Transform(IDirect3DRMFrame *iface, D3DVECTOR *d, D3DVECTOR *s) { - FIXME("iface %p, d %p, s %p stub!\n", iface, d, s); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface); - return E_NOTIMPL; + TRACE("iface %p, d %p, s %p.\n", iface, d, s); + + return d3drm_frame3_Transform(&frame->IDirect3DRMFrame3_iface, d, s); } static HRESULT WINAPI d3drm_frame2_AddMoveCallback2(IDirect3DRMFrame2 *iface, @@ -2914,7 +3108,7 @@ static const struct IDirect3DRMFrameVtbl d3drm_frame1_vtbl = d3drm_frame1_Transform, }; -static inline struct d3drm_frame *unsafe_impl_from_IDirect3DRMFrame3(IDirect3DRMFrame3 *iface) +struct d3drm_frame *unsafe_impl_from_IDirect3DRMFrame3(IDirect3DRMFrame3 *iface) { if (!iface) return NULL; @@ -2953,7 +3147,7 @@ HRESULT d3drm_frame_create(struct d3drm_frame **frame, IUnknown *parent_frame, I d3drm_object_init(&object->obj, classname); - memcpy(object->transform, identity, sizeof(D3DRMMATRIX4D)); + object->transform = identity; if (parent_frame) { diff --git a/dll/directx/wine/d3drm/light.c b/dll/directx/wine/d3drm/light.c index e31c02675ae..2f53f200aad 100644 --- a/dll/directx/wine/d3drm/light.c +++ b/dll/directx/wine/d3drm/light.c @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "d3drm_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3drm); diff --git a/dll/directx/wine/d3drm/material.c b/dll/directx/wine/d3drm/material.c index 62acb5a8d4a..e402ea630d3 100644 --- a/dll/directx/wine/d3drm/material.c +++ b/dll/directx/wine/d3drm/material.c @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "d3drm_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3drm); diff --git a/dll/directx/wine/d3drm/math.c b/dll/directx/wine/d3drm/math.c index a6c0c858126..01d596b8a5b 100644 --- a/dll/directx/wine/d3drm/math.c +++ b/dll/directx/wine/d3drm/math.c @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "d3drm_private.h" /* Create a RGB color from its components */ diff --git a/dll/directx/wine/d3drm/meshbuilder.c b/dll/directx/wine/d3drm/meshbuilder.c index 009055593cb..9b85c2d0d0b 100644 --- a/dll/directx/wine/d3drm/meshbuilder.c +++ b/dll/directx/wine/d3drm/meshbuilder.c @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "d3drm_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3drm); diff --git a/dll/directx/wine/d3drm/texture.c b/dll/directx/wine/d3drm/texture.c index 7741718ce90..07f0896a30b 100644 --- a/dll/directx/wine/d3drm/texture.c +++ b/dll/directx/wine/d3drm/texture.c @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "d3drm_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3drm); diff --git a/dll/directx/wine/d3drm/viewport.c b/dll/directx/wine/d3drm/viewport.c index 5c0e24bc429..8e959d5f37e 100644 --- a/dll/directx/wine/d3drm/viewport.c +++ b/dll/directx/wine/d3drm/viewport.c @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include "d3drm_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3drm); @@ -53,6 +50,7 @@ static HRESULT d3drm_update_background_material(struct d3drm_viewport *viewport) if (FAILED(hr = IDirect3DRMFrame_GetScene(viewport->camera, &root_frame))) return hr; color = IDirect3DRMFrame_GetSceneBackground(root_frame); + IDirect3DRMFrame_Release(root_frame); memset(&mat, 0, sizeof(mat)); mat.dwSize = sizeof(mat); @@ -371,6 +369,13 @@ static HRESULT WINAPI d3drm_viewport2_Init(IDirect3DRMViewport2 *iface, IDirect3 viewport->material = material; viewport->device = device_obj; + viewport->clip.left = -0.5f; + viewport->clip.top = 0.5f; + viewport->clip.right = 0.5f; + viewport->clip.bottom = -0.5f; + viewport->clip.front = 1.0f; + viewport->clip.back = 100.0f; + cleanup: if (FAILED(hr)) @@ -485,7 +490,13 @@ static HRESULT WINAPI d3drm_viewport2_SetFront(IDirect3DRMViewport2 *iface, D3DV TRACE("iface %p, front %.8e.\n", iface, front); - viewport->front = front; + if (!viewport->d3d_viewport) + return D3DRMERR_BADOBJECT; + + if (front <= 0.0f) + return D3DRMERR_BADVALUE; + + viewport->clip.front = front; return D3DRM_OK; } @@ -505,7 +516,13 @@ static HRESULT WINAPI d3drm_viewport2_SetBack(IDirect3DRMViewport2 *iface, D3DVA TRACE("iface %p, back %.8e.\n", iface, back); - viewport->back = back; + if (!viewport->d3d_viewport) + return D3DRMERR_BADOBJECT; + + if (back <= viewport->clip.front) + return D3DRMERR_BADVALUE; + + viewport->clip.back = back; return D3DRM_OK; } @@ -525,7 +542,16 @@ static HRESULT WINAPI d3drm_viewport2_SetField(IDirect3DRMViewport2 *iface, D3DV TRACE("iface %p, field %.8e.\n", iface, field); - viewport->field = field; + if (!viewport->d3d_viewport) + return D3DRMERR_BADOBJECT; + + if (field <= 0.0f) + return D3DRMERR_BADVALUE; + + viewport->clip.left = -field; + viewport->clip.right = field; + viewport->clip.bottom = -field; + viewport->clip.top = field; return D3DRM_OK; } @@ -555,16 +581,30 @@ static HRESULT WINAPI d3drm_viewport1_SetUniformScaling(IDirect3DRMViewport *ifa static HRESULT WINAPI d3drm_viewport2_SetCamera(IDirect3DRMViewport2 *iface, IDirect3DRMFrame3 *camera) { - FIXME("iface %p, camera %p stub!\n", iface, camera); + struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface); + struct d3drm_frame *frame = unsafe_impl_from_IDirect3DRMFrame3(camera); - return E_NOTIMPL; + TRACE("iface %p, camera %p.\n", iface, camera); + + if (!camera || !viewport->camera) + return D3DRMERR_BADOBJECT; + + IDirect3DRMFrame_AddRef(&frame->IDirect3DRMFrame_iface); + IDirect3DRMFrame_Release(viewport->camera); + viewport->camera = &frame->IDirect3DRMFrame_iface; + + return D3DRM_OK; } static HRESULT WINAPI d3drm_viewport1_SetCamera(IDirect3DRMViewport *iface, IDirect3DRMFrame *camera) { - FIXME("iface %p, camera %p stub!\n", iface, camera); + struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface); + struct d3drm_frame *frame = unsafe_impl_from_IDirect3DRMFrame(camera); - return E_NOTIMPL; + TRACE("iface %p, camera %p.\n", iface, camera); + + return d3drm_viewport2_SetCamera(&viewport->IDirect3DRMViewport2_iface, + frame ? &frame->IDirect3DRMFrame3_iface : NULL); } static HRESULT WINAPI d3drm_viewport2_SetProjection(IDirect3DRMViewport2 *iface, D3DRMPROJECTIONTYPE type) @@ -650,33 +690,67 @@ static HRESULT WINAPI d3drm_viewport1_ForceUpdate(IDirect3DRMViewport *iface, static HRESULT WINAPI d3drm_viewport2_SetPlane(IDirect3DRMViewport2 *iface, D3DVALUE left, D3DVALUE right, D3DVALUE bottom, D3DVALUE top) { - FIXME("iface %p, left %.8e, right %.8e, bottom %.8e, top %.8e stub!\n", + struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface); + + TRACE("iface %p, left %.8e, right %.8e, bottom %.8e, top %.8e.\n", iface, left, right, bottom, top); - return E_NOTIMPL; + if (!viewport->d3d_viewport) + return D3DRMERR_BADOBJECT; + + viewport->clip.left = left; + viewport->clip.right = right; + viewport->clip.bottom = bottom; + viewport->clip.top = top; + + return D3DRM_OK; } static HRESULT WINAPI d3drm_viewport1_SetPlane(IDirect3DRMViewport *iface, D3DVALUE left, D3DVALUE right, D3DVALUE bottom, D3DVALUE top) { - FIXME("iface %p, left %.8e, right %.8e, bottom %.8e, top %.8e stub!\n", + struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface); + + TRACE("iface %p, left %.8e, right %.8e, bottom %.8e, top %.8e.\n", iface, left, right, bottom, top); - return E_NOTIMPL; + return d3drm_viewport2_SetPlane(&viewport->IDirect3DRMViewport2_iface, left, right, bottom, top); } static HRESULT WINAPI d3drm_viewport2_GetCamera(IDirect3DRMViewport2 *iface, IDirect3DRMFrame3 **camera) { - FIXME("iface %p, camera %p stub!\n", iface, camera); + struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface); - return E_NOTIMPL; + TRACE("iface %p, camera %p.\n", iface, camera); + + if (!camera) + return D3DRMERR_BADVALUE; + + if (!viewport->camera) + return D3DRMERR_BADOBJECT; + + return IDirect3DRMFrame_QueryInterface(viewport->camera, &IID_IDirect3DRMFrame3, (void **)camera); } static HRESULT WINAPI d3drm_viewport1_GetCamera(IDirect3DRMViewport *iface, IDirect3DRMFrame **camera) { - FIXME("iface %p, camera %p stub!\n", iface, camera); + struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface); + struct d3drm_frame *camera_impl; + IDirect3DRMFrame3 *camera3; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, camera %p.\n", iface, camera); + + if (!camera) + return D3DRMERR_BADVALUE; + + if (FAILED(hr = d3drm_viewport2_GetCamera(&viewport->IDirect3DRMViewport2_iface, &camera3))) + return hr; + + camera_impl = unsafe_impl_from_IDirect3DRMFrame3(camera3); + *camera = &camera_impl->IDirect3DRMFrame_iface; + + return D3DRM_OK; } static HRESULT WINAPI d3drm_viewport2_GetDevice(IDirect3DRMViewport2 *iface, IDirect3DRMDevice3 **device) @@ -685,6 +759,9 @@ static HRESULT WINAPI d3drm_viewport2_GetDevice(IDirect3DRMViewport2 *iface, IDi TRACE("iface %p, device %p.\n", iface, device); + if (!device) + return D3DRMERR_BADVALUE; + if (!viewport->device) return D3DRMERR_BADOBJECT; @@ -700,6 +777,9 @@ static HRESULT WINAPI d3drm_viewport1_GetDevice(IDirect3DRMViewport *iface, IDir TRACE("iface %p, device %p.\n\n", iface, device); + if (!device) + return D3DRMERR_BADVALUE; + if (!viewport->device) return D3DRMERR_BADOBJECT; @@ -712,19 +792,31 @@ static HRESULT WINAPI d3drm_viewport1_GetDevice(IDirect3DRMViewport *iface, IDir static HRESULT WINAPI d3drm_viewport2_GetPlane(IDirect3DRMViewport2 *iface, D3DVALUE *left, D3DVALUE *right, D3DVALUE *bottom, D3DVALUE *top) { - FIXME("iface %p, left %p, right %p, bottom %p, top %p stub!\n", + struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface); + + TRACE("iface %p, left %p, right %p, bottom %p, top %p.\n", iface, left, right, bottom, top); - return E_NOTIMPL; + if (!viewport->d3d_viewport) + return D3DRMERR_BADOBJECT; + + *left = viewport->clip.left; + *right = viewport->clip.right; + *bottom = viewport->clip.bottom; + *top = viewport->clip.top; + + return D3DRM_OK; } static HRESULT WINAPI d3drm_viewport1_GetPlane(IDirect3DRMViewport *iface, D3DVALUE *left, D3DVALUE *right, D3DVALUE *bottom, D3DVALUE *top) { - FIXME("iface %p, left %p, right %p, bottom %p, top %p stub!\n", + struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface); + + TRACE("iface %p, left %p, right %p, bottom %p, top %p.\n", iface, left, right, bottom, top); - return E_NOTIMPL; + return d3drm_viewport2_GetPlane(&viewport->IDirect3DRMViewport2_iface, left, right, bottom, top); } static HRESULT WINAPI d3drm_viewport2_Pick(IDirect3DRMViewport2 *iface, @@ -819,7 +911,11 @@ static D3DVALUE WINAPI d3drm_viewport2_GetField(IDirect3DRMViewport2 *iface) TRACE("iface %p.\n", iface); - return viewport->field; + if (!viewport->d3d_viewport) + return -1.0f; + + return (viewport->clip.right - viewport->clip.left + + viewport->clip.top - viewport->clip.bottom) / 4.0f; } static D3DVALUE WINAPI d3drm_viewport1_GetField(IDirect3DRMViewport *iface) @@ -837,7 +933,10 @@ static D3DVALUE WINAPI d3drm_viewport2_GetBack(IDirect3DRMViewport2 *iface) TRACE("iface %p.\n", iface); - return viewport->back; + if (!viewport->d3d_viewport) + return -1.0f; + + return viewport->clip.back; } static D3DVALUE WINAPI d3drm_viewport1_GetBack(IDirect3DRMViewport *iface) @@ -855,7 +954,10 @@ static D3DVALUE WINAPI d3drm_viewport2_GetFront(IDirect3DRMViewport2 *iface) TRACE("iface %p.\n", iface); - return viewport->front; + if (!viewport->d3d_viewport) + return -1.0f; + + return viewport->clip.front; } static D3DVALUE WINAPI d3drm_viewport1_GetFront(IDirect3DRMViewport *iface) @@ -892,6 +994,9 @@ static HRESULT WINAPI d3drm_viewport2_GetDirect3DViewport(IDirect3DRMViewport2 * TRACE("iface %p, viewport %p.\n", iface, viewport); + if (!viewport) + return D3DRMERR_BADVALUE; + if (!viewport_object->d3d_viewport) return D3DRMERR_BADOBJECT; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 128045db4f3..7fc878f7c5c 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -25,7 +25,7 @@ dll/directx/wine/amstream # Synced to WineStaging-3.9 dll/directx/wine/d3d8 # Synced to WineStaging-3.3 dll/directx/wine/d3d9 # Synced to WineStaging-3.3 dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-4.18 -dll/directx/wine/d3drm # Synced to WineStaging-4.0 +dll/directx/wine/d3drm # Synced to WineStaging-4.18 dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-4.0 dll/directx/wine/d3dxof # Synced to WineStaging-3.17 dll/directx/wine/ddraw # Synced to WineStaging-3.3
5 years, 1 month
1
0
0
0
[reactos] 01/01: [D3DCOMPILER_43_WINETEST] Sync with Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7ce1a24a8bf91ae9345c8…
commit 7ce1a24a8bf91ae9345c8b8d49d103b9db4d8e0c Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Oct 26 13:01:05 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Oct 26 13:01:05 2019 +0100 [D3DCOMPILER_43_WINETEST] Sync with Wine Staging 4.18. CORE-16441 --- dll/directx/wine/d3dx9_43/CMakeLists.txt | 2 +- modules/rostests/winetests/CMakeLists.txt | 1 + .../winetests/d3dcompiler_43/CMakeLists.txt | 13 + modules/rostests/winetests/d3dcompiler_43/asm.c | 1760 ++++++++++++++++++++ modules/rostests/winetests/d3dcompiler_43/blob.c | 886 ++++++++++ modules/rostests/winetests/d3dcompiler_43/hlsl.c | 685 ++++++++ .../rostests/winetests/d3dcompiler_43/reflection.c | 1545 +++++++++++++++++ .../rostests/winetests/d3dcompiler_43/testlist.c | 18 + 8 files changed, 4909 insertions(+), 1 deletion(-) diff --git a/dll/directx/wine/d3dx9_43/CMakeLists.txt b/dll/directx/wine/d3dx9_43/CMakeLists.txt index 2361819fced..385278abc2b 100644 --- a/dll/directx/wine/d3dx9_43/CMakeLists.txt +++ b/dll/directx/wine/d3dx9_43/CMakeLists.txt @@ -1,7 +1,7 @@ add_definitions(-D__WINESRC__) include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -spec2def(d3dx9_43.dll d3dx9_43.spec) +spec2def(d3dx9_43.dll d3dx9_43.spec ADD_IMPORTLIB) list(APPEND SOURCE d3dx9_43_main.c diff --git a/modules/rostests/winetests/CMakeLists.txt b/modules/rostests/winetests/CMakeLists.txt index 0e70ccb1cc4..702f31fb75e 100644 --- a/modules/rostests/winetests/CMakeLists.txt +++ b/modules/rostests/winetests/CMakeLists.txt @@ -23,6 +23,7 @@ add_subdirectory(credui) add_subdirectory(crypt32) add_subdirectory(cryptnet) add_subdirectory(cryptui) +add_subdirectory(d3dcompiler_43) add_subdirectory(d3drm) add_subdirectory(devenum) add_subdirectory(dinput) diff --git a/modules/rostests/winetests/d3dcompiler_43/CMakeLists.txt b/modules/rostests/winetests/d3dcompiler_43/CMakeLists.txt new file mode 100644 index 00000000000..2fe06983fcc --- /dev/null +++ b/modules/rostests/winetests/d3dcompiler_43/CMakeLists.txt @@ -0,0 +1,13 @@ + +add_definitions(-DUSE_WINE_TODOS -DD3D_COMPILER_VERSION=43) + +add_executable(d3dcompiler_43_winetest + asm.c + blob.c + hlsl.c + reflection.c + testlist.c) + +set_module_type(d3dcompiler_43_winetest win32cui) +add_importlibs(d3dcompiler_43_winetest d3d9 d3dx9_43 user32 msvcrt kernel32) +add_rostests_file(TARGET d3dcompiler_43_winetest) diff --git a/modules/rostests/winetests/d3dcompiler_43/asm.c b/modules/rostests/winetests/d3dcompiler_43/asm.c new file mode 100644 index 00000000000..900e6628439 --- /dev/null +++ b/modules/rostests/winetests/d3dcompiler_43/asm.c @@ -0,0 +1,1760 @@ +/* + * Copyright (C) 2010 Matteo Bruni + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS +#define CONST_VTABLE +#include "wine/test.h" + +#include <d3d9types.h> +#include <d3dcommon.h> +#include <d3dcompiler.h> + +/* TODO: maybe this is defined in some header file, + perhaps with a different name? */ +#define D3DXERR_INVALIDDATA 0x88760b59 + +static HRESULT (WINAPI *pD3DAssemble)(const void *data, SIZE_T datasize, const char *filename, + const D3D_SHADER_MACRO *defines, ID3DInclude *include, UINT flags, ID3DBlob **shader, + ID3DBlob **error_messages); +static pD3DPreprocess ppD3DPreprocess; + +struct shader_test { + const char *text; + const DWORD bytes[128]; +}; + +static void dump_shader(DWORD *shader) { + unsigned int i = 0, j = 0; + do { + trace("0x%08x ", shader[i]); + j++; + i++; + if(j == 6) trace("\n"); + } while(shader[i - 1] != D3DSIO_END); + if(j != 6) trace("\n"); +} + +static void exec_tests(const char *name, struct shader_test tests[], unsigned int count) { + HRESULT hr; + DWORD *res; + unsigned int i, j; + BOOL diff; + ID3DBlob *shader, *messages; + + for(i = 0; i < count; i++) { + /* D3DAssemble sets messages to 0 if there aren't error messages */ + messages = NULL; + hr = pD3DAssemble(tests[i].text, strlen(tests[i].text), NULL, + NULL, NULL, D3DCOMPILE_SKIP_VALIDATION, + &shader, &messages); + ok(hr == S_OK, "Test %s, shader %d: D3DAssemble failed with error 0x%x - %d\n", name, i, hr, hr & 0x0000FFFF); + if(messages) { + trace("D3DAssemble messages:\n%s", (char *)ID3D10Blob_GetBufferPointer(messages)); + ID3D10Blob_Release(messages); + } + if(FAILED(hr)) continue; + + j = 0; + diff = FALSE; + res = ID3D10Blob_GetBufferPointer(shader); + while(res[j] != D3DSIO_END && tests[i].bytes[j] != D3DSIO_END) { + if(res[j] != tests[i].bytes[j]) diff = TRUE; + j++; + }; + /* Both must have an end token */ + if(res[j] != tests[i].bytes[j]) diff = TRUE; + + if(diff) { + ok(FALSE, "Test %s, shader %d: Generated code differs\n", name, i); + dump_shader(res); + } + ID3D10Blob_Release(shader); + } +} + +static void preproc_test(void) { + struct shader_test tests[] = { + { /* shader 0 */ + "vs.1.1\r\n" + "//some comments\r\n" + "//other comments\n" + "; yet another comment\r\n" + "add r0, r0, r1\n", + {0xfffe0101, 0x00000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x0000ffff} + }, + { /* shader 1 */ + "#line 1 \"vertex.vsh\"\n" + "vs.1.1\n", + {0xfffe0101, 0x0000ffff} + }, + { /* shader 2 */ + "#define REG 1 + 2 +\\\n" + "3 + 4\n" + "vs.1.1\n" + "mov r0, c0[ REG ]\n", + {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e4000a, 0x0000ffff} + }, + }; + + exec_tests("preproc", tests, ARRAY_SIZE(tests)); +} + +static void ps_1_1_test(void) { + struct shader_test tests[] = { + { /* shader 0 */ + "ps.1.1\r\n" + "tex t0\r\n" + "add r0.rgb, r0, r1\r\n" + "+mov r0.a, t0\r\n", + {0xffff0101, 0x00000042, 0xb00f0000, 0x00000002, 0x80070000, 0x80e40000, + 0x80e40001, 0x40000001, 0x80080000, 0xb0e40000, 0x0000ffff} + }, + { /* shader 1 */ + "ps.1.1\n" + "mov_d4 r0, r1\n", + {0xffff0101, 0x00000001, 0x8e0f0000, 0x80e40001, 0x0000ffff} + }, + { /* shader 2 */ + "ps_1_1\n" + "def c2, 0, 0., 0, 0.\n", + {0xffff0101, 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x0000ffff} + }, + }; + + exec_tests("ps_1_1", tests, ARRAY_SIZE(tests)); +} + +static void vs_1_1_test(void) { + struct shader_test tests[] = { + /* Basic instruction tests */ + { /* shader 0 */ + "vs_1_1\n" + "add r0, r1, r2\n", + {0xfffe0101, 0x00000002, 0x800f0000, 0x80e40001, 0x80e40002, 0x0000ffff} + }, + { /* shader 1 */ + "vs_1_1\n" + "nop\n", + {0xfffe0101, 0x00000000, 0x0000ffff} + }, + /* Output register tests */ + { /* shader 2 */ + "vs_1_1\n" + "mov oPos, c0\n", + {0xfffe0101, 0x00000001, 0xc00f0000, 0xa0e40000, 0x0000ffff} + }, + { /* shader 3 */ + "vs_1_1\n" + "mov oT0, c0\n", + {0xfffe0101, 0x00000001, 0xe00f0000, 0xa0e40000, 0x0000ffff} + }, + { /* shader 4 */ + "vs_1_1\n" + "mov oT5, c0\n", + {0xfffe0101, 0x00000001, 0xe00f0005, 0xa0e40000, 0x0000ffff} + }, + { /* shader 5 */ + "vs_1_1\n" + "mov oD0, c0\n", + {0xfffe0101, 0x00000001, 0xd00f0000, 0xa0e40000, 0x0000ffff} + }, + { /* shader 6 */ + "vs_1_1\n" + "mov oD1, c0\n", + {0xfffe0101, 0x00000001, 0xd00f0001, 0xa0e40000, 0x0000ffff} + }, + { /* shader 7 */ + "vs_1_1\n" + "mov oFog, c0.x\n", + {0xfffe0101, 0x00000001, 0xc00f0001, 0xa0000000, 0x0000ffff} + }, + { /* shader 8 */ + "vs_1_1\n" + "mov oPts, c0.x\n", + {0xfffe0101, 0x00000001, 0xc00f0002, 0xa0000000, 0x0000ffff} + }, + /* A bunch of tests for declarations */ + { /* shader 9 */ + "vs_1_1\n" + "dcl_position0 v0", + {0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000ffff} + }, + { /* shader 10 */ + "vs_1_1\n" + "dcl_position v1", + {0xfffe0101, 0x0000001f, 0x80000000, 0x900f0001, 0x0000ffff} + }, + { /* shader 11 */ + "vs_1_1\n" + "dcl_normal12 v15", + {0xfffe0101, 0x0000001f, 0x800c0003, 0x900f000f, 0x0000ffff} + }, + { /* shader 12 */ + "vs_1_1\n" + "add r0, v0, v1\n", + {0xfffe0101, 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, 0x0000ffff} + }, + { /* shader 13 */ + "vs_1_1\n" + "def c12, 0, -1, -0.5, 1024\n", + {0xfffe0101, 0x00000051, 0xa00f000c, 0x00000000, 0xbf800000, 0xbf000000, + 0x44800000, 0x0000ffff} + }, + { /* shader 14: writemasks, swizzles */ + "vs_1_1\n" + "dp4 r0.xw, r1.wzyx, r2.xxww\n", + {0xfffe0101, 0x00000009, 0x80090000, 0x801b0001, 0x80f00002, 0x0000ffff} + }, + { /* shader 15: negation input modifier. Other modifiers not supprted in vs_1_1 */ + "vs_1_1\n" + "add r0, -r0.x, -r1\n", + {0xfffe0101, 0x00000002, 0x800f0000, 0x81000000, 0x81e40001, 0x0000ffff} + }, + { /* shader 16: relative addressing */ + "vs_1_1\n" + "mov r0, c0[a0.x]\n", + {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e42000, 0x0000ffff} + }, + { /* shader 17: relative addressing */ + "vs_1_1\n" + "mov r0, c1[a0.x + 2]\n", + {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e42003, 0x0000ffff} + }, + { /* shader 18 */ + "vs_1_1\n" + "def c0, 1.0f, 1.0f, 1.0f, 0.5f\n", + {0xfffe0101, 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, + 0x3f000000, 0x0000ffff} + }, + /* Other relative addressing tests */ + { /* shader 19 */ + "vs_1_1\n" + "mov r0, c[ a0.x + 12 ]\n", + {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e4200c, 0x0000ffff} + }, + { /* shader 20 */ + "vs_1_1\n" + "mov r0, c[ 2 + a0.x ]\n", + {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e42002, 0x0000ffff} + }, + { /* shader 21 */ + "vs_1_1\n" + "mov r0, c[ 2 + a0.x + 12 ]\n", + {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e4200e, 0x0000ffff} + }, + { /* shader 22 */ + "vs_1_1\n" + "mov r0, c[ 2 + 10 + 12 ]\n", + {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e40018, 0x0000ffff} + }, + { /* shader 23 */ + "vs_1_1\n" + "mov r0, c4[ 2 ]\n", + {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e40006, 0x0000ffff} + }, + { /* shader 24 */ + "vs_1_1\n" + "rcp r0, v0.x\n", + {0xfffe0101, 0x00000006, 0x800f0000, 0x90000000, 0x0000ffff} + }, + { /* shader 25 */ + "vs.1.1\n" + "rsq r0, v0.x\n", + {0xfffe0101, 0x00000007, 0x800f0000, 0x90000000, 0x0000ffff} + }, + }; + + exec_tests("vs_1_1", tests, ARRAY_SIZE(tests)); +} + +static void ps_1_3_test(void) { + struct shader_test tests[] = { + /* Basic instruction tests */ + { /* shader 0 */ + "ps_1_3\n" + "mov r0, r1\n", + {0xffff0103, 0x00000001, 0x800f0000, 0x80e40001, 0x0000ffff} + }, + { /* shader 1 */ + "ps_1_3\n" + "add r0, r1, r0\n", + {0xffff0103, 0x00000002, 0x800f0000, 0x80e40001, 0x80e40000, 0x0000ffff} + }, + /* Color interpolator tests */ + { /* shader 2 */ + "ps_1_3\n" + "mov r0, v0\n", + {0xffff0103, 0x00000001, 0x800f0000, 0x90e40000, 0x0000ffff} + }, + { /* shader 3 */ + "ps_1_3\n" + "mov r0, v1\n", + {0xffff0103, 0x00000001, 0x800f0000, 0x90e40001, 0x0000ffff} + }, + /* Texture sampling instructions */ + { /* shader 4 */ + "ps_1_3\n" + "tex t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x0000ffff} + }, + { /* shader 5 */ + "ps_1_3\n" + "tex t0\n" + "texreg2ar t1, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000045, 0xb00f0001, 0xb0e40000, + 0x0000ffff} + }, + { /* shader 6 */ + "ps_1_3\n" + "tex t0\n" + "texreg2gb t1, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000046, 0xb00f0001, 0xb0e40000, + 0x0000ffff} + }, + { /* shader 7 */ + "ps_1_3\n" + "tex t0\n" + "texreg2rgb t1, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000052, 0xb00f0001, 0xb0e40000, + 0x0000ffff} + }, + { /* shader 8 */ + "ps_1_3\n" + "cnd r0, r1, r0, v0\n", + {0xffff0103, 0x00000050, 0x800f0000, 0x80e40001, 0x80e40000, 0x90e40000, + 0x0000ffff} + }, + { /* shader 9 */ + "ps_1_3\n" + "cmp r0, r1, r0, v0\n", + {0xffff0103, 0x00000058, 0x800f0000, 0x80e40001, 0x80e40000, 0x90e40000, + 0x0000ffff} + }, + { /* shader 10 */ + "ps_1_3\n" + "texkill t0\n", + {0xffff0103, 0x00000041, 0xb00f0000, 0x0000ffff} + }, + { /* shader 11 */ + "ps_1_3\n" + "tex t0\n" + "texm3x2pad t1, t0\n" + "texm3x2tex t2, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000047, 0xb00f0001, 0xb0e40000, + 0x00000048, 0xb00f0002, 0xb0e40000, 0x0000ffff} + }, + { /* shader 12 */ + "ps_1_3\n" + "tex t0\n" + "texm3x2pad t1, t0\n" + "texm3x2depth t2, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000047, 0xb00f0001, 0xb0e40000, + 0x00000054, 0xb00f0002, 0xb0e40000, 0x0000ffff} + }, + { /* shader 13 */ + "ps_1_3\n" + "tex t0\n" + "texbem t1, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000043, 0xb00f0001, 0xb0e40000, + 0x0000ffff} + }, + { /* shader 14 */ + "ps_1_3\n" + "tex t0\n" + "texbeml t1, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000044, 0xb00f0001, 0xb0e40000, + 0x0000ffff} + }, + { /* shader 15 */ + "ps_1_3\n" + "tex t0\n" + "texdp3tex t1, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000053, 0xb00f0001, 0xb0e40000, + 0x0000ffff} + }, + { /* shader 16 */ + "ps_1_3\n" + "tex t0\n" + "texdp3 t1, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000055, 0xb00f0001, 0xb0e40000, + 0x0000ffff} + }, + { /* shader 17 */ + "ps_1_3\n" + "tex t0\n" + "texm3x3pad t1, t0\n" + "texm3x3pad t2, t0\n" + "texm3x3tex t3, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000049, 0xb00f0001, 0xb0e40000, + 0x00000049, 0xb00f0002, 0xb0e40000, 0x0000004a, 0xb00f0003, 0xb0e40000, + 0x0000ffff} + }, + { /* shader 18 */ + "ps_1_3\n" + "tex t0\n" + "texm3x3pad t1, t0\n" + "texm3x3pad t2, t0\n" + "texm3x3 t3, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000049, 0xb00f0001, 0xb0e40000, + 0x00000049, 0xb00f0002, 0xb0e40000, 0x00000056, 0xb00f0003, 0xb0e40000, + 0x0000ffff} + }, + { /* shader 19 */ + "ps_1_3\n" + "tex t0\n" + "texm3x3pad t1, t0\n" + "texm3x3pad t2, t0\n" + "texm3x3spec t3, t0, c0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000049, 0xb00f0001, 0xb0e40000, + 0x00000049, 0xb00f0002, 0xb0e40000, 0x0000004c, 0xb00f0003, 0xb0e40000, + 0xa0e40000, 0x0000ffff} + }, + { /* shader 20 */ + "ps_1_3\n" + "tex t0\n" + "texm3x3pad t1, t0\n" + "texm3x3pad t2, t0\n" + "texm3x3vspec t3, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000049, 0xb00f0001, 0xb0e40000, + 0x00000049, 0xb00f0002, 0xb0e40000, 0x0000004d, 0xb00f0003, 0xb0e40000, + 0x0000ffff} + }, + { /* shader 21 */ + "ps_1_3\n" + "texcoord t0\n", + {0xffff0103, 0x00000040, 0xb00f0000, 0x0000ffff} + }, + /* Modifiers, shifts */ + { /* shader 22 */ + "ps_1_3\n" + "mov_x2_sat r0, 1 - r1\n", + {0xffff0103, 0x00000001, 0x811f0000, 0x86e40001, 0x0000ffff} + }, + { /* shader 23 */ + "ps_1_3\n" + "mov_d8 r0, -r1\n", + {0xffff0103, 0x00000001, 0x8d0f0000, 0x81e40001, 0x0000ffff} + }, + { /* shader 24 */ + "ps_1_3\n" + "mov_sat r0, r1_bx2\n", + {0xffff0103, 0x00000001, 0x801f0000, 0x84e40001, 0x0000ffff} + }, + { /* shader 25 */ + "ps_1_3\n" + "mov_sat r0, r1_bias\n", + {0xffff0103, 0x00000001, 0x801f0000, 0x82e40001, 0x0000ffff} + }, + { /* shader 26 */ + "ps_1_3\n" + "mov_sat r0, -r1_bias\n", + {0xffff0103, 0x00000001, 0x801f0000, 0x83e40001, 0x0000ffff} + }, + { /* shader 27 */ + "ps_1_3\n" + "mov_sat r0, -r1_bx2\n", + {0xffff0103, 0x00000001, 0x801f0000, 0x85e40001, 0x0000ffff} + }, + { /* shader 28 */ + "ps_1_3\n" + "mov_sat r0, -r1_x2\n", + {0xffff0103, 0x00000001, 0x801f0000, 0x88e40001, 0x0000ffff} + }, + { /* shader 29 */ + "ps_1_3\n" + "mov_x4_sat r0.a, -r1_bx2.a\n", + {0xffff0103, 0x00000001, 0x82180000, 0x85ff0001, 0x0000ffff} + }, + { /* shader 30 */ + "ps_1_3\n" + "texcoord_x2 t0\n", + {0xffff0103, 0x00000040, 0xb10f0000, 0x0000ffff} + }, + { /* shader 31 */ + "ps_1_3\n" + "tex_x2 t0\n", + {0xffff0103, 0x00000042, 0xb10f0000, 0x0000ffff} + }, + { /* shader 32 */ + "ps_1_3\n" + "texreg2ar_x4 t0, t1\n", + {0xffff0103, 0x00000045, 0xb20f0000, 0xb0e40001, 0x0000ffff} + }, + { /* shader 33 */ + "ps_1_3\n" + "texbem_d4 t1, t0\n", + {0xffff0103, 0x00000043, 0xbe0f0001, 0xb0e40000, 0x0000ffff} + }, + { /* shader 34 */ + "ps_1_3\n" + "tex t0\n" + "texm3x3pad_x2 t1, t0\n" + "texm3x3pad_x2 t2, t0\n" + "texm3x3tex_x2 t3, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000049, 0xb10f0001, 0xb0e40000, + 0x00000049, 0xb10f0002, 0xb0e40000, 0x0000004a, 0xb10f0003, 0xb0e40000, + 0x0000ffff} + }, + { /* shader 35 */ + "ps.1.3\n" + "tex t0\n" + "texdp3tex_x8 t1, t0\n", + {0xffff0103, 0x00000042, 0xb00f0000, 0x00000053, 0xb30f0001, 0xb0e40000, + 0x0000ffff} + }, + }; + + exec_tests("ps_1_3", tests, ARRAY_SIZE(tests)); +} + +static void ps_1_4_test(void) { + struct shader_test tests[] = { + /* Basic instruction tests */ + { /* shader 0 */ + "ps_1_4\n" + "mov r0, r1\n", + {0xffff0104, 0x00000001, 0x800f0000, 0x80e40001, 0x0000ffff} + }, + { /* shader 1 */ + "ps_1_4\n" + "mov r0, r5\n", + {0xffff0104, 0x00000001, 0x800f0000, 0x80e40005, 0x0000ffff} + }, + { /* shader 2 */ + "ps_1_4\n" + "mov r0, c7\n", + {0xffff0104, 0x00000001, 0x800f0000, 0xa0e40007, 0x0000ffff} + }, + { /* shader 3 */ + "ps_1_4\n" + "mov r0, v1\n", + {0xffff0104, 0x00000001, 0x800f0000, 0x90e40001, 0x0000ffff} + }, + { /* shader 4 */ + "ps_1_4\n" + "phase\n", + {0xffff0104, 0x0000fffd, 0x0000ffff} + }, + { /* shader 5 */ + "ps_1_4\n" + "texcrd r0, t0\n", + {0xffff0104, 0x00000040, 0x800f0000, 0xb0e40000, 0x0000ffff} + }, + { /* shader 6 */ + "ps_1_4\n" + "texcrd r4, t3\n", + {0xffff0104, 0x00000040, 0x800f0004, 0xb0e40003, 0x0000ffff} + }, + { /* shader 7 */ + "ps_1_4\n" + "texcrd_sat r4, t3\n", + {0xffff0104, 0x00000040, 0x801f0004, 0xb0e40003, 0x0000ffff} + }, + { /* shader 8 */ + "ps_1_4\n" + "texld r0, t0\n", + {0xffff0104, 0x00000042, 0x800f0000, 0xb0e40000, 0x0000ffff} + }, + { /* shader 9 */ + "ps_1_4\n" + "texld r1, t4\n", + {0xffff0104, 0x00000042, 0x800f0001, 0xb0e40004, 0x0000ffff} + }, + { /* shader 10 */ + "ps_1_4\n" + "texld r5, r0\n", + {0xffff0104, 0x00000042, 0x800f0005, 0x80e40000, 0x0000ffff} + }, + { /* shader 11 */ + "ps_1_4\n" + "texld r5, c0\n", /* Assembly succeeds, validation fails */ + {0xffff0104, 0x00000042, 0x800f0005, 0xa0e40000, 0x0000ffff} + }, + { /* shader 12 */ + "ps_1_4\n" + "texld r5, r2_dz\n", + {0xffff0104, 0x00000042, 0x800f0005, 0x89e40002, 0x0000ffff} + }, + { /* shader 13 */ + "ps_1_4\n" + "bem r1.rg, c0, r0\n", + {0xffff0104, 0x00000059, 0x80030001, 0xa0e40000, 0x80e40000, 0x0000ffff} + }, + { /* shader 14 */ + "ps_1_4\n" + "texdepth r5\n", + {0xffff0104, 0x00000057, 0x800f0005, 0x0000ffff} + }, + { /* shader 15 */ + "ps_1_4\n" + "add r0, r1, r2_bx2\n", + {0xffff0104, 0x00000002, 0x800f0000, 0x80e40001, 0x84e40002, 0x0000ffff} + }, + { /* shader 16 */ + "ps_1_4\n" + "add_x4 r0, r1, r2\n", + {0xffff0104, 0x00000002, 0x820f0000, 0x80e40001, 0x80e40002, 0x0000ffff} + }, + { /* shader 17 */ + "ps_1_4\n" + "add r0.rgb, r1, r2\n" + "+add r0.a, r1, r2\n", + {0xffff0104, 0x00000002, 0x80070000, 0x80e40001, 0x80e40002, 0x40000002, + 0x80080000, 0x80e40001, 0x80e40002, 0x0000ffff} + }, + { /* shader 18 */ + "ps_1_4\n" + "texdepth_x2 r5\n", + {0xffff0104, 0x00000057, 0x810f0005, 0x0000ffff} + }, + { /* shader 18 */ + "ps.1.4\n" + "bem_d2 r1, c0, r0\n", + {0xffff0104, 0x00000059, 0x8f0f0001, 0xa0e40000, 0x80e40000, 0x0000ffff} + }, + }; + + exec_tests("ps_1_4", tests, ARRAY_SIZE(tests)); +} + +static void vs_2_0_test(void) { + struct shader_test tests[] = { + /* Basic instruction tests */ + { /* shader 0 */ + "vs_2_0\n" + "mov r0, r1\n", + {0xfffe0200, 0x02000001, 0x800f0000, 0x80e40001, 0x0000ffff} + }, + { /* shader 1 */ + "vs_2_0\n" + "lrp r0, v0, c0, r1\n", + {0xfffe0200, 0x04000012, 0x800f0000, 0x90e40000, 0xa0e40000, 0x80e40001, + 0x0000ffff} + }, + { /* shader 2 */ + "vs_2_0\n" + "dp4 oPos, v0, c0\n", + {0xfffe0200, 0x03000009, 0xc00f0000, 0x90e40000, 0xa0e40000, 0x0000ffff} + }, + { /* shader 3 */ + "vs_2_0\n" + "mov r0, c0[a0.x]\n", + {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0000000, 0x0000ffff} + }, + { /* shader 4 */ + "vs_2_0\n" + "mov r0, c0[a0.y]\n", + {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0550000, 0x0000ffff} + }, + { /* shader 5 */ + "vs_2_0\n" + "mov r0, c0[a0.z]\n", + {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0aa0000, 0x0000ffff} + }, + { /* shader 6 */ + "vs_2_0\n" + "mov r0, c0[a0.w]\n", + {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0ff0000, 0x0000ffff} + }, + { /* shader 7 */ + "vs_2_0\n" + "mov r0, c0[a0.w].x\n", + {0xfffe0200, 0x03000001, 0x800f0000, 0xa0002000, 0xb0ff0000, 0x0000ffff} + }, + { /* shader 8 */ + "vs_2_0\n" + "mov r0, -c0[a0.w+5].x\n", + {0xfffe0200, 0x03000001, 0x800f0000, 0xa1002005, 0xb0ff0000, 0x0000ffff} + }, + { /* shader 9 */ + "vs_2_0\n" + "mov r0, c0[a0]\n", + {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0e40000, 0x0000ffff} + }, + { /* shader 10 */ + "vs_2_0\n" + "mov r0, c0[a0.xyww]\n", + {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0f40000, 0x0000ffff} + }, + { /* shader 11 */ + "vs_2_0\n" + "add r0, c0[a0.x], c1[a0.y]\n", /* validation would fail on this line */ + {0xfffe0200, 0x05000002, 0x800f0000, 0xa0e42000, 0xb0000000, 0xa0e42001, + 0xb0550000, 0x0000ffff} + }, + { /* shader 12 */ + "vs_2_0\n" + "rep i0\n" + "endrep\n", + {0xfffe0200, 0x01000026, 0xf0e40000, 0x00000027, 0x0000ffff} + }, + { /* shader 13 */ + "vs_2_0\n" + "if b0\n" + "else\n" + "endif\n", + {0xfffe0200, 0x01000028, 0xe0e40800, 0x0000002a, 0x0000002b, 0x0000ffff} + }, + { /* shader 14 */ + "vs_2_0\n" + "loop aL, i0\n" + "endloop\n", + {0xfffe0200, 0x0200001b, 0xf0e40800, 0xf0e40000, 0x0000001d, 0x0000ffff} + }, + { /* shader 15 */ + "vs_2_0\n" + "nrm r0, c0\n", + {0xfffe0200, 0x02000024, 0x800f0000, 0xa0e40000, 0x0000ffff} + }, + { /* shader 16 */ + "vs_2_0\n" + "crs r0, r1, r2\n", + {0xfffe0200, 0x03000021, 0x800f0000, 0x80e40001, 0x80e40002, 0x0000ffff} + }, + { /* shader 17 */ + "vs_2_0\n" + "sgn r0, r1, r2, r3\n", + {0xfffe0200, 0x04000022, 0x800f0000, 0x80e40001, 0x80e40002, 0x80e40003, + 0x0000ffff} + }, + { /* shader 18 */ + "vs_2_0\n" + "sincos r0, r1, r2, r3\n", + {0xfffe0200, 0x04000025, 0x800f0000, 0x80e40001, 0x80e40002, 0x80e40003, + 0x0000ffff} + }, + { /* shader 19 */ + "vs_2_0\n" + "pow r0, r1, r2\n", + {0xfffe0200, 0x03000020, 0x800f0000, 0x80e40001, 0x80e40002, 0x0000ffff} + }, + { /* shader 20 */ + "vs_2_0\n" + "mova a0.y, c0.z\n", + {0xfffe0200, 0x0200002e, 0xb0020000, 0xa0aa0000, 0x0000ffff} + }, + { /* shader 21 */ + "vs_2_0\n" + "defb b0, true\n" + "defb b1, false\n", + {0xfffe0200, 0x0200002f, 0xe00f0800, 0x00000001, 0x0200002f, 0xe00f0801, + 0x00000000, 0x0000ffff} + }, + { /* shader 22 */ + "vs_2_0\n" + "defi i0, -1, 1, 10, 0\n" + "defi i1, 0, 40, 30, 10\n", + {0xfffe0200, 0x05000030, 0xf00f0000, 0xffffffff, 0x00000001, 0x0000000a, + 0x00000000, 0x05000030, 0xf00f0001, 0x00000000, 0x00000028, 0x0000001e, + 0x0000000a, 0x0000ffff} + }, + { /* shader 23 */ + "vs_2_0\n" + "loop aL, i0\n" + "mov r0, c0[aL]\n" + "endloop\n", + {0xfffe0200, 0x0200001b, 0xf0e40800, 0xf0e40000, 0x03000001, 0x800f0000, + 0xa0e42000, 0xf0e40800, 0x0000001d, 0x0000ffff} + }, + { /* shader 24 */ + "vs_2_0\n" + "call l0\n" + "ret\n" + "label l0\n" + "ret\n", + {0xfffe0200, 0x01000019, 0xa0e41000, 0x0000001c, 0x0100001e, 0xa0e41000, + 0x0000001c, 0x0000ffff} + }, + { /* shader 25 */ + "vs_2_0\n" + "callnz l0, b0\n" + "ret\n" + "label l0\n" + "ret\n", + {0xfffe0200, 0x0200001a, 0xa0e41000, 0xe0e40800, 0x0000001c, 0x0100001e, + 0xa0e41000, 0x0000001c, 0x0000ffff} + }, + { /* shader 26 */ + "vs_2_0\n" + "callnz l0, !b0\n" + "ret\n" + "label l0\n" + "ret\n", + {0xfffe0200, 0x0200001a, 0xa0e41000, 0xede40800, 0x0000001c, 0x0100001e, + 0xa0e41000, 0x0000001c, 0x0000ffff} + }, + { /* shader 27 */ + "vs_2_0\n" + "if !b0\n" + "else\n" + "endif\n", + {0xfffe0200, 0x01000028, 0xede40800, 0x0000002a, 0x0000002b, 0x0000ffff} + }, + { /* shader 28 */ + "vs_2_0\n" + "call l3\n" + "ret\n" + "label l3\n" + "ret\n", + {0xfffe0200, 0x01000019, 0xa0e41003, 0x0000001c, 0x0100001e, 0xa0e41003, 0x0000001c, 0x0000ffff} + }, + { /* shader 29: labels up to 2047 are accepted even in vs_2_0 */ + "vs.2.0\n" + "call l2047\n", + {0xfffe0200, 0x01000019, 0xa0e417ff, 0x0000ffff} + }, + }; + + exec_tests("vs_2_0", tests, ARRAY_SIZE(tests)); +} + +static void vs_2_x_test(void) { + struct shader_test tests[] = { + { /* shader 0 */ + "vs_2_x\n" + "rep i0\n" + "break\n" + "endrep\n", + {0xfffe0201, 0x01000026, 0xf0e40000, 0x0000002c, 0x00000027, 0x0000ffff} + }, + { /* shader 1 */ + "vs_2_x\n" + "if_ge r0, r1\n" + "endif\n", + {0xfffe0201, 0x02030029, 0x80e40000, 0x80e40001, 0x0000002b, 0x0000ffff} + }, + { /* shader 2 */ + "vs_2_x\n" + "rep i0\n" + "break_ne r0, r1\n" + "endrep", + {0xfffe0201, 0x01000026, 0xf0e40000, 0x0205002d, 0x80e40000, 0x80e40001, + 0x00000027, 0x0000ffff} + }, + + /* predicates */ + { /* shader 3 */ + "vs_2_x\n" + "setp_gt p0, r0, r1\n" + "(!p0) add r2, r2, r3\n", + {0xfffe0201, 0x0301005e, 0xb00f1000, 0x80e40000, 0x80e40001, 0x14000002, + 0x800f0002, 0xbde41000, 0x80e40002, 0x80e40003, 0x0000ffff} + }, + { /* shader 4 */ + "vs_2_x\n" + "if p0.x\n" + "else\n" + "endif\n", + {0xfffe0201, 0x01000028, 0xb0001000, 0x0000002a, 0x0000002b, 0x0000ffff} + }, + { /* shader 5 */ + "vs_2_x\n" + "callnz l0, !p0.z\n" + "ret\n" + "label l0\n" + "ret\n", + {0xfffe0201, 0x0200001a, 0xa0e41000, 0xbdaa1000, 0x0000001c, + 0x0100001e, 0xa0e41000, 0x0000001c, 0x0000ffff} + }, + { /* shader 6 */ + "vs.2.x\n" + "rep i0\n" + "breakp p0.w\n" + "endrep\n", + {0xfffe0201, 0x01000026, 0xf0e40000, 0x01000060, 0xb0ff1000, + 0x00000027, 0x0000ffff} + }, + }; + + exec_tests("vs_2_x", tests, ARRAY_SIZE(tests)); +} + +static void ps_2_0_test(void) { + struct shader_test tests[] = { + { /* shader 0 */ + "ps_2_0\n" + "dcl_2d s0\n", + {0xffff0200, 0x0200001f, 0x90000000, 0xa00f0800, 0x0000ffff} + }, + { /* shader 1 */ + "ps_2_0\n" + "dcl_cube s0\n", + {0xffff0200, 0x0200001f, 0x98000000, 0xa00f0800, 0x0000ffff} + }, + { /* shader 2 */ + "ps_2_0\n" + "dcl_volume s0\n", + {0xffff0200, 0x0200001f, 0xa0000000, 0xa00f0800, 0x0000ffff} + }, + { /* shader 3 */ + "ps_2_0\n" + "dcl_volume s0\n" + "dcl_cube s1\n" + "dcl_2d s2\n", + {0xffff0200, 0x0200001f, 0xa0000000, 0xa00f0800, 0x0200001f, 0x98000000, + 0xa00f0801, 0x0200001f, 0x90000000, 0xa00f0802, 0x0000ffff} + }, + { /* shader 4 */ + "ps_2_0\n" + "mov r0, t0\n", + {0xffff0200, 0x02000001, 0x800f0000, 0xb0e40000, 0x0000ffff} + }, + { /* shader 5 */ + "ps_2_0\n" + "dcl_2d s2\n" + "texld r0, t1, s2\n", + {0xffff0200, 0x0200001f, 0x90000000, 0xa00f0802, 0x03000042, 0x800f0000, + 0xb0e40001, 0xa0e40802, 0x0000ffff} + }, + { /* shader 6 */ + "ps_2_0\n" + "texkill t0\n", + {0xffff0200, 0x01000041, 0xb00f0000, 0x0000ffff} + }, + { /* shader 7 */ + "ps_2_0\n" + "mov oC0, c0\n" + "mov oC1, c1\n", + {0xffff0200, 0x02000001, 0x800f0800, 0xa0e40000, 0x02000001, 0x800f0801, + 0xa0e40001, 0x0000ffff} + }, + { /* shader 8 */ + "ps_2_0\n" + "mov oDepth, c0.x\n", + {0xffff0200, 0x02000001, 0x900f0800, 0xa0000000, 0x0000ffff} + }, + { /* shader 9 */ + "ps_2_0\n" + "dcl_2d s2\n" + "texldp r0, t1, s2\n", + {0xffff0200, 0x0200001f, 0x90000000, 0xa00f0802, 0x03010042, 0x800f0000, + 0xb0e40001, 0xa0e40802, 0x0000ffff} + }, + { /* shader 10 */ + "ps.2.0\n" + "dcl_2d s2\n" + "texldb r0, t1, s2\n", + {0xffff0200, 0x0200001f, 0x90000000, 0xa00f0802, 0x03020042, 0x800f0000, + 0xb0e40001, 0xa0e40802, 0x0000ffff} + }, + }; + + exec_tests("ps_2_0", tests, ARRAY_SIZE(tests)); +} + +static void ps_2_x_test(void) { + struct shader_test tests[] = { + /* defb and defi are not supposed to work in ps_2_0 (even if defb actually works in ps_2_0 with native) */ + { /* shader 0 */ + "ps_2_x\n" + "defb b0, true\n" + "defb b1, false\n", + {0xffff0201, 0x0200002f, 0xe00f0800, 0x00000001, 0x0200002f, 0xe00f0801, + 0x00000000, 0x0000ffff} + }, + { /* shader 1 */ + "ps_2_x\n" + "defi i0, -1, 1, 10, 0\n" + "defi i1, 0, 40, 30, 10\n", + {0xffff0201, 0x05000030, 0xf00f0000, 0xffffffff, 0x00000001, 0x0000000a, + 0x00000000, 0x05000030, 0xf00f0001, 0x00000000, 0x00000028, 0x0000001e, + 0x0000000a, 0x0000ffff} + }, + { /* shader 2 */ + "ps_2_x\n" + "dsx r0, r0\n", + {0xffff0201, 0x0200005b, 0x800f0000, 0x80e40000, 0x0000ffff} + }, + { /* shader 3 */ + "ps_2_x\n" + "dsy r0, r0\n", + {0xffff0201, 0x0200005c, 0x800f0000, 0x80e40000, 0x0000ffff} + }, + { /* shader 4 */ + "ps_2_x\n" + "dcl_2d s2\n" + "texldd r0, v1, s2, r3, r4\n", + {0xffff0201, 0x0200001f, 0x90000000, 0xa00f0802, 0x0500005d, 0x800f0000, + 0x90e40001, 0xa0e40802, 0x80e40003, 0x80e40004, 0x0000ffff} + }, + /* Static flow control tests */ + { /* shader 5 */ + "ps_2_x\n" + "call l0\n" + "ret\n" + "label l0\n" + "ret\n", + {0xffff0201, 0x01000019, 0xa0e41000, 0x0000001c, 0x0100001e, 0xa0e41000, + 0x0000001c, 0x0000ffff} + }, + { /* shader 6 */ + "ps_2_x\n" + "callnz l0, b0\n" + "ret\n" + "label l0\n" + "ret\n", + {0xffff0201, 0x0200001a, 0xa0e41000, 0xe0e40800, 0x0000001c, 0x0100001e, + 0xa0e41000, 0x0000001c, 0x0000ffff} + }, + { /* shader 7 */ + "ps_2_x\n" + "callnz l0, !b0\n" + "ret\n" + "label l0\n" + "ret\n", + {0xffff0201, 0x0200001a, 0xa0e41000, 0xede40800, 0x0000001c, 0x0100001e, + 0xa0e41000, 0x0000001c, 0x0000ffff} + }, + { /* shader 8 */ + "ps_2_x\n" + "if !b0\n" + "else\n" + "endif\n", + {0xffff0201, 0x01000028, 0xede40800, 0x0000002a, 0x0000002b, 0x0000ffff} + }, + /* Dynamic flow control tests */ + { /* shader 9 */ + "ps_2_x\n" + "rep i0\n" + "break\n" + "endrep\n", + {0xffff0201, 0x01000026, 0xf0e40000, 0x0000002c, 0x00000027, 0x0000ffff} + }, + { /* shader 10 */ + "ps_2_x\n" + "if_ge r0, r1\n" + "endif\n", + {0xffff0201, 0x02030029, 0x80e40000, 0x80e40001, 0x0000002b, 0x0000ffff} + }, + { /* shader 11 */ + "ps_2_x\n" + "rep i0\n" + "break_ne r0, r1\n" + "endrep", + {0xffff0201, 0x01000026, 0xf0e40000, 0x0205002d, 0x80e40000, 0x80e40001, + 0x00000027, 0x0000ffff} + }, + /* Predicates */ + { /* shader 12 */ + "ps_2_x\n" + "setp_gt p0, r0, r1\n" + "(!p0) add r2, r2, r3\n", + {0xffff0201, 0x0301005e, 0xb00f1000, 0x80e40000, 0x80e40001, 0x14000002, + 0x800f0002, 0xbde41000, 0x80e40002, 0x80e40003, 0x0000ffff} + }, + { /* shader 13 */ + "ps_2_x\n" + "if p0.x\n" + "else\n" + "endif\n", + {0xffff0201, 0x01000028, 0xb0001000, 0x0000002a, 0x0000002b, 0x0000ffff} + }, + { /* shader 14 */ + "ps_2_x\n" + "callnz l0, !p0.z\n" + "ret\n" + "label l0\n" + "ret\n", + {0xffff0201, 0x0200001a, 0xa0e41000, 0xbdaa1000, 0x0000001c, + 0x0100001e, 0xa0e41000, 0x0000001c, 0x0000ffff} + }, + { /* shader 15 */ + "ps_2_x\n" + "rep i0\n" + "breakp p0.w\n" + "endrep\n", + {0xffff0201, 0x01000026, 0xf0e40000, 0x01000060, 0xb0ff1000, + 0x00000027, 0x0000ffff} + }, + { /* shader 16 */ + "ps.2.x\n" + "call l2047\n" + "ret\n" + "label l2047\n" + "ret\n", + {0xffff0201, 0x01000019, 0xa0e417ff, 0x0000001c, 0x0100001e, 0xa0e417ff, + 0x0000001c, 0x0000ffff} + }, + }; + + exec_tests("ps_2_x", tests, ARRAY_SIZE(tests)); +} + +static void vs_3_0_test(void) { + struct shader_test tests[] = { + { /* shader 0 */ + "vs_3_0\n" + "mov r0, c0\n", + {0xfffe0300, 0x02000001, 0x800f0000, 0xa0e40000, 0x0000ffff} + }, + { /* shader 1 */ + "vs_3_0\n" + "dcl_2d s0\n", + {0xfffe0300, 0x0200001f, 0x90000000, 0xa00f0800, 0x0000ffff} + }, + { /* shader 2 */ + "vs_3_0\n" + "dcl_position o0\n", + {0xfffe0300, 0x0200001f, 0x80000000, 0xe00f0000, 0x0000ffff} + }, + { /* shader 3 */ + "vs_3_0\n" + "dcl_texcoord12 o11\n", + {0xfffe0300, 0x0200001f, 0x800c0005, 0xe00f000b, 0x0000ffff} + }, + { /* shader 4 */ + "vs_3_0\n" + "texldl r0, v0, s0\n", + {0xfffe0300, 0x0300005f, 0x800f0000, 0x90e40000, 0xa0e40800, 0x0000ffff} + }, + { /* shader 5 */ + "vs_3_0\n" + "mov r0, c0[aL]\n", + {0xfffe0300, 0x03000001, 0x800f0000, 0xa0e42000, 0xf0e40800, 0x0000ffff} + }, + { /* shader 6 */ + "vs_3_0\n" + "mov o[ a0.x + 12 ], r0\n", + {0xfffe0300, 0x03000001, 0xe00f200c, 0xb0000000, 0x80e40000, 0x0000ffff} + }, + { /* shader 7 */ + "vs_3_0\n" + "add_sat r0, r0, r1\n", + {0xfffe0300, 0x03000002, 0x801f0000, 0x80e40000, 0x80e40001, 0x0000ffff} + }, + { /* shader 8 */ + "vs_3_0\n" + "mov r2, r1_abs\n", + {0xfffe0300, 0x02000001, 0x800f0002, 0x8be40001, 0x0000ffff} + }, + { /* shader 9 */ + "vs_3_0\n" + "mov r2, r1.xygb\n", + {0xfffe0300, 0x02000001, 0x800f0002, 0x80940001, 0x0000ffff} + }, + { /* shader 10 */ + "vs_3_0\n" + "mov r2.xyb, r1\n", + {0xfffe0300, 0x02000001, 0x80070002, 0x80e40001, 0x0000ffff} + }, + { /* shader 11 */ + "vs_3_0\n" + "mova_sat a0.x, r1\n", + {0xfffe0300, 0x0200002e, 0xb0110000, 0x80e40001, 0x0000ffff} + }, + { /* shader 12 */ + "vs_3_0\n" + "sincos r0, r1\n", + {0xfffe0300, 0x02000025, 0x800f0000, 0x80e40001, 0x0000ffff} + }, + { /* shader 13 */ + "vs_3_0\n" + "def c0, 1.0f, 1.0f, 1.0f, 0.5f\n", + {0xfffe0300, 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, + 0x3f000000, 0x0000ffff} + }, + { /* shader 14: no register number checks with relative addressing */ + "vs.3.0\n" + "add r0, v20[aL], r2\n", + {0xfffe0300, 0x04000002, 0x800f0000, 0x90e42014, 0xf0e40800, 0x80e40002, + 0x0000ffff} + }, + + }; + + exec_tests("vs_3_0", tests, ARRAY_SIZE(tests)); +} + +static void ps_3_0_test(void) { + struct shader_test tests[] = { + { /* shader 0 */ + "ps_3_0\n" + "mov r0, c0\n", + {0xffff0300, 0x02000001, 0x800f0000, 0xa0e40000, 0x0000ffff} + }, + { /* shader 1 */ + "ps_3_0\n" + "dcl_normal5 v0\n", + {0xffff0300, 0x0200001f, 0x80050003, 0x900f0000, 0x0000ffff} + }, + { /* shader 2 */ + "ps_3_0\n" + "mov r0, vPos\n", + {0xffff0300, 0x02000001, 0x800f0000, 0x90e41000, 0x0000ffff} + }, + { /* shader 3 */ + "ps_3_0\n" + "mov r0, vFace\n", + {0xffff0300, 0x02000001, 0x800f0000, 0x90e41001, 0x0000ffff} + }, + { /* shader 4 */ + "ps_3_0\n" + "mov r0, v[ aL + 12 ]\n", + {0xffff0300, 0x03000001, 0x800f0000, 0x90e4200c, 0xf0e40800, 0x0000ffff} + }, + { /* shader 5 */ + "ps_3_0\n" + "loop aL, i0\n" + "mov r0, v0[aL]\n" + "endloop\n", + {0xffff0300, 0x0200001b, 0xf0e40800, 0xf0e40000, 0x03000001, 0x800f0000, + 0x90e42000, 0xf0e40800, 0x0000001d, 0x0000ffff} + }, + { /* shader 6 */ + "ps_3_0\n" + "texldl r0, v0, s0\n", + {0xffff0300, 0x0300005f, 0x800f0000, 0x90e40000, 0xa0e40800, 0x0000ffff} + }, + { /* shader 7 */ + "ps_3_0\n" + "add_pp r0, r0, r1\n", + {0xffff0300, 0x03000002, 0x802f0000, 0x80e40000, 0x80e40001, 0x0000ffff} + }, + { /* shader 8 */ + "ps_3_0\n" + "dsx_sat r0, r1\n", + {0xffff0300, 0x0200005b, 0x801f0000, 0x80e40001, 0x0000ffff} + }, + { /* shader 9 */ + "ps_3_0\n" + "texldd_pp r0, r1, r2, r3, r4\n", + {0xffff0300, 0x0500005d, 0x802f0000, 0x80e40001, 0x80e40002, 0x80e40003, + 0x80e40004, 0x0000ffff} + }, + { /* shader 10 */ + "ps_3_0\n" + "texkill v0\n", + {0xffff0300, 0x01000041, 0x900f0000, 0x0000ffff} + }, + { /* shader 11 */ + "ps_3_0\n" + "add oC3, r0, r1\n", + {0xffff0300, 0x03000002, 0x800f0803, 0x80e40000, 0x80e40001, 0x0000ffff} + }, + { /* shader 12 */ + "ps_3_0\n" + "dcl_texcoord0_centroid v0\n", + {0xffff0300, 0x0200001f, 0x80000005, 0x904f0000, 0x0000ffff} + }, + { /* shader 13 */ + "ps_3_0\n" + "dcl_2d_centroid s0\n", + {0xffff0300, 0x0200001f, 0x90000000, 0xa04f0800, 0x0000ffff} + }, + { /* shader 14 */ + "ps.3.0\n" + "dcl_2d_pp s0\n", + {0xffff0300, 0x0200001f, 0x90000000, 0xa02f0800, 0x0000ffff} + }, + }; + + exec_tests("ps_3_0", tests, ARRAY_SIZE(tests)); +} + +static void failure_test(void) { + const char * tests[] = { + /* shader 0: instruction modifier not allowed */ + "ps_3_0\n" + "dcl_2d s2\n" + "texldd_x2 r0, v1, s2, v3, v4\n", + /* shader 1: coissue not supported in vertex shaders */ + "vs.1.1\r\n" + "add r0.rgb, r0, r1\n" + "+add r0.a, r0, r2\n", + /* shader 2: coissue not supported in pixel shader version >= 2.0 */ + "ps_2_0\n" + "texld r0, t0, s0\n" + "add r0.rgb, r0, r1\n" + "+add r0.a, r0, v1\n", + /* shader 3: predicates not supported in vertex shader < 2.0 */ + "vs_1_1\n" + "(p0) add r0, r0, v0\n", + /* shader 4: register a0 doesn't exist in pixel shaders */ + "ps_3_0\n" + "mov r0, v[ a0 + 12 ]\n", + /* shader 5: s0 doesn't exist in vs_1_1 */ + "vs_1_1\n" + "mov r0, s0\n", + /* shader 6: aL is a scalar register, no swizzles allowed */ + "ps_3_0\n" + "mov r0, v[ aL.x + 12 ]\n", + /* shader 7: tn doesn't exist in ps_3_0 */ + "ps_3_0\n" + "dcl_2d s2\n" + "texldd r0, t1, s2, v3, v4\n", + /* shader 8: two shift modifiers */ + "ps_1_3\n" + "mov_x2_x2 r0, r1\n", + /* shader 9: too many source registers for mov instruction */ + "vs_1_1\n" + "mov r0, r1, r2\n", + /* shader 10: invalid combination of negate and divide modifiers */ + "ps_1_4\n" + "texld r5, -r2_dz\n", + /* shader 11: complement modifier not allowed in >= PS 2 */ + "ps_2_0\n" + "mov r2, 1 - r0\n", + /* shader 12: invalid modifier */ + "vs_3_0\n" + "mov r2, 2 - r0\n", + /* shader 13: float value in relative addressing */ + "vs_3_0\n" + "mov r2, c[ aL + 3.4 ]\n", + /* shader 14: complement modifier not available in VS */ + "vs_3_0\n" + "mov r2, 1 - r1\n", + /* shader 15: _x2 modifier not available in VS */ + "vs_1_1\n" + "mov r2, r1_x2\n", + /* shader 16: _abs modifier not available in < VS 3.0 */ + "vs_1_1\n" + "mov r2, r1_abs\n", + /* shader 17: _x2 modifier not available in >= PS 2.0 */ + "ps_2_0\n" + "mov r0, r1_x2\n", + /* shader 18: wrong swizzle */ + "vs_2_0\n" + "mov r0, r1.abcd\n", + /* shader 19: wrong swizzle */ + "vs_2_0\n" + "mov r0, r1.xyzwx\n", + /* shader 20: wrong swizzle */ + "vs_2_0\n" + "mov r0, r1.\n", + /* shader 21: invalid writemask */ + "vs_2_0\n" + "mov r0.xxyz, r1\n", + /* shader 22: register r5 doesn't exist in PS < 1.4 */ + "ps_1_3\n" + "mov r5, r0\n", + /* shader 23: can't declare output registers in a pixel shader */ + "ps_3_0\n" + "dcl_positiont o0\n", + /* shader 24: _pp instruction modifier not allowed in vertex shaders */ + "vs_3_0\n" + "add_pp r0, r0, r1\n", + /* shader 25: _x4 instruction modified not allowed in > ps_1_x */ + "ps_3_0\n" + "add_x4 r0, r0, r1\n", + /* shader 26: there aren't oCx registers in ps_1_x */ + "ps_1_3\n" + "add oC0, r0, r1\n", + /* shader 27: oC3 is the max in >= ps_2_0 */ + "ps_3_0\n" + "add oC4, r0, r1\n", + /* shader 28: register v17 doesn't exist */ + "vs_3_0\n" + "add r0, r0, v17\n", + /* shader 29: register o13 doesn't exist */ + "vs_3_0\n" + "add o13, r0, r1\n", + /* shader 30: label > 2047 not allowed */ + "vs_3_0\n" + "call l2048\n", + /* shader 31: s20 register does not exist */ + "ps_3_0\n" + "texld r0, r1, s20\n", + /* shader 32: t5 not allowed in ps_1_3 */ + "ps_1_3\n" + "tex t5\n", + /* shader 33: no temporary registers relative addressing */ + "vs_3_0\n" + "add r0, r0[ a0.x ], r1\n", + /* shader 34: no input registers relative addressing in vs_2_0 */ + "vs_2_0\n" + "add r0, v[ a0.x ], r1\n", + /* shader 35: no aL register in ps_2_0 */ + "ps_2_0\n" + "add r0, v[ aL ], r1\n", + /* shader 36: no relative addressing in ps_2_0 */ + "ps_2_0\n" + "add r0, v[ r0 ], r1\n", + /* shader 37: no a0 register in ps_3_0 */ + "ps_3_0\n" + "add r0, v[ a0.x ], r1\n", + /* shader 38: only a0.x accepted in vs_1_1 */ + "vs_1_1\n" + "mov r0, c0[ a0 ]\n", + /* shader 39: invalid modifier for dcl instruction */ + "ps_3_0\n" + "dcl_texcoord0_sat v0\n", + /* shader 40: shift not allowed */ + "ps_3_0\n" + "dcl_texcoord0_x2 v0\n", + /* shader 41: no modifier allowed with dcl instruction in vs */ + "vs_3_0\n" + "dcl_texcoord0_centroid v0\n", + /* shader 42: no modifiers with vs dcl sampler instruction */ + "vs_3_0\n" + "dcl_2d_pp s0\n", + /* shader 43: */ + "ps_2_0\n" + "texm3x3vspec t3, t0\n", + }; + HRESULT hr; + unsigned int i; + ID3DBlob *shader, *messages; + + for(i = 0; i < ARRAY_SIZE(tests); i++) + { + shader = NULL; + messages = NULL; + hr = pD3DAssemble(tests[i], strlen(tests[i]), NULL, + NULL, NULL, D3DCOMPILE_SKIP_VALIDATION, + &shader, &messages); + ok(hr == D3DXERR_INVALIDDATA, "Failure test, shader %d: " + "expected D3DAssemble failure with D3DXERR_INVALIDDATA, " + "got 0x%x - %d\n", i, hr, hr & 0x0000FFFF); + if(messages) { + trace("D3DAssemble messages:\n%s", (char *)ID3D10Blob_GetBufferPointer(messages)); + ID3D10Blob_Release(messages); + } + if(shader) { + DWORD *res = ID3D10Blob_GetBufferPointer(shader); + dump_shader(res); + ID3D10Blob_Release(shader); + } + } +} + +static HRESULT WINAPI testD3DInclude_open(ID3DInclude *iface, D3D_INCLUDE_TYPE include_type, + const char *filename, const void *parent_data, const void **data, UINT *bytes) +{ + static const char include[] = "#define REGISTER r0\nvs.1.1\n"; + static const char include2[] = "#include \"incl3.vsh\"\n"; + static const char include3[] = "vs.1.1\n"; + static const char include4[] = "#include <incl3.vsh>\n"; + char *buffer; + + trace("include_type = %d, filename %s\n", include_type, filename); + trace("parent_data (%p) -> %s\n", parent_data, parent_data ? (char *)parent_data : "(null)"); + + if (!strcmp(filename, "incl.vsh")) + { + buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include)); + CopyMemory(buffer, include, sizeof(include)); + *bytes = sizeof(include); + ok(!parent_data, "Wrong parent_data value.\n"); + } + else if (!strcmp(filename, "incl2.vsh")) + { + buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include2)); + CopyMemory(buffer, include2, sizeof(include2)); + *bytes = sizeof(include2); + ok(!parent_data, "Wrong parent_data value.\n"); + ok(include_type == D3D_INCLUDE_LOCAL, "Wrong include type %d.\n", include_type); + } + else if (!strcmp(filename, "incl3.vsh")) + { + buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include3)); + CopyMemory(buffer, include3, sizeof(include3)); + *bytes = sizeof(include3); + /* Also check for the correct parent_data content */ + ok(parent_data != NULL + && (!strncmp(include2, parent_data, strlen(include2)) + || !strncmp(include4, parent_data, strlen(include4))), + "Wrong parent_data value.\n"); + } + else if (!strcmp(filename, "incl4.vsh")) + { + buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include4)); + CopyMemory(buffer, include4, sizeof(include4)); + *bytes = sizeof(include4); + ok(parent_data == NULL, "Wrong parent_data value.\n"); + ok(include_type == D3D_INCLUDE_SYSTEM, "Wrong include type %d.\n", include_type); + } + else if (!strcmp(filename, "includes/incl.vsh")) + { + buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include)); + CopyMemory(buffer, include, sizeof(include)); + *bytes = sizeof(include); + ok(!parent_data, "Wrong parent_data value.\n"); + } + else + { + ok(FALSE, "Unexpected file %s included.\n", filename); + return E_FAIL; + } + + *data = buffer; + + return S_OK; +} + +static HRESULT WINAPI testD3DInclude_close(ID3DInclude *iface, const void *data) +{ + HeapFree(GetProcessHeap(), 0, (void *)data); + return S_OK; +} + +static const struct ID3DIncludeVtbl D3DInclude_Vtbl = +{ + testD3DInclude_open, + testD3DInclude_close +}; + +struct D3DIncludeImpl { + ID3DInclude ID3DInclude_iface; +}; + +static void assembleshader_test(void) { + static const char test1[] = + { + "vs.1.1\n" + "mov DEF2, v0\n" + }; + static const char testshader[] = + { + "#include \"incl.vsh\"\n" + "mov REGISTER, v0\n" + }; + static const D3D_SHADER_MACRO defines[] = + { + { + "DEF1", "10 + 15" + }, + { + "DEF2", "r0" + }, + { + NULL, NULL + } + }; + HRESULT hr; + ID3DBlob *shader, *messages; + struct D3DIncludeImpl include; + + /* defines test */ + shader = NULL; + messages = NULL; + hr = pD3DAssemble(test1, strlen(test1), NULL, + defines, NULL, D3DCOMPILE_SKIP_VALIDATION, + &shader, &messages); + ok(hr == S_OK, "defines test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); + if(messages) { + trace("D3DAssemble messages:\n%s", (char *)ID3D10Blob_GetBufferPointer(messages)); + ID3D10Blob_Release(messages); + } + if(shader) ID3D10Blob_Release(shader); + + /* NULL messages test */ + shader = NULL; + hr = pD3DAssemble(test1, strlen(test1), NULL, + defines, NULL, D3DCOMPILE_SKIP_VALIDATION, + &shader, NULL); + ok(hr == S_OK, "NULL messages test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); + if(shader) ID3D10Blob_Release(shader); + + /* NULL shader test */ + messages = NULL; + hr = pD3DAssemble(test1, strlen(test1), NULL, + defines, NULL, D3DCOMPILE_SKIP_VALIDATION, + NULL, &messages); + ok(hr == S_OK, "NULL shader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); + if(messages) { + trace("D3DAssemble messages:\n%s", (char *)ID3D10Blob_GetBufferPointer(messages)); + ID3D10Blob_Release(messages); + } + + /* D3DInclude test */ + shader = NULL; + messages = NULL; + include.ID3DInclude_iface.lpVtbl = &D3DInclude_Vtbl; + hr = pD3DAssemble(testshader, strlen(testshader), NULL, NULL, &include.ID3DInclude_iface, + D3DCOMPILE_SKIP_VALIDATION, &shader, &messages); + ok(hr == S_OK, "D3DInclude test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); + if(messages) { + trace("D3DAssemble messages:\n%s", (char *)ID3D10Blob_GetBufferPointer(messages)); + ID3D10Blob_Release(messages); + } + if(shader) ID3D10Blob_Release(shader); + + /* NULL shader tests */ + shader = NULL; + messages = NULL; + hr = pD3DAssemble(NULL, 0, NULL, + NULL, NULL, D3DCOMPILE_SKIP_VALIDATION, + &shader, &messages); + ok(hr == D3DXERR_INVALIDDATA, "NULL shader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); + if(messages) { + trace("D3DAssemble messages:\n%s", (char *)ID3D10Blob_GetBufferPointer(messages)); + ID3D10Blob_Release(messages); + } + if(shader) ID3D10Blob_Release(shader); +} + +static void d3dpreprocess_test(void) +{ + static const char test1[] = + { + "vs.1.1\n" + "mov DEF2, v0\n" + }; + static const char quotation_marks_test[] = + { + "vs.1.1\n" + "; ' comment\n" + "; \" comment\n" + "mov 0, v0\n" + }; + static const char *include_test_shaders[] = + { + "#include \"incl.vsh\"\n" + "mov REGISTER, v0\n", + + "#include \"incl2.vsh\"\n" + "mov REGISTER, v0\n", + + "#include <incl.vsh>\n" + "mov REGISTER, v0\n", + + "#include <incl4.vsh>\n" + "mov REGISTER, v0\n", + + "#include \"includes/incl.vsh\"\n" + "mov REGISTER, v0\n" + }; + HRESULT hr; + ID3DBlob *shader, *messages; + static const D3D_SHADER_MACRO defines[] = + { + { + "DEF1", "10 + 15" + }, + { + "DEF2", "r0" + }, + { + NULL, NULL + } + }; + struct D3DIncludeImpl include; + unsigned int i; + + /* pDefines test */ + shader = NULL; + messages = NULL; + hr = ppD3DPreprocess(test1, strlen(test1), NULL, + defines, NULL, &shader, &messages); + ok(hr == S_OK, "pDefines test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); + if (messages) + { + trace("D3DPreprocess messages:\n%s", (char *)ID3D10Blob_GetBufferPointer(messages)); + ID3D10Blob_Release(messages); + } + if (shader) ID3D10Blob_Release(shader); + + /* NULL messages test */ + shader = NULL; + hr = ppD3DPreprocess(test1, strlen(test1), NULL, + defines, NULL, &shader, NULL); + ok(hr == S_OK, "NULL messages test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); + if (shader) ID3D10Blob_Release(shader); + + /* NULL shader test */ + messages = NULL; + hr = ppD3DPreprocess(test1, strlen(test1), NULL, + defines, NULL, NULL, &messages); + ok(hr == E_INVALIDARG, "NULL shader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); + if (messages) + { + trace("D3DPreprocess messages:\n%s", (char *)ID3D10Blob_GetBufferPointer(messages)); + ID3D10Blob_Release(messages); + } + + /* quotation marks test */ + shader = NULL; + messages = NULL; + hr = ppD3DPreprocess(quotation_marks_test, strlen(quotation_marks_test), NULL, + NULL, NULL, &shader, &messages); + todo_wine ok(hr == S_OK, "quotation marks test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); + if (messages) + { + trace("D3DPreprocess messages:\n%s", (char *)ID3D10Blob_GetBufferPointer(messages)); + ID3D10Blob_Release(messages); + } + if (shader) ID3D10Blob_Release(shader); + + /* pInclude tests */ + include.ID3DInclude_iface.lpVtbl = &D3DInclude_Vtbl; + for (i = 0; i < ARRAY_SIZE(include_test_shaders); ++i) + { + shader = NULL; + messages = NULL; + hr = ppD3DPreprocess(include_test_shaders[i], strlen(include_test_shaders[i]), NULL, NULL, + &include.ID3DInclude_iface, &shader, &messages); + ok(hr == S_OK, "pInclude test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); + if (messages) + { + trace("D3DPreprocess messages:\n%s", (char *)ID3D10Blob_GetBufferPointer(messages)); + ID3D10Blob_Release(messages); + } + if (shader) ID3D10Blob_Release(shader); + } + + /* NULL shader tests */ + shader = NULL; + messages = NULL; + hr = ppD3DPreprocess(NULL, 0, NULL, + NULL, NULL, &shader, &messages); + ok(hr == E_INVALIDARG, "NULL shader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); + if (messages) + { + trace("D3DPreprocess messages:\n%s", (char *)ID3D10Blob_GetBufferPointer(messages)); + ID3D10Blob_Release(messages); + } + if (shader) ID3D10Blob_Release(shader); +} + +static BOOL load_d3dcompiler(void) +{ + HMODULE module; + + if (!(module = LoadLibraryA("d3dcompiler_43.dll"))) return FALSE; + + pD3DAssemble = (void*)GetProcAddress(module, "D3DAssemble"); + ppD3DPreprocess = (void*)GetProcAddress(module, "D3DPreprocess"); + return TRUE; +} + +START_TEST(asm) +{ + if (!load_d3dcompiler()) + { + win_skip("Could not load d3dcompiler_43.dll\n"); + return; + } + + preproc_test(); + ps_1_1_test(); + vs_1_1_test(); + ps_1_3_test(); + ps_1_4_test(); + vs_2_0_test(); + vs_2_x_test(); + ps_2_0_test(); + ps_2_x_test(); + vs_3_0_test(); + ps_3_0_test(); + + failure_test(); + + assembleshader_test(); + + d3dpreprocess_test(); +} diff --git a/modules/rostests/winetests/d3dcompiler_43/blob.c b/modules/rostests/winetests/d3dcompiler_43/blob.c new file mode 100644 index 00000000000..3e1a3aa3da3 --- /dev/null +++ b/modules/rostests/winetests/d3dcompiler_43/blob.c @@ -0,0 +1,886 @@ +/* + * Copyright 2010 Rico Schüller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * Nearly all compiler functions need the shader blob and the size. The size + * is always located at DWORD #6 in the shader blob (blob[6]). + * The functions are e.g.: D3DGet*SignatureBlob, D3DReflect + */ + +#define COBJMACROS +#include "d3dcompiler.h" +#include "wine/test.h" + +/* + * This doesn't belong here, but for some functions it is possible to return that value, + * see
http://msdn.microsoft.com/en-us/library/bb205278%28v=VS.85%29.aspx
+ * The original definition is in D3DX10core.h. + */ +#define D3DERR_INVALIDCALL 0x8876086c + +static HRESULT (WINAPI *pD3DCreateBlob)(SIZE_T, ID3DBlob **); +static HRESULT (WINAPI *pD3DGetBlobPart)(const void *, SIZE_T, D3D_BLOB_PART, UINT, ID3DBlob **); +static HRESULT (WINAPI *pD3DReadFileToBlob)(const WCHAR *, ID3DBlob **); +static HRESULT (WINAPI *pD3DStripShader)(const void *, SIZE_T, UINT, ID3DBlob **); + +#define MAKE_TAG(ch0, ch1, ch2, ch3) \ + ((DWORD)(ch0) | ((DWORD)(ch1) << 8) | \ + ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) +#define TAG_Aon9 MAKE_TAG('A', 'o', 'n', '9') +#define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') +#define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N') +#define TAG_OSGN MAKE_TAG('O', 'S', 'G', 'N') +#define TAG_PCSG MAKE_TAG('P', 'C', 'S', 'G') +#define TAG_RDEF MAKE_TAG('R', 'D', 'E', 'F') +#define TAG_SDBG MAKE_TAG('S', 'D', 'B', 'G') +#define TAG_SHDR MAKE_TAG('S', 'H', 'D', 'R') +#define TAG_SHEX MAKE_TAG('S', 'H', 'E', 'X') +#define TAG_STAT MAKE_TAG('S', 'T', 'A', 'T') +#define TAG_XNAP MAKE_TAG('X', 'N', 'A', 'P') +#define TAG_XNAS MAKE_TAG('X', 'N', 'A', 'S') + +static void test_create_blob(void) +{ + ID3D10Blob *blob; + HRESULT hr; + ULONG refcount; + + hr = pD3DCreateBlob(1, NULL); + ok(hr == D3DERR_INVALIDCALL, "D3DCreateBlob failed with %x\n", hr); + + hr = pD3DCreateBlob(0, NULL); + ok(hr == D3DERR_INVALIDCALL, "D3DCreateBlob failed with %x\n", hr); + + hr = pD3DCreateBlob(0, &blob); + ok(hr == S_OK, "D3DCreateBlob failed with %x\n", hr); + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); +} + +static const D3D_BLOB_PART parts[] = +{ + D3D_BLOB_INPUT_SIGNATURE_BLOB, D3D_BLOB_OUTPUT_SIGNATURE_BLOB, D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB, + D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB, D3D_BLOB_ALL_SIGNATURE_BLOB, D3D_BLOB_DEBUG_INFO, + D3D_BLOB_LEGACY_SHADER, D3D_BLOB_XNA_PREPASS_SHADER, D3D_BLOB_XNA_SHADER, + D3D_BLOB_TEST_ALTERNATE_SHADER, D3D_BLOB_TEST_COMPILE_DETAILS, D3D_BLOB_TEST_COMPILE_PERF +}; + +/* + * test_blob_part - fxc.exe /E VS /Tvs_4_0_level_9_0 /Fx + */ +#if 0 +float4 VS(float4 position : POSITION, float4 pos : SV_POSITION) : SV_POSITION +{ + return position; +} +#endif +static DWORD test_blob_part[] = { +0x43425844, 0x0ef2a70f, 0x6a548011, 0x91ff9409, 0x9973a43d, 0x00000001, 0x000002e0, 0x00000008, +0x00000040, 0x0000008c, 0x000000d8, 0x0000013c, 0x00000180, 0x000001fc, 0x00000254, 0x000002ac, +0x53414e58, 0x00000044, 0x00000044, 0xfffe0200, 0x00000020, 0x00000024, 0x00240000, 0x00240000, +0x00240000, 0x00240000, 0x00240000, 0xfffe0200, 0x0200001f, 0x80000005, 0x900f0000, 0x02000001, +0xc00f0000, 0x80e40000, 0x0000ffff, 0x50414e58, 0x00000044, 0x00000044, 0xfffe0200, 0x00000020, +0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0xfffe0200, 0x0200001f, +0x80000005, 0x900f0000, 0x02000001, 0xc00f0000, 0x80e40000, 0x0000ffff, 0x396e6f41, 0x0000005c, +0x0000005c, 0xfffe0200, 0x00000034, 0x00000028, 0x00240000, 0x00240000, 0x00240000, 0x00240000, +0x00240001, 0x00000000, 0xfffe0200, 0x0200001f, 0x80000005, 0x900f0000, 0x04000004, 0xc0030000, +0x90ff0000, 0xa0e40000, 0x90e40000, 0x02000001, 0xc00c0000, 0x90e40000, 0x0000ffff, 0x52444853, +0x0000003c, 0x00010040, 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, +0x00000000, 0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, +0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, +0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, +0x00000050, 0x00000000, 0x00000000, 0x00000000, 0x0000001c, 0xfffe0400, 0x00000100, 0x0000001c, +0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, +0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000050, 0x00000002, +0x00000008, 0x00000038, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, +0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x49534f50, 0x4e4f4954, 0x5f565300, +0x49534f50, 0x4e4f4954, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, +0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, +}; + +static void test_get_blob_part(void) +{ + ID3DBlob *blob, *blob2; + HRESULT hr; + ULONG refcount; + DWORD *dword; + SIZE_T size; + UINT i; + + hr = pD3DCreateBlob(1, &blob2); + ok(hr == S_OK, "D3DCreateBlob failed with %x\n", hr); + blob = blob2; + + /* invalid cases */ + hr = pD3DGetBlobPart(NULL, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, &blob); + ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr); + ok(blob2 == blob, "D3DGetBlobPart failed got %p, expected %p\n", blob, blob2); + + hr = pD3DGetBlobPart(NULL, 0, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, &blob); + ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr); + ok(blob2 == blob, "D3DGetBlobPart failed got %p, expected %p\n", blob, blob2); + + hr = pD3DGetBlobPart(NULL, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, NULL); + ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr); + + hr = pD3DGetBlobPart(NULL, 0, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, NULL); + ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr); + + hr = pD3DGetBlobPart(test_blob_part, 0, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, &blob); + ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr); + ok(blob2 == blob, "D3DGetBlobPart failed got %p, expected %p\n", blob, blob2); + + hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, NULL); + ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr); + + hr = pD3DGetBlobPart(test_blob_part, 0, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, NULL); + ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr); + + hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 1, &blob); + ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr); + ok(blob2 == blob, "D3DGetBlobPart failed got %p, expected %p\n", blob, blob2); + + hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], 0xffffffff, 0, &blob); + ok(hr == D3DERR_INVALIDCALL, "D3DGetBlobPart failed with %x\n", hr); + ok(blob2 == blob, "D3DGetBlobPart failed got %p, expected %p\n", blob, blob2); + + refcount = ID3D10Blob_Release(blob2); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + /* D3D_BLOB_INPUT_SIGNATURE_BLOB */ + hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, &blob); + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 124, "GetBufferSize failed, got %lu, expected %u\n", size, 124); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(TAG_DXBC == *dword, "DXBC got %#x, expected %#x.\n", *dword, TAG_DXBC); + ok(TAG_ISGN == *(dword+9), "ISGN got %#x, expected %#x.\n", *(dword+9), TAG_ISGN); + + for (i = 0; i < ARRAY_SIZE(parts); i++) + { + hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2); + + if (parts[i] == D3D_BLOB_INPUT_SIGNATURE_BLOB) + { + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + refcount = ID3D10Blob_Release(blob2); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + } + else + { + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + } + } + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + /* D3D_BLOB_OUTPUT_SIGNATURE_BLOB */ + hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_OUTPUT_SIGNATURE_BLOB, 0, &blob); + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 88, "GetBufferSize failed, got %lu, expected %u\n", size, 88); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(TAG_DXBC == *dword, "DXBC got %#x, expected %#x.\n", *dword, TAG_DXBC); + ok(TAG_OSGN == *(dword+9), "OSGN got %#x, expected %#x.\n", *(dword+9), TAG_OSGN); + + for (i = 0; i < ARRAY_SIZE(parts); i++) + { + hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2); + + if (parts[i] == D3D_BLOB_OUTPUT_SIGNATURE_BLOB) + { + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + refcount = ID3D10Blob_Release(blob2); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + } + else + { + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + } + } + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + /* D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB */ + hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB, 0, &blob); + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 180, "GetBufferSize failed, got %lu, expected %u\n", size, 180); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(TAG_DXBC == *dword, "DXBC got %#x, expected %#x.\n", *dword, TAG_DXBC); + ok(TAG_ISGN == *(dword+10), "ISGN got %#x, expected %#x.\n", *(dword+10), TAG_ISGN); + ok(TAG_OSGN == *(dword+32), "OSGN got %#x, expected %#x.\n", *(dword+32), TAG_OSGN); + + for (i = 0; i < ARRAY_SIZE(parts); i++) + { + hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2); + + if (parts[i] == D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB + || parts[i] == D3D_BLOB_INPUT_SIGNATURE_BLOB + || parts[i] == D3D_BLOB_OUTPUT_SIGNATURE_BLOB) + { + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + refcount = ID3D10Blob_Release(blob2); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + } + else + { + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + } + } + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + /* D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB */ + hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB, 0, &blob); + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + + /* D3D_BLOB_ALL_SIGNATURE_BLOB */ + hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_ALL_SIGNATURE_BLOB, 0, &blob); + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + + /* D3D_BLOB_DEBUG_INFO */ + hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_DEBUG_INFO, 0, &blob); + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + + /* D3D_BLOB_LEGACY_SHADER */ + hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_LEGACY_SHADER, 0, &blob); + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 92, "GetBufferSize failed, got %lu, expected %u\n", size, 92); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(test_blob_part[0] != *dword, "DXBC failed got %#x.\n", *dword); + + for (i = 0; i < ARRAY_SIZE(parts); i++) + { + /* There isn't a full DXBC blob returned for D3D_BLOB_LEGACY_SHADER */ + hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2); + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + } + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + /* D3D_BLOB_XNA_PREPASS_SHADER */ + hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_XNA_PREPASS_SHADER, 0, &blob); + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 68, "GetBufferSize failed, got %lu, expected %u\n", size, 68); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(test_blob_part[0] != *dword, "DXBC failed got %#x.\n", *dword); + + for (i = 0; i < ARRAY_SIZE(parts); i++) + { + /* There isn't a full DXBC blob returned for D3D_BLOB_XNA_PREPASS_SHADER */ + hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2); + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + } + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + /* D3D_BLOB_XNA_SHADER */ + hr = pD3DGetBlobPart(test_blob_part, test_blob_part[6], D3D_BLOB_XNA_SHADER, 0, &blob); + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 68, "GetBufferSize failed, got %lu, expected %u\n", size, 68); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(test_blob_part[0] != *dword, "DXBC failed got %#x.\n", *dword); + + for (i = 0; i < ARRAY_SIZE(parts); i++) + { + /* There isn't a full DXBC blob returned for D3D_BLOB_XNA_SHADER */ + hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2); + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + } + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + /* check corner cases for D3DStripShader */ + hr = pD3DStripShader(test_blob_part, test_blob_part[6], 0xffffffff, &blob); + ok(hr == S_OK, "D3DStripShader failed, got %x, expected %x\n", hr, S_OK); + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + hr = pD3DStripShader(test_blob_part, test_blob_part[6], 0, &blob); + ok(hr == S_OK, "D3DStripShader failed, got %x, expected %x\n", hr, S_OK); + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + hr = pD3DStripShader(NULL, test_blob_part[6], 0, &blob); + ok(hr == D3DERR_INVALIDCALL, "D3DStripShader failed, got %x, expected %x\n", hr, D3DERR_INVALIDCALL); + + hr = pD3DStripShader(test_blob_part, 2, 0, &blob); + ok(hr == D3DERR_INVALIDCALL, "D3DStripShader failed, got %x, expected %x\n", hr, D3DERR_INVALIDCALL); + + hr = pD3DStripShader(test_blob_part, test_blob_part[6], 0, NULL); + ok(hr == E_FAIL, "D3DStripShader failed, got %x, expected %x\n", hr, E_FAIL); + + hr = pD3DStripShader(NULL, test_blob_part[6], 0, NULL); + ok(hr == E_FAIL, "D3DStripShader failed, got %x, expected %x\n", hr, E_FAIL); + + hr = pD3DStripShader(test_blob_part, 0, 0, NULL); + ok(hr == E_FAIL, "D3DStripShader failed, got %x, expected %x\n", hr, E_FAIL); + + /* D3DCOMPILER_STRIP_DEBUG_INFO */ + hr = pD3DStripShader(test_blob_part, test_blob_part[6], D3DCOMPILER_STRIP_DEBUG_INFO, &blob); + ok(hr == S_OK, "D3DStripShader failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 736, "GetBufferSize failed, got %lu, expected %u\n", size, 736); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(TAG_DXBC == *dword, "DXBC got %#x, expected %#x.\n", *dword, TAG_DXBC); + ok(TAG_XNAS == *(dword+16), "XNAS got %#x, expected %#x.\n", *(dword+16), TAG_XNAS); + ok(TAG_XNAP == *(dword+35), "XNAP got %#x, expected %#x.\n", *(dword+35), TAG_XNAP); + ok(TAG_Aon9 == *(dword+54), "Aon9 got %#x, expected %#x.\n", *(dword+54), TAG_Aon9); + ok(TAG_SHDR == *(dword+79), "SHDR got %#x, expected %#x.\n", *(dword+79), TAG_SHDR); + ok(TAG_STAT == *(dword+96), "STAT got %#x, expected %#x.\n", *(dword+96), TAG_STAT); + ok(TAG_RDEF == *(dword+127), "RDEF got %#x, expected %#x.\n", *(dword+127), TAG_RDEF); + ok(TAG_ISGN == *(dword+149), "ISGN got %#x, expected %#x.\n", *(dword+149), TAG_ISGN); + ok(TAG_OSGN == *(dword+171), "OSGN got %#x, expected %#x.\n", *(dword+171), TAG_OSGN); + + hr = pD3DGetBlobPart(dword, size, D3D_BLOB_DEBUG_INFO, 0, &blob2); + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + /* D3DCOMPILER_STRIP_REFLECTION_DATA */ + hr = pD3DStripShader(test_blob_part, test_blob_part[6], D3DCOMPILER_STRIP_REFLECTION_DATA, &blob); + ok(hr == S_OK, "D3DStripShader failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 516, "GetBufferSize failed, got %lu, expected %u\n", size, 516); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(TAG_DXBC == *dword, "DXBC got %#x, expected %#x.\n", *dword, TAG_DXBC); + ok(TAG_XNAS == *(dword+14), "XNAS got %#x, expected %#x.\n", *(dword+14), TAG_XNAS); + ok(TAG_XNAP == *(dword+33), "XNAP got %#x, expected %#x.\n", *(dword+33), TAG_XNAP); + ok(TAG_Aon9 == *(dword+52), "Aon9 got %#x, expected %#x.\n", *(dword+52), TAG_Aon9); + ok(TAG_SHDR == *(dword+77), "SHDR got %#x, expected %#x.\n", *(dword+77), TAG_SHDR); + ok(TAG_ISGN == *(dword+94), "ISGN got %#x, expected %#x.\n", *(dword+94), TAG_ISGN); + ok(TAG_OSGN == *(dword+116), "OSGN got %#x, expected %#x.\n", *(dword+116), TAG_OSGN); + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); +} + +/* + * test_blob_part2 - fxc.exe /E BHS /Ths_5_0 /Zi + */ +#if 0 +struct VSO { float3 p : POSITION; }; +struct HSDO { float e[4] : SV_TessFactor; float i[2] : SV_InsideTessFactor; }; +struct HSO { float3 p : BEZIERPOS; }; +HSDO BCHS( InputPatch<VSO, 8> ip, uint PatchID : SV_PrimitiveID ) +{ + HSDO res; + res.e[0] = res.e[1] = res.e[2] = res.e[3] = 1.0f; + res.i[0] = res.i[1] = 1.0f; + return res; +} +[domain("quad")] +[partitioning("integer")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(8)] +[patchconstantfunc("BCHS")] +HSO BHS( InputPatch<VSO, 8> p, uint i : SV_OutputControlPointID, uint PatchID : SV_PrimitiveID ) +{ + HSO res; + res.p = p[i].p; + return res; +} +#endif +static DWORD test_blob_part2[] = { +0x43425844, 0xa9d455ae, 0x4cf9c0df, 0x4cf806dc, 0xc57a8c2c, 0x00000001, 0x0000139b, 0x00000007, +0x0000003c, 0x000000b4, 0x000000e8, 0x0000011c, 0x000001e0, 0x00000320, 0x000003bc, 0x46454452, +0x00000070, 0x00000000, 0x00000000, 0x00000000, 0x0000003c, 0x48530500, 0x00000101, 0x0000003c, +0x31314452, 0x0000003c, 0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, +0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, +0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x0000002c, 0x00000001, +0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x49534f50, +0x4e4f4954, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, +0x00000000, 0x00000003, 0x00000000, 0x00000807, 0x495a4542, 0x4f505245, 0xabab0053, 0x47534350, +0x000000bc, 0x00000006, 0x00000008, 0x00000098, 0x00000000, 0x0000000b, 0x00000003, 0x00000000, +0x00000e01, 0x00000098, 0x00000001, 0x0000000b, 0x00000003, 0x00000001, 0x00000e01, 0x00000098, +0x00000002, 0x0000000b, 0x00000003, 0x00000002, 0x00000e01, 0x00000098, 0x00000003, 0x0000000b, +0x00000003, 0x00000003, 0x00000e01, 0x000000a6, 0x00000000, 0x0000000c, 0x00000003, 0x00000004, +0x00000e01, 0x000000a6, 0x00000001, 0x0000000c, 0x00000003, 0x00000005, 0x00000e01, 0x545f5653, +0x46737365, 0x6f746361, 0x56530072, 0x736e495f, 0x54656469, 0x46737365, 0x6f746361, 0xabab0072, +0x58454853, 0x00000138, 0x00030050, 0x0000004e, 0x01000071, 0x01004093, 0x01004094, 0x01001895, +0x01000896, 0x01001897, 0x0100086a, 0x01000073, 0x02000099, 0x00000004, 0x0200005f, 0x00017000, +0x04000067, 0x00102012, 0x00000000, 0x0000000b, 0x04000067, 0x00102012, 0x00000001, 0x0000000c, +0x04000067, 0x00102012, 0x00000002, 0x0000000d, 0x04000067, 0x00102012, 0x00000003, 0x0000000e, +0x02000068, 0x00000001, 0x0400005b, 0x00102012, 0x00000000, 0x00000004, 0x04000036, 0x00100012, +0x00000000, 0x0001700a, 0x06000036, 0x00902012, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, +0x0100003e, 0x01000073, 0x02000099, 0x00000002, 0x0200005f, 0x00017000, 0x04000067, 0x00102012, +0x00000004, 0x0000000f, 0x04000067, 0x00102012, 0x00000005, 0x00000010, 0x02000068, 0x00000001, +0x0400005b, 0x00102012, 0x00000004, 0x00000002, 0x04000036, 0x00100012, 0x00000000, 0x0001700a, +0x07000036, 0x00d02012, 0x00000004, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0100003e, +0x54415453, 0x00000094, 0x00000006, 0x00000001, 0x00000000, 0x00000005, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x0000000f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000008, 0x00000003, 0x00000001, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x47424453, +0x00000fd7, 0x00000054, 0x000002d5, 0x00000306, 0x0000030a, 0x00000101, 0x00000001, 0x00000000, +0x00000006, 0x00000010, 0x00000006, 0x00000958, 0x00000000, 0x000009e8, 0x00000008, 0x000009e8, +0x00000006, 0x00000a88, 0x00000007, 0x00000b00, 0x00000c34, 0x00000c64, 0x00000000, 0x0000004a, +0x0000004a, 0x0000026a, 0x00000000, 0x00000036, 0x00000001, 0x00000004, 0x00000000, 0xffffffff, +0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000003, 0x00000000, +0x00000003, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000007, +0x00000000, 0x00000003, 0x00000024, 0x00000000, 0x00000000, 0x00000001, 0x00000036, 0x00000001, +0x00000001, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, +0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, +0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000003, 0x00000024, 0x00000000, 0x00000000, +0x00000002, 0x0000003e, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000003, +0x00000024, 0x00000000, 0x00000000, 0x00000003, 0x00000036, 0x00000001, 0x00000004, 0x00000000, +0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000001, +0x00000000, 0x00000001, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000007, 0x00000000, 0x00000003, 0x00000024, 0x00000000, 0x00000000, 0x00000004, 0x00000036, +0x00000001, 0x00000001, 0x00000004, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, +0x00000004, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, +0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000003, 0x00000024, 0x00000000, +0x00000000, 0x00000005, 0x0000003e, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000000, +0x00000003, 0x00000024, 0x00000000, 0x00000000, 0x00000006, 0x00000003, 0xffffffff, 0xffffffff, +0x00000003, 0x00000000, 0x00000006, 0x00000003, 0xffffffff, 0xffffffff, 0x00000003, 0x00000001, +0x00000006, 0x00000003, 0xffffffff, 0xffffffff, 0x00000003, 0x00000002, 0x00000006, 0x00000003, +0xffffffff, 0xffffffff, 0x00000003, 0x00000003, 0x00000006, 0x00000003, 0xffffffff, 0xffffffff, +0x00000003, 0x00000004, 0x00000006, 0x00000003, 0xffffffff, 0xffffffff, 0x00000003, 0x00000005, +0x00000000, 0x00000002, 0x00000014, 0x00000007, 0x000002c1, 0x00000000, 0x00000002, 0x00000030, +0x00000007, 0x000002c8, 0x00000000, 0x00000004, 0x0000001e, 0x00000002, 0x00000102, 0x00000000, +0x00000004, 0x00000027, 0x00000007, 0x0000010b, 0x00000000, 0x00000006, 0x00000009, 0x00000003, +0x00000131, 0x00000000, 0x00000001, 0x00000014, 0x00000006, 0x000002cf, 0x00000000, 0x00000004, +0x00000005, 0x00000004, 0x000000e9, 0x00000000, 0x00000009, 0x00000004, 0x00000000, 0x00000000, +0x00000003, 0x00000051, 0x00000003, 0x00000001, 0x00000000, 0x00000003, 0x00000076, 0x00000004, +0x00000002, 0x00000004, 0x00000000, 0x000002b4, 0x00000007, 0x00000001, 0x0000000c, 0x00000003, +0x00000076, 0x00000004, 0x00000002, 0x00000004, 0x00000001, 0x000002bb, 0x00000006, 0x00000001, +0x00000010, 0x00000004, 0x000000e9, 0x00000004, 0x00000003, 0x00000014, 0x00000005, 0x00000000, +0x00000001, 0x00000001, 0x00000003, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000003, +0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0xffffffff, 0x00000001, +0x00000014, 0x00000004, 0x00000004, 0xffffffff, 0x00000001, 0x00000000, 0x00000000, 0x00000001, +0x00000001, 0xffffffff, 0x00000001, 0x00000008, 0x00000004, 0x00000002, 0xffffffff, 0x00000006, +0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, +0x00000006, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000001, 0x00000020, 0x0000000c, 0x00000018, 0xffffffff, 0x00000003, 0x00000000, 0x00000000, +0x00000001, 0x00000001, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xffffffff, +0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, +0x00000000, 0x00000006, 0xffffffff, 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000006, +0x00000004, 0x00000005, 0x00000006, 0x00000008, 0x00000004, 0x00000005, 0x00000002, 0x505c3a43, +0x72676f72, 0x656d6d61, 0x63694d5c, 0x6f736f72, 0x44207466, 0x63657269, 0x53205874, 0x28204b44, +0x656e754a, 0x31303220, 0x555c2930, 0x696c6974, 0x73656974, 0x6e69625c, 0x3638785c, 0x6165685c, +0x2e726564, 0x74737866, 0x74637572, 0x4f535620, 0x66207b20, 0x74616f6c, 0x20702033, 0x4f50203a, +0x49544953, 0x203b4e4f, 0x730a3b7d, 0x63757274, 0x53482074, 0x7b204f44, 0x6f6c6620, 0x65207461, +0x205d345b, 0x5653203a, 0x7365545f, 0x63614673, 0x3b726f74, 0x6f6c6620, 0x69207461, 0x205d325b, +0x5653203a, 0x736e495f, 0x54656469, 0x46737365, 0x6f746361, 0x7d203b72, 0x74730a3b, 0x74637572, +0x4f534820, 0x66207b20, 0x74616f6c, 0x20702033, 0x4542203a, 0x5245495a, 0x3b534f50, 0x0a3b7d20, +0x4f445348, 0x48434220, 0x49202853, 0x7475706e, 0x63746150, 0x53563c68, 0x38202c4f, 0x7069203e, +0x6975202c, 0x5020746e, 0x68637461, 0x3a204449, 0x5f565320, 0x6d697250, 0x76697469, 0x20444965, +0x0a7b0a29, 0x20202020, 0x4f445348, 0x73657220, 0x20200a3b, 0x65722020, 0x5b652e73, 0x3d205d30, +0x73657220, 0x315b652e, 0x203d205d, 0x2e736572, 0x5d325b65, 0x72203d20, 0x652e7365, 0x205d335b, +0x2e31203d, 0x0a3b6630, 0x20202020, 0x2e736572, 0x5d305b69, 0x72203d20, 0x692e7365, 0x205d315b, +0x2e31203d, 0x0a3b6630, 0x20202020, 0x75746572, 0x72206e72, 0x0a3b7365, 0x645b0a7d, 0x69616d6f, +0x7122286e, 0x22646175, 0x5b0a5d29, 0x74726170, 0x6f697469, 0x676e696e, 0x6e692228, 0x65676574, +0x5d292272, 0x756f5b0a, 0x74757074, 0x6f706f74, 0x79676f6c, 0x72742228, 0x676e6169, 0x635f656c, +0x5d292277, 0x756f5b0a, 0x74757074, 0x746e6f63, 0x706c6f72, 0x746e696f, 0x29382873, 0x705b0a5d, +0x68637461, 0x736e6f63, 0x746e6174, 0x636e7566, 0x43422228, 0x29225348, 0x53480a5d, 0x4842204f, +0x49202853, 0x7475706e, 0x63746150, 0x53563c68, 0x38202c4f, 0x2c70203e, 0x6e697520, 0x20692074, +0x5653203a, 0x74754f5f, 0x43747570, 0x72746e6f, 0x6f506c6f, 0x49746e69, 0x75202c44, 0x20746e69, +0x63746150, 0x20444968, 0x5653203a, 0x6972505f, 0x6974696d, 0x44496576, 0x7b0a2920, 0x2020200a, +0x4f534820, 0x73657220, 0x20200a3b, 0x65722020, 0x20702e73, 0x5b70203d, 0x702e5d69, 0x20200a3b, +0x65722020, 0x6e727574, 0x73657220, 0x0a7d0a3b, 0x626f6c47, 0x4c736c61, 0x6c61636f, 0x44534873, +0x653a3a4f, 0x4f445348, 0x56693a3a, 0x3a3a4f53, 0x63694d70, 0x6f736f72, 0x28207466, 0x48202952, +0x204c534c, 0x64616853, 0x43207265, 0x69706d6f, 0x2072656c, 0x39322e39, 0x3235392e, 0x3131332e, +0x48420031, 0x73680053, 0x305f355f, 0x6e6f6320, 0x6c6f7274, 0x696f7020, 0x0000746e, +}; + +static void test_get_blob_part2(void) +{ + ID3DBlob *blob, *blob2; + HRESULT hr; + ULONG refcount; + DWORD *dword; + SIZE_T size; + UINT i; + + /* D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB */ + hr = pD3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB, 0, &blob); + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 232, "GetBufferSize failed, got %lu, expected %u\n", size, 232); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(TAG_DXBC == *dword, "DXBC got %#x, expected %#x.\n", *dword, TAG_DXBC); + ok(TAG_PCSG == *(dword+9), "PCSG got %#x, expected %#x.\n", *(dword+9), TAG_PCSG); + + for (i = 0; i < ARRAY_SIZE(parts); i++) + { + hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2); + + if (parts[i] == D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB) + { + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + refcount = ID3D10Blob_Release(blob2); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + } + else + { + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + } + } + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + /* D3D_BLOB_ALL_SIGNATURE_BLOB */ + hr = pD3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_ALL_SIGNATURE_BLOB, 0, &blob); + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 344, "GetBufferSize failed, got %lu, expected %u\n", size, 344); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(TAG_DXBC == *dword, "DXBC got %#x, expected %#x.\n", *dword, TAG_DXBC); + ok(TAG_ISGN == *(dword+11), "ISGN got %#x, expected %#x.\n", *(dword+11), TAG_ISGN); + ok(TAG_OSGN == *(dword+24), "OSGN got %#x, expected %#x.\n", *(dword+24), TAG_OSGN); + ok(TAG_PCSG == *(dword+37), "PCSG got %#x, expected %#x.\n", *(dword+37), TAG_PCSG); + + for (i = 0; i < ARRAY_SIZE(parts); i++) + { + hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2); + + if (parts[i] == D3D_BLOB_ALL_SIGNATURE_BLOB + || parts[i] == D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB + || parts[i] == D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB + || parts[i] == D3D_BLOB_INPUT_SIGNATURE_BLOB + || parts[i] == D3D_BLOB_OUTPUT_SIGNATURE_BLOB) + { + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + refcount = ID3D10Blob_Release(blob2); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + } + else + { + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + } + } + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + /* D3D_BLOB_DEBUG_INFO */ + hr = pD3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_DEBUG_INFO, 0, &blob); + ok(hr == S_OK, "D3DGetBlobPart failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 4055, "GetBufferSize failed, got %lu, expected %u\n", size, 4055); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(TAG_DXBC != *dword, "DXBC failed got %#x.\n", *dword); + + for (i = 0; i < ARRAY_SIZE(parts); i++) + { + /* There isn't a full DXBC blob returned for D3D_BLOB_DEBUG_INFO */ + hr = pD3DGetBlobPart(dword, size, parts[i], 0, &blob2); + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + } + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + /* D3D_BLOB_LEGACY_SHADER */ + hr = pD3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_LEGACY_SHADER, 0, &blob); + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + + /* D3D_BLOB_XNA_PREPASS_SHADER */ + hr = pD3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_XNA_PREPASS_SHADER, 0, &blob); + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + + /* D3D_BLOB_XNA_SHADER */ + hr = pD3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_XNA_SHADER, 0, &blob); + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + + /* D3DCOMPILER_STRIP_DEBUG_INFO */ + hr = pD3DStripShader(test_blob_part2, test_blob_part2[6], D3DCOMPILER_STRIP_DEBUG_INFO, &blob); + ok(hr == S_OK, "D3DStripShader failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 952, "GetBufferSize failed, got %lu, expected %u\n", size, 952); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(TAG_DXBC == *dword, "DXBC got %#x, expected %#x.\n", *dword, TAG_DXBC); + ok(TAG_RDEF == *(dword+14), "RDEF got %#x, expected %#x.\n", *(dword+14), TAG_RDEF); + ok(TAG_ISGN == *(dword+44), "ISGN got %#x, expected %#x.\n", *(dword+44), TAG_ISGN); + ok(TAG_OSGN == *(dword+57), "OSGN got %#x, expected %#x.\n", *(dword+57), TAG_OSGN); + ok(TAG_PCSG == *(dword+70), "PCSG got %#x, expected %#x.\n", *(dword+70), TAG_PCSG); + ok(TAG_SHEX == *(dword+119), "SHEX got %#x, expected %#x.\n", *(dword+119), TAG_SHEX); + ok(TAG_STAT == *(dword+199), "STAT got %#x, expected %#x.\n", *(dword+199), TAG_STAT); + + hr = pD3DGetBlobPart(dword, size, D3D_BLOB_DEBUG_INFO, 0, &blob2); + ok(hr == E_FAIL, "D3DGetBlobPart failed, got %x, expected %x\n", hr, E_FAIL); + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); + + /* D3DCOMPILER_STRIP_REFLECTION_DATA */ + hr = pD3DStripShader(test_blob_part2, test_blob_part2[6], D3DCOMPILER_STRIP_REFLECTION_DATA, &blob); + ok(hr == S_OK, "D3DStripShader failed, got %x, expected %x\n", hr, S_OK); + + size = ID3D10Blob_GetBufferSize(blob); + ok(size == 4735, "GetBufferSize failed, got %lu, expected %u\n", size, 4735); + + dword = ((DWORD*)ID3D10Blob_GetBufferPointer(blob)); + ok(TAG_DXBC == *dword, "DXBC got %#x, expected %#x.\n", *dword, TAG_DXBC); + ok(TAG_ISGN == *(dword+13), "ISGN got %#x, expected %#x.\n", *(dword+13), TAG_ISGN); + ok(TAG_OSGN == *(dword+26), "OSGN got %#x, expected %#x.\n", *(dword+26), TAG_OSGN); + ok(TAG_PCSG == *(dword+39), "PCSG got %#x, expected %#x.\n", *(dword+39), TAG_PCSG); + ok(TAG_SHEX == *(dword+88), "SHEX got %#x, expected %#x.\n", *(dword+88), TAG_SHEX); + ok(TAG_SDBG == *(dword+168), "SDBG got %#x, expected %#x.\n", *(dword+168), TAG_SDBG); + + refcount = ID3D10Blob_Release(blob); + ok(!refcount, "ID3DBlob has %u references left\n", refcount); +} + +static BOOL load_d3dcompiler_43(void) +{ + HMODULE module; + + if (!(module = LoadLibraryA("d3dcompiler_43.dll"))) return FALSE; + + pD3DCreateBlob = (void*)GetProcAddress(module, "D3DCreateBlob"); + pD3DGetBlobPart = (void*)GetProcAddress(module, "D3DGetBlobPart"); + pD3DStripShader = (void*)GetProcAddress(module, "D3DStripShader"); + return TRUE; +} + +static BOOL load_d3dcompiler_47(void) +{ + HMODULE module; + + if (!(module = LoadLibraryA("d3dcompiler_47.dll"))) + return FALSE; + + pD3DReadFileToBlob = (void *)GetProcAddress(module, "D3DReadFileToBlob"); + return TRUE; +} + +static BOOL create_file(WCHAR *filename, const DWORD *data, DWORD data_size) +{ + static WCHAR temp_dir[MAX_PATH]; + DWORD written; + HANDLE file; + + if (!temp_dir[0]) + GetTempPathW(ARRAY_SIZE(temp_dir), temp_dir); + GetTempFileNameW(temp_dir, NULL, 0, filename); + file = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + if (file == INVALID_HANDLE_VALUE) + return FALSE; + + if (data) + { + WriteFile(file, data, data_size, &written, NULL); + if (written != data_size) + { + CloseHandle(file); + DeleteFileW(filename); + return FALSE; + } + } + CloseHandle(file); + return TRUE; +} + +/* test_cso_data - fxc.exe file.hlsl /Fo file.cso */ +static const DWORD test_cso_data[] = +{ +#if 0 + struct PSInput + { + float4 value : SV_POSITION; + }; + + PSInput main(float4 position : POSITION) + { + PSInput result; + result.value = position; + return result; + } +#endif + 0xfffe0200, 0x0014fffe, 0x42415443, 0x0000001c, 0x00000023, 0xfffe0200, 0x00000000, 0x00000000, + 0x00000100, 0x0000001c, 0x325f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, + 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x30312072, 0xab00312e, 0x0200001f, 0x80000000, + 0x900f0000, 0x02000001, 0xc00f0000, 0x90e40000, 0x0000ffff +}; + +static void test_D3DReadFileToBlob(void) +{ + WCHAR filename[MAX_PATH] = {'n','o','n','e','x','i','s','t','e','n','t',0}; + ID3DBlob *blob = NULL; + SIZE_T data_size; + DWORD *data; + HRESULT hr; + + hr = pD3DReadFileToBlob(filename, NULL); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got unexpected hr %#x.\n", hr); + + hr = pD3DReadFileToBlob(filename, &blob); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got unexpected hr %#x.\n", hr); + + if (0) + { + /* Crashes on Windows. */ + create_file(filename, test_cso_data, ARRAY_SIZE(test_cso_data)); + pD3DReadFileToBlob(filename, NULL); + DeleteFileW(filename); + } + + if (!create_file(filename, NULL, 0)) + { + win_skip("File creation failed.\n"); + return; + } + hr = pD3DReadFileToBlob(filename, &blob); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + data_size = ID3D10Blob_GetBufferSize(blob); + ok(!data_size, "Got unexpected data size.\n"); + DeleteFileW(filename); + ID3D10Blob_Release(blob); + + if (!create_file(filename, test_cso_data, ARRAY_SIZE(test_cso_data))) + { + win_skip("File creation failed.\n"); + return; + } + hr = pD3DReadFileToBlob(filename, &blob); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + data_size = ID3D10Blob_GetBufferSize(blob); + ok(data_size == ARRAY_SIZE(test_cso_data), "Got unexpected data size.\n"); + data = ID3D10Blob_GetBufferPointer(blob); + ok(!memcmp(data, test_cso_data, ARRAY_SIZE(test_cso_data)), "Got unexpected data.\n"); + DeleteFileW(filename); + ID3D10Blob_Release(blob); +} + +START_TEST(blob) +{ + if (load_d3dcompiler_43()) + { + test_create_blob(); + test_get_blob_part(); + test_get_blob_part2(); + } + else + { + win_skip("Could not load d3dcompiler_43.dll\n"); + } + + if (load_d3dcompiler_47()) + { + test_D3DReadFileToBlob(); + } + else + { + win_skip("Could not load d3dcompiler_47.dll.\n"); + } +} diff --git a/modules/rostests/winetests/d3dcompiler_43/hlsl.c b/modules/rostests/winetests/d3dcompiler_43/hlsl.c new file mode 100644 index 00000000000..f169f681cae --- /dev/null +++ b/modules/rostests/winetests/d3dcompiler_43/hlsl.c @@ -0,0 +1,685 @@ +/* + * Copyright (C) 2010 Travis Athougies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS +#include "wine/test.h" +#include "d3dx9.h" +#include "d3dcompiler.h" + +#include <math.h> + +static pD3DCompile ppD3DCompile; + +struct vertex +{ + float x, y, z; + float tx, ty; +}; + +/* Tells compute_shader_probe* which pixels should be what colors */ +struct hlsl_probe_info +{ + unsigned int x, y; + /* The expected values in this region */ + D3DXCOLOR c; + /* The max error for any value */ + float epsilon; + /* An error message to print if this test fails */ + const char *message; +}; + +static HWND create_window(void) +{ + WNDCLASSA wc = {0}; + wc.lpfnWndProc = DefWindowProcA; + wc.lpszClassName = "d3d9_test_wc"; + RegisterClassA(&wc); + + return CreateWindowA("d3d9_test_wc", "d3d9_test", 0, 0, 0, 0, 0, 0, 0, 0, 0); +} + +static IDirect3DDevice9 *init_d3d9(IDirect3DVertexDeclaration9 **vdeclaration, + IDirect3DVertexBuffer9 **quad_geometry, IDirect3DVertexShader9 **vshader_passthru) +{ + static const struct vertex quad_vertices[4] = + { + {-1.0f, -1.0f, 0.0f, 0.0f, 1.0f}, + {-1.0f, 1.0f, 0.0f, 0.0f, 0.0f}, + { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f}, + { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f} + }; + + static const D3DVERTEXELEMENT9 vdeclelements[] = + { + {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, + {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, + D3DDECL_END() + }; + + static const char *vshader_passthru_hlsl = + "float4 vshader(float4 pos: POSITION, inout float2 texcoord: TEXCOORD0): POSITION\n" + "{\n" + " return pos;\n" + "}"; + + IDirect3D9 *d3d9_ptr; + IDirect3DDevice9 *device_ptr = NULL; + D3DPRESENT_PARAMETERS present_parameters; + + void *temp_geometry_vertices; + + ID3D10Blob *compiled = NULL; + ID3D10Blob *errors = NULL; + + HRESULT hr; + + d3d9_ptr = Direct3DCreate9(D3D_SDK_VERSION); + if (!d3d9_ptr) + { + skip("could not create D3D9\n"); + return NULL; + } + + hr = IDirect3D9_CheckDeviceFormat(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, + 0, D3DRTYPE_SURFACE, D3DFMT_A32B32G32R32F); + if (FAILED(hr)) + { + skip("A32B32G32R32F format not available on this device\n"); + IDirect3D9_Release(d3d9_ptr); + return NULL; + } + + ZeroMemory(&present_parameters, sizeof(present_parameters)); + present_parameters.Windowed = TRUE; + present_parameters.hDeviceWindow = create_window(); + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + + hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, + D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr); + IDirect3D9_Release(d3d9_ptr); + if (FAILED(hr)) + { + skip("could not create Direct3D9 device\n"); + return NULL; + } + + /* Create the quad geometry */ + hr = IDirect3DDevice9_CreateVertexBuffer(device_ptr, 4 * sizeof(struct vertex), + D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, quad_geometry, NULL); + ok(SUCCEEDED(hr), + "Could not create vertex buffer, IDirect3DDevice9_CreateVertexBuffer returned: %08x\n", hr); + + hr = IDirect3DVertexBuffer9_Lock(*quad_geometry, 0, sizeof(quad_vertices), &temp_geometry_vertices, 0); + ok(SUCCEEDED(hr), "IDirect3DVertexBuffer9_Lock returned: %08x\n", hr); + memcpy(temp_geometry_vertices, quad_vertices, sizeof(quad_vertices)); + IDirect3DVertexBuffer9_Unlock(*quad_geometry); + + hr = IDirect3DDevice9_CreateVertexDeclaration(device_ptr, vdeclelements, vdeclaration); + ok(SUCCEEDED(hr), "Could not create vertex declaration: " + "IDirect3DDevice9_CreateVertexDeclaration returned: %08x\n", hr); + + hr = IDirect3DDevice9_SetVertexDeclaration(device_ptr, *vdeclaration); + ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned: %08x\n", hr); + + /* Create a simple vertex shader to just pass through the values */ + hr = ppD3DCompile(vshader_passthru_hlsl, strlen(vshader_passthru_hlsl), NULL, + NULL, NULL, "vshader", "vs_1_1", 0, 0, &compiled, &errors); + if (FAILED(hr)) + { + skip("not compiling vertex shader due to lacking wine HLSL support!\n"); + if (errors) + ID3D10Blob_Release(errors); + return NULL; + } + + hr = IDirect3DDevice9_CreateVertexShader(device_ptr, ID3D10Blob_GetBufferPointer(compiled), + vshader_passthru); + ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader returned: %08x\n", hr); + ID3D10Blob_Release(compiled); + + return device_ptr; +} + +/* Convenience functions */ +static void set_float4_d3d9(IDirect3DDevice9 *device, ID3DXConstantTable *constants, const char *name, + float x, float y, float z, float w) +{ + D3DXVECTOR4 vector; + vector.x = x; + vector.y = y; + vector.z = z; + vector.w = w; + ID3DXConstantTable_SetVector(constants, device, name, &vector); +} + +/* Compile our pixel shader and get back the compiled version and a constant table */ +static IDirect3DPixelShader9 *compile_pixel_shader9(IDirect3DDevice9 *device, const char *shader, + const char *profile, ID3DXConstantTable **constants) +{ + ID3D10Blob *compiled = NULL; + ID3D10Blob *errors = NULL; + IDirect3DPixelShader9 *pshader; + HRESULT hr; + + hr = ppD3DCompile(shader, strlen(shader), NULL, NULL, + NULL, "test", profile, /* test is the name of the entry point of our shader */ + 0, 0, &compiled, &errors); + ok(hr == D3D_OK, "Pixel shader %s compilation failed: %s\n", shader, + errors ? (char *)ID3D10Blob_GetBufferPointer(errors) : ""); + if (FAILED(hr)) return NULL; + + hr = D3DXGetShaderConstantTable(ID3D10Blob_GetBufferPointer(compiled), constants); + ok(hr == D3D_OK, "Could not get constant table from compiled pixel shader\n"); + + hr = IDirect3DDevice9_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(compiled), &pshader); + ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader returned: %08x\n", hr); + ID3D10Blob_Release(compiled); + return pshader; +} + +/* Draw a full screen quad */ +static void draw_quad_with_shader9(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry) +{ + HRESULT hr; + D3DXMATRIX projection_matrix; + + D3DXMatrixOrthoLH(&projection_matrix, 2.0f, 2.0f, 0.0f, 1.0f); + IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &projection_matrix); + + hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned: %08x\n", hr); + + hr = IDirect3DDevice9_BeginScene(device); + ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned: %08x\n", hr); + + hr = IDirect3DDevice9_SetStreamSource(device, 0, quad_geometry, 0, sizeof(struct vertex)); + ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource returned: %08x\n", hr); + hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2); + ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive returned: %08x\n", hr); + + hr = IDirect3DDevice9_EndScene(device); + ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned: %08x\n", hr); +} + +static void setup_device9(IDirect3DDevice9 *device, IDirect3DSurface9 **render_target, + IDirect3DSurface9 **readback, D3DFORMAT format, unsigned int width, unsigned int height, + IDirect3DVertexShader9 *vshader, IDirect3DPixelShader9 *pshader) +{ + HRESULT hr; + hr = IDirect3DDevice9_CreateRenderTarget(device, width, height, format, + D3DMULTISAMPLE_NONE, 0, FALSE, render_target, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget returned: %08x\n", hr); + + /* The Direct3D 9 docs state that we cannot lock a render target surface, + instead we must copy the render target onto this surface to lock it */ + hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, + D3DPOOL_SYSTEMMEM, readback, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned: %08x\n", hr); + + hr = IDirect3DDevice9_SetRenderTarget(device, 0, *render_target); + ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget returned: %08x\n", hr); + + hr = IDirect3DDevice9_SetVertexShader(device, vshader); + ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned: %08x\n", hr); + hr = IDirect3DDevice9_SetPixelShader(device, pshader); + ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned: %08x\n", hr); +} + +static BOOL colors_match(D3DXCOLOR a, D3DXCOLOR b, float epsilon) +{ + return (fabs(a.r - b.r) < epsilon && fabs(a.g - b.g) < epsilon && fabs(a.b - b.b) < epsilon && + fabs(a.a - b.a) < epsilon); +} + +/* Compute a shader on a width by height buffer and probes certain locations + to see if they are as expected. */ +static void compute_shader_probe9(IDirect3DDevice9 *device, IDirect3DVertexShader9 *vshader, + IDirect3DPixelShader9 *pshader, IDirect3DVertexBuffer9 *quad_geometry, + const struct hlsl_probe_info *probes, unsigned int count, + unsigned int width, unsigned int height, unsigned int line_number) +{ + IDirect3DSurface9 *render_target; + IDirect3DSurface9 *readback; + + HRESULT hr; + D3DLOCKED_RECT lr; + D3DXCOLOR *pbits_data; + unsigned int i; + + setup_device9(device, &render_target, &readback, D3DFMT_A32B32G32R32F, + width, height, vshader, pshader); + + /* Draw the quad with the shader and read back the data */ + draw_quad_with_shader9(device, quad_geometry); + IDirect3DDevice9_GetRenderTargetData(device, render_target, readback); + hr = IDirect3DSurface9_LockRect(readback, &lr, NULL, D3DLOCK_READONLY); + ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned: %08x\n", hr); + pbits_data = lr.pBits; + + /* Now go through the probes and check each one */ + for (i = 0; i < count; i++, probes++) { + int index = probes->x + (probes->y * lr.Pitch / sizeof(D3DXCOLOR)); + ok(colors_match(probes->c, pbits_data[index], probes->epsilon), + "Line %d: At (%d, %d): %s: Expected (%.04f,%.04f,%.04f, %.04f), got " + "(%.04f,%.04f,%.04f,%.04f)\n", line_number, probes->x, probes->y, probes->message, + probes->c.r, probes->c.g, probes->c.b, probes->c.a, pbits_data[index].r, + pbits_data[index].g, pbits_data[index].b, pbits_data[index].a); + } + + hr = IDirect3DSurface9_UnlockRect(readback); + ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned: %08x\n", hr); + + /* We now present the scene. This is mostly for debugging purposes, since GetRenderTargetData + also waits for drawing commands to complete. The reason this call is here and not in a + draw function is because the contents of the render target surface are invalidated after + this call. */ + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_Present returned: %08x\n", hr); + + IDirect3DSurface9_Release(render_target); + IDirect3DSurface9_Release(readback); +} + +/* Now the actual test functions */ +static void test_swizzle(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, + IDirect3DVertexShader9 *vshader_passthru) +{ + static const struct hlsl_probe_info probes[] = + { + {0, 0, {0.0101f, 0.0303f, 0.0202f, 0.0404f}, 0.0001f, "swizzle_test"} + }; + + static const char *swizzle_test_shader = + "uniform float4 color;\n" + "float4 test(): COLOR\n" + "{\n" + " float4 ret = color;\n" + " ret.gb = ret.ra;\n" + " ret.ra = float2(0.0101, 0.0404);\n" + " return ret;\n" + "}"; + + ID3DXConstantTable *constants; + IDirect3DPixelShader9 *pshader; + + pshader = compile_pixel_shader9(device, swizzle_test_shader, "ps_2_0", &constants); + if (pshader != NULL) + { + set_float4_d3d9(device, constants, "color", 0.0303f, 0.0f, 0.0f, 0.0202f); + + compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, + probes, ARRAY_SIZE(probes), 1, 1, __LINE__); + + ID3DXConstantTable_Release(constants); + IDirect3DPixelShader9_Release(pshader); + } +} + +static void test_math(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, + IDirect3DVertexShader9 *vshader_passthru) +{ + /* Tests order of operations */ + static const float u = 2.5f, v = 0.3f, w = 0.2f, x = 0.7f, y = 0.1f, z = 1.5f; + + static const struct hlsl_probe_info probes[] = + { + {0, 0, {-12.4300f, 9.8333f, 1.6000f, 34.9999f}, 0.0001f, + "order of operations test"} + }; + + static const char *order_of_operations_shader = + "float4 test(uniform float u, uniform float v, uniform float w, uniform float x,\n" + " uniform float y, uniform float z): COLOR\n" + "{\n" + " return float4(x * y - z / w + --u / -v,\n" + " z * x / y + w / -v,\n" + " u + v - w,\n" + " x / y / w);\n" + "}"; + + ID3DXConstantTable *constants; + IDirect3DPixelShader9 *pshader; + + pshader = compile_pixel_shader9(device, order_of_operations_shader, "ps_2_0", &constants); + if (pshader != NULL) + { + ID3DXConstantTable_SetFloat(constants, device, "$u", u); + ID3DXConstantTable_SetFloat(constants, device, "$v", v); + ID3DXConstantTable_SetFloat(constants, device, "$w", w); + ID3DXConstantTable_SetFloat(constants, device, "$x", x); + ID3DXConstantTable_SetFloat(constants, device, "$y", y); + ID3DXConstantTable_SetFloat(constants, device, "$z", z); + + compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, + probes, ARRAY_SIZE(probes), 1, 1, __LINE__); + + ID3DXConstantTable_Release(constants); + IDirect3DPixelShader9_Release(pshader); + } +} + +static void test_conditionals(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, + IDirect3DVertexShader9 *vshader_passthru) +{ + static const struct hlsl_probe_info if_greater_probes[] = + { + { 0, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test"}, + { 5, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test"}, + {10, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test"}, + {15, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test"}, + {25, 0, {0.1f, 0.2f, 0.3f, 0.4f}, 0.0001f, "if greater test"}, + {30, 0, {0.1f, 0.2f, 0.3f, 0.4f}, 0.0001f, "if greater test"} + }; + + static const char *if_greater_shader = + "float4 test(float2 pos: TEXCOORD0): COLOR\n" + "{\n" + " if((pos.x * 32.0) > 20.0)\n" + " return float4(0.1, 0.2, 0.3, 0.4);\n" + " else\n" + " return float4(0.9, 0.8, 0.7, 0.6);\n" + "}"; + + static const struct hlsl_probe_info ternary_operator_probes[] = + { + {0, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test"}, + {1, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test"}, + {2, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test"}, + {3, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test"}, + {4, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test"}, + {5, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test"}, + {6, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test"}, + {7, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test"} + }; + + static const char *ternary_operator_shader = + "float4 test(float2 pos: TEXCOORD0): COLOR\n" + "{\n" + " return (pos.x < 0.5?float4(0.5, 0.25, 0.5, 0.75):float4(0.6, 0.8, 0.1, 0.2));\n" + "}"; + + ID3DXConstantTable *constants; + IDirect3DPixelShader9 *pshader; + + pshader = compile_pixel_shader9(device, if_greater_shader, "ps_2_0", &constants); + if (pshader != NULL) + { + compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, if_greater_probes, + ARRAY_SIZE(if_greater_probes), 32, 1, __LINE__); + + ID3DXConstantTable_Release(constants); + IDirect3DPixelShader9_Release(pshader); + } + + pshader = compile_pixel_shader9(device, ternary_operator_shader, "ps_2_0", &constants); + if (pshader != NULL) + { + compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, ternary_operator_probes, + ARRAY_SIZE(ternary_operator_probes), 8, 1, __LINE__); + + ID3DXConstantTable_Release(constants); + IDirect3DPixelShader9_Release(pshader); + } +} + +static void test_float_vectors(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, + IDirect3DVertexShader9 *vshader_passthru) +{ + static const struct hlsl_probe_info vec4_indexing_test1_probes[] = + { + {0, 0, {0.020f, 0.245f, 0.351f, 1.000f}, 0.0001f, "vec4 indexing test 1"} + }; + + static const char *vec4_indexing_test1_shader = + "float4 test(): COLOR\n" + "{\n" + " float4 color;\n" + " color[0] = 0.020;\n" + " color[1] = 0.245;\n" + " color[2] = 0.351;\n" + " color[3] = 1.0;\n" + " return color;\n" + "}"; + + static const struct hlsl_probe_info vec4_indexing_test2_probes[] = + { + {0, 0, {0.5f, 0.3f, 0.8f, 0.2f}, 0.0001f, "vec4 indexing test 2"} + }; + + /* We have this uniform i here so the compiler can't optimize */ + static const char *vec4_indexing_test2_shader = + "uniform int i;\n" + "float4 test(): COLOR\n" + "{\n" + " float4 color = float4(0.5, 0.4, 0.3, 0.2);\n" + " color.g = color[i];\n" + " color.b = 0.8;\n" + " return color;\n" + "}"; + + ID3DXConstantTable *constants; + IDirect3DPixelShader9 *pshader; + + pshader = compile_pixel_shader9(device, vec4_indexing_test1_shader, "ps_2_0", &constants); + if (pshader != NULL) + { + compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, vec4_indexing_test1_probes, + ARRAY_SIZE(vec4_indexing_test1_probes), 1, 1, __LINE__); + + ID3DXConstantTable_Release(constants); + IDirect3DPixelShader9_Release(pshader); + } + + pshader = compile_pixel_shader9(device, vec4_indexing_test2_shader, "ps_2_0", &constants); + if (pshader != NULL) + { + ID3DXConstantTable_SetInt(constants, device, "i", 2); + + compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, vec4_indexing_test2_probes, + ARRAY_SIZE(vec4_indexing_test2_probes), 32, 1, __LINE__); + + ID3DXConstantTable_Release(constants); + IDirect3DPixelShader9_Release(pshader); + } +} + +static void test_trig(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, + IDirect3DVertexShader9 *vshader_passthru) +{ + static const struct hlsl_probe_info sincos_probes[] = + { + {0, 0, {0.5000f, 1.0000f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {1, 0, {0.5975f, 0.9904f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {2, 0, {0.6913f, 0.9620f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {3, 0, {0.7778f, 0.9160f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {4, 0, {0.8536f, 0.8536f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {5, 0, {0.9157f, 0.7778f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {6, 0, {0.9620f, 0.6913f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {7, 0, {0.9904f, 0.5975f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {8, 0, {1.0000f, 0.5000f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {9, 0, {0.9904f, 0.4025f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {10, 0, {0.9619f, 0.3087f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {11, 0, {0.9157f, 0.2222f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {12, 0, {0.8536f, 0.1464f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {13, 0, {0.7778f, 0.0843f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {14, 0, {0.6913f, 0.0381f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {15, 0, {0.5975f, 0.0096f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {16, 0, {0.5000f, 0.0000f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {17, 0, {0.4025f, 0.0096f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {18, 0, {0.3087f, 0.0381f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {19, 0, {0.2222f, 0.0843f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {20, 0, {0.1464f, 0.1464f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {21, 0, {0.0843f, 0.2222f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {22, 0, {0.0381f, 0.3087f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {23, 0, {0.0096f, 0.4025f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {24, 0, {0.0000f, 0.5000f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {25, 0, {0.0096f, 0.5975f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {26, 0, {0.0381f, 0.6913f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {27, 0, {0.0843f, 0.7778f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {28, 0, {0.1464f, 0.8536f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {29, 0, {0.2222f, 0.9157f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {30, 0, {0.3087f, 0.9619f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + {31, 0, {0.4025f, 0.9904f, 0.0f, 0.0f}, 0.001f, "sin/cos test"}, + }; + + static const char *sincos_shader = + "float4 test(float x: TEXCOORD0): COLOR\n" + "{\n" + " const float pi2 = 6.2831853;\n" + " float calcd_sin = (sin(x * pi2) + 1)/2;\n" + " float calcd_cos = (cos(x * pi2) + 1)/2;\n" + " return float4(calcd_sin, calcd_cos, 0, 0);\n" + "}"; + + ID3DXConstantTable *constants; + IDirect3DPixelShader9 *pshader; + + pshader = compile_pixel_shader9(device, sincos_shader, "ps_2_0", &constants); + if (pshader != NULL) + { + compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, sincos_probes, + ARRAY_SIZE(sincos_probes), 32, 1, __LINE__); + + ID3DXConstantTable_Release(constants); + IDirect3DPixelShader9_Release(pshader); + } +} + +static void test_fail(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *qquad_geometry, + IDirect3DVertexShader9 *vshader_passthru) +{ + static const char *tests[] = + { + "float4 test(float2 pos: TEXCOORD0) : COLOR\n" + "{\n" + " return y;\n" + "}", + + "float4 test(float2 pos: TEXCOORD0) : COLOR\n" + "{\n" + " float4 x = float4(0, 0, 0, 0);\n" + " x.xzzx = float4(1, 2, 3, 4);\n" + " return x;\n" + "}", + + "float4 test(float2 pos: TEXCOORD0) : COLOR\n" + "{\n" + " float4 x = pos;\n" + " return x;\n" + "}", + + "float4 test(float2 pos, TEXCOORD0) ; COLOR\n" + "{\n" + " pos = float4 x;\n" + " mul(float4(5, 4, 3, 2), mvp) = x;\n" + " return float4;\n" + "}", + + "float4 563r(float2 45s: TEXCOORD0) : COLOR\n" + "{\n" + " float2 x = 45s;\n" + " return float4(x.x, x.y, 0, 0);\n" + "}", + + "float4 test(float2 pos: TEXCOORD0) : COLOR\n" + "{\n" + " struct { int b,c; } x = {0};\n" + " return y;\n" + "}", + + "float4 test(float2 pos: TEXCOORD0) : COLOR\n" + "{\n" + " struct {} x = {};\n" + " return y;\n" + "}", + }; + + ID3D10Blob *compiled, *errors; + unsigned int i; + HRESULT hr; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + compiled = errors = NULL; + hr = ppD3DCompile(tests[i], strlen(tests[i]), NULL, NULL, NULL, "test", "ps_2_0", 0, 0, &compiled, &errors); + ok(hr == E_FAIL, "Test %u, got unexpected hr %#x.\n", i, hr); + ok(!!errors, "Test %u, expected non-NULL error blob.\n", i); + ok(!compiled, "Test %u, expected no compiled shader blob.\n", i); + ID3D10Blob_Release(errors); + } +} + +static BOOL load_d3dcompiler(void) +{ + HMODULE module; + + if (!(module = LoadLibraryA("d3dcompiler_43.dll"))) return FALSE; + + ppD3DCompile = (void*)GetProcAddress(module, "D3DCompile"); + return TRUE; +} + +START_TEST(hlsl) +{ + D3DCAPS9 caps; + ULONG refcount; + IDirect3DDevice9 *device; + IDirect3DVertexDeclaration9 *vdeclaration; + IDirect3DVertexBuffer9 *quad_geometry; + IDirect3DVertexShader9 *vshader_passthru; + + if (!load_d3dcompiler()) + { + win_skip("Could not load d3dcompiler_43.dll\n"); + return; + } + + device = init_d3d9(&vdeclaration, &quad_geometry, &vshader_passthru); + if (!device) return; + + /* Make sure we support pixel shaders, before trying to compile them! */ + /* Direct3D 9 (Shader model 1-3 tests) */ + IDirect3DDevice9_GetDeviceCaps(device, &caps); + if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) + { + todo_wine + { + test_swizzle(device, quad_geometry, vshader_passthru); + test_math(device, quad_geometry, vshader_passthru); + test_conditionals(device, quad_geometry, vshader_passthru); + test_float_vectors(device, quad_geometry, vshader_passthru); + test_trig(device, quad_geometry, vshader_passthru); + test_fail(device, quad_geometry, vshader_passthru); + } + } else skip("no pixel shader support\n"); + + /* Reference counting sanity checks */ + if (vshader_passthru) + { + refcount = IDirect3DVertexShader9_Release(vshader_passthru); + ok(!refcount, "Pass-through vertex shader has %u references left\n", refcount); + } + + refcount = IDirect3DVertexBuffer9_Release(quad_geometry); + ok(!refcount, "Vertex buffer has %u references left\n", refcount); + + refcount = IDirect3DVertexDeclaration9_Release(vdeclaration); + ok(!refcount, "Vertex declaration has %u references left\n", refcount); + + refcount = IDirect3DDevice9_Release(device); + ok(!refcount, "Device has %u references left\n", refcount); +} diff --git a/modules/rostests/winetests/d3dcompiler_43/reflection.c b/modules/rostests/winetests/d3dcompiler_43/reflection.c new file mode 100644 index 00000000000..23c3d9c8c9d --- /dev/null +++ b/modules/rostests/winetests/d3dcompiler_43/reflection.c @@ -0,0 +1,1545 @@ +/* + * Copyright 2010 Rico Schüller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * Nearly all compiler functions need the shader blob and the size. The size + * is always located at DWORD #6 in the shader blob (blob[6]). + * The functions are e.g.: D3DGet*SignatureBlob, D3DReflect + */ + +#define COBJMACROS +#include "initguid.h" +#include "d3dcompiler.h" +#include "wine/test.h" + +/* includes for older reflection interfaces */ +#ifndef __REACTOS__ +#include "d3d10.h" +#include "d3d10_1shader.h" +#endif + +/* + * This doesn't belong here, but for some functions it is possible to return that value, + * see
http://msdn.microsoft.com/en-us/library/bb205278%28v=VS.85%29.aspx
+ * The original definition is in D3DX10core.h. + */ +#define D3DERR_INVALIDCALL 0x8876086c + +static HRESULT (WINAPI *pD3DReflect)(const void *, SIZE_T, REFIID, void **); + +/* Creator string for comparison - Version 9.29.952.3111 (43) */ +static DWORD shader_creator[] = { +0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, +0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, +}; + +/* + * fxc.exe /E VS /Tvs_4_0 /Fx + */ +#if 0 +float4 VS(float4 position : POSITION, float4 pos : SV_POSITION) : SV_POSITION +{ + return position; +} +#endif + +#ifndef __REACTOS__ + +static DWORD test_reflection_blob[] = { +0x43425844, 0x77c6324f, 0xfd27948a, 0xe6958d31, 0x53361cba, 0x00000001, 0x000001d8, 0x00000005, +0x00000034, 0x0000008c, 0x000000e4, 0x00000118, 0x0000015c, 0x46454452, 0x00000050, 0x00000000, +0x00000000, 0x00000000, 0x0000001c, 0xfffe0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f, +0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e, +0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, 0x00000038, +0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000, 0x00000000, +0x00000003, 0x00000001, 0x0000000f, 0x49534f50, 0x4e4f4954, 0x5f565300, 0x49534f50, 0x4e4f4954, +0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, +0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, +0x00010040, 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, +0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, +0x00000074, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, +0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static void test_reflection_references(void) +{ + HRESULT hr; + ULONG count; + ID3D11ShaderReflection *ref11, *ref11_test; + ID3D10ShaderReflection *ref10; + ID3D10ShaderReflection1 *ref10_1; + + hr = pD3DReflect(test_reflection_blob, test_reflection_blob[6], &IID_ID3D11ShaderReflection, (void **)&ref11); + ok(hr == S_OK, "D3DReflect failed, got %x, expected %x\n", hr, S_OK); + + hr = ref11->lpVtbl->QueryInterface(ref11, &IID_ID3D11ShaderReflection, (void **)&ref11_test); + ok(hr == S_OK, "QueryInterface failed, got %x, expected %x\n", hr, S_OK); + + count = ref11_test->lpVtbl->Release(ref11_test); + ok(count == 1, "Release failed %u\n", count); + + hr = ref11->lpVtbl->QueryInterface(ref11, &IID_ID3D10ShaderReflection, (void **)&ref10); + ok(hr == E_NOINTERFACE, "QueryInterface failed, got %x, expected %x\n", hr, E_NOINTERFACE); + + hr = ref11->lpVtbl->QueryInterface(ref11, &IID_ID3D10ShaderReflection1, (void **)&ref10_1); + ok(hr == E_NOINTERFACE, "QueryInterface failed, got %x, expected %x\n", hr, E_NOINTERFACE); + + count = ref11->lpVtbl->Release(ref11); + ok(count == 0, "Release failed %u\n", count); + + /* check invalid cases */ + hr = pD3DReflect(test_reflection_blob, test_reflection_blob[6], &IID_ID3D10ShaderReflection, (void **)&ref10); + ok(hr == E_NOINTERFACE, "D3DReflect failed, got %x, expected %x\n", hr, E_NOINTERFACE); + + hr = pD3DReflect(test_reflection_blob, test_reflection_blob[6], &IID_ID3D10ShaderReflection1, (void **)&ref10_1); + ok(hr == E_NOINTERFACE, "D3DReflect failed, got %x, expected %x\n", hr, E_NOINTERFACE); + + hr = pD3DReflect(NULL, test_reflection_blob[6], &IID_ID3D10ShaderReflection1, (void **)&ref10_1); + ok(hr == D3DERR_INVALIDCALL, "D3DReflect failed, got %x, expected %x\n", hr, D3DERR_INVALIDCALL); + + hr = pD3DReflect(NULL, test_reflection_blob[6], &IID_ID3D11ShaderReflection, (void **)&ref11); + ok(hr == D3DERR_INVALIDCALL, "D3DReflect failed, got %x, expected %x\n", hr, D3DERR_INVALIDCALL); + + /* returns different errors with different sizes */ + hr = pD3DReflect(test_reflection_blob, 31, &IID_ID3D10ShaderReflection1, (void **)&ref10_1); + ok(hr == D3DERR_INVALIDCALL, "D3DReflect failed, got %x, expected %x\n", hr, D3DERR_INVALIDCALL); + + hr = pD3DReflect(test_reflection_blob, 32, &IID_ID3D10ShaderReflection1, (void **)&ref10_1); + ok(hr == E_FAIL, "D3DReflect failed, got %x, expected %x\n", hr, E_FAIL); + + hr = pD3DReflect(test_reflection_blob, test_reflection_blob[6]-1, &IID_ID3D10ShaderReflection1, (void **)&ref10_1); + ok(hr == E_FAIL, "D3DReflect failed, got %x, expected %x\n", hr, E_FAIL); + + hr = pD3DReflect(test_reflection_blob, 31, &IID_ID3D11ShaderReflection, (void **)&ref11); + ok(hr == D3DERR_INVALIDCALL, "D3DReflect failed, got %x, expected %x\n", hr, D3DERR_INVALIDCALL); + + hr = pD3DReflect(test_reflection_blob, 32, &IID_ID3D11ShaderReflection, (void **)&ref11); + ok(hr == E_FAIL, "D3DReflect failed, got %x, expected %x\n", hr, E_FAIL); + + hr = pD3DReflect(test_reflection_blob, test_reflection_blob[6]-1, &IID_ID3D11ShaderReflection, (void **)&ref11); + ok(hr == E_FAIL, "D3DReflect failed, got %x, expected %x\n", hr, E_FAIL); +} + +#endif /* !__REACTOS__ */ + +/* + * fxc.exe /E VS /Tvs_4_1 /Fx + */ +#if 0 +struct vsin +{ + float4 x : SV_position; + float4 a : BINORMAL; + uint b : BLENDINDICES; + float c : BLENDWEIGHT; + float4 d : COLOR; + float4 d1 : COLOR1; + float4 e : NORMAL; + float4 f : POSITION; + float4 g : POSITIONT; + float h : PSIZE; + float4 i : TANGENT; + float4 j : TEXCOORD; + uint k : SV_VertexID; + uint l : SV_InstanceID; + float m : testin; +}; +struct vsout +{ + float4 x : SV_position; + float4 a : COLOR0; + float b : FOG; + float4 c : POSITION0; + float d : PSIZE; + float e : TESSFACTOR0; + float4 f : TEXCOORD0; + float g : SV_ClipDistance0; + float h : SV_CullDistance0; + uint i : SV_InstanceID; + float j : testout; +}; +vsout VS(vsin x) +{ + vsout s; + s.x = float4(1.6f, 0.3f, 0.1f, 0.0f); + int y = 1; + int p[5] = {1, 2, 3, 5, 4}; + y = y << (int) x.x.x & 0xf; + s.x.x = p[y]; + s.a = x.d; + s.b = x.c; + s.c = x.f; + s.d = x.h; + s.e = x.h; + s.f = x.j; + s.g = 1.0f; + s.h = 1.0f; + s.i = 2; + s.j = x.m; + return s; +} +#endif +static DWORD test_reflection_desc_vs_blob[] = { +0x43425844, 0xb65955ac, 0xcea1cb75, 0x06c5a1ad, 0x8a555fa1, 0x00000001, 0x0000076c, 0x00000005, +0x00000034, 0x0000008c, 0x0000028c, 0x00000414, 0x000006f0, 0x46454452, 0x00000050, 0x00000000, +0x00000000, 0x00000000, 0x0000001c, 0xfffe0401, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f, +0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e, +0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x000001f8, 0x0000000f, 0x00000008, 0x00000170, +0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000010f, 0x0000017c, 0x00000000, 0x00000000, +0x00000003, 0x00000001, 0x0000000f, 0x00000185, 0x00000000, 0x00000000, 0x00000001, 0x00000002, +0x00000001, 0x00000192, 0x00000000, 0x00000000, 0x00000003, 0x00000003, 0x00000101, 0x0000019e, +0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x00000f0f, 0x0000019e, 0x00000001, 0x00000000, +0x00000003, 0x00000005, 0x0000000f, 0x000001a4, 0x00000000, 0x00000000, 0x00000003, 0x00000006, +0x0000000f, 0x000001ab, 0x00000000, 0x00000000, 0x00000003, 0x00000007, 0x00000f0f, 0x000001b4, +0x00000000, 0x00000000, 0x00000003, 0x00000008, 0x0000000f, 0x000001be, 0x00000000, 0x00000000, +0x00000003, 0x00000009, 0x00000101, 0x000001c4, 0x00000000, 0x00000000, 0x00000003, 0x0000000a, +0x0000000f, 0x000001cc, 0x00000000, 0x00000000, 0x00000003, 0x0000000b, 0x00000f0f, 0x000001d5, +0x00000000, 0x00000006, 0x00000001, 0x0000000c, 0x00000001, 0x000001e1, 0x00000000, 0x00000008, +0x00000001, 0x0000000d, 0x00000001, 0x000001ef, 0x00000000, 0x00000000, 0x00000003, 0x0000000e, +0x00000101, 0x705f5653, 0x7469736f, 0x006e6f69, 0x4f4e4942, 0x4c414d52, 0x454c4200, 0x4e49444e, +0x45434944, 0x4c420053, 0x57444e45, 0x48474945, 0x4f430054, 0x00524f4c, 0x4d524f4e, 0x50004c41, +0x5449534f, 0x004e4f49, 0x49534f50, 0x4e4f4954, 0x53500054, 0x00455a49, 0x474e4154, 0x00544e45, +0x43584554, 0x44524f4f, 0x5f565300, 0x74726556, 0x44497865, 0x5f565300, 0x74736e49, 0x65636e61, +0x74004449, 0x69747365, 0xabab006e, 0x4e47534f, 0x00000180, 0x0000000b, 0x00000008, 0x00000110, +0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000011c, 0x00000000, 0x00000000, +0x00000003, 0x00000001, 0x0000000f, 0x00000122, 0x00000000, 0x00000000, 0x00000003, 0x00000002, +0x00000e01, 0x00000126, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000d02, 0x0000012c, +0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000b04, 0x00000137, 0x00000000, 0x00000000, +0x00000003, 0x00000002, 0x00000708, 0x0000013f, 0x00000000, 0x00000000, 0x00000003, 0x00000003, +0x0000000f, 0x00000148, 0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x0000000f, 0x00000151, +0x00000000, 0x00000002, 0x00000003, 0x00000005, 0x00000e01, 0x00000161, 0x00000000, 0x00000003, +0x00000003, 0x00000005, 0x00000d02, 0x00000171, 0x00000000, 0x00000000, 0x00000001, 0x00000006, +0x00000e01, 0x705f5653, 0x7469736f, 0x006e6f69, 0x4f4c4f43, 0x4f460052, 0x53500047, 0x00455a49, +0x53534554, 0x54434146, 0x7400524f, 0x6f747365, 0x50007475, 0x5449534f, 0x004e4f49, 0x43584554, +0x44524f4f, 0x5f565300, 0x70696c43, 0x74736944, 0x65636e61, 0x5f565300, 0x6c6c7543, 0x74736944, +0x65636e61, 0x5f565300, 0x74736e49, 0x65636e61, 0xab004449, 0x52444853, 0x000002d4, 0x00010041, +0x000000b5, 0x0100086a, 0x0300005f, 0x00101012, 0x00000000, 0x0300005f, 0x00101012, 0x00000003, +0x0300005f, 0x001010f2, 0x00000004, 0x0300005f, 0x001010f2, 0x00000007, 0x0300005f, 0x00101012, +0x00000009, 0x0300005f, 0x001010f2, 0x0000000b, 0x0300005f, 0x00101012, 0x0000000e, 0x04000067, +0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x03000065, 0x00102012, +0x00000002, 0x03000065, 0x00102022, 0x00000002, 0x03000065, 0x00102042, 0x00000002, 0x03000065, +0x00102082, 0x00000002, 0x03000065, 0x001020f2, 0x00000003, 0x03000065, 0x001020f2, 0x00000004, +0x04000067, 0x00102012, 0x00000005, 0x00000002, 0x04000067, 0x00102022, 0x00000005, 0x00000003, +0x03000065, 0x00102012, 0x00000006, 0x02000068, 0x00000001, 0x04000069, 0x00000000, 0x00000005, +0x00000004, 0x06000036, 0x00203012, 0x00000000, 0x00000000, 0x00004001, 0x00000001, 0x06000036, +0x00203012, 0x00000000, 0x00000001, 0x00004001, 0x00000002, 0x06000036, 0x00203012, 0x00000000, +0x00000002, 0x00004001, 0x00000003, 0x06000036, 0x00203012, 0x00000000, 0x00000003, 0x00004001, +0x00000005, 0x06000036, 0x00203012, 0x00000000, 0x00000004, 0x00004001, 0x00000004, 0x0500001b, +0x00100012, 0x00000000, 0x0010100a, 0x00000000, 0x07000029, 0x00100012, 0x00000000, 0x00004001, +0x00000001, 0x0010000a, 0x00000000, 0x07000001, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, +0x00004001, 0x0000000f, 0x07000036, 0x00100012, 0x00000000, 0x0420300a, 0x00000000, 0x0010000a, +0x00000000, 0x0500002b, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x08000036, 0x001020e2, +0x00000000, 0x00004002, 0x00000000, 0x3e99999a, 0x3dcccccd, 0x00000000, 0x05000036, 0x001020f2, +0x00000001, 0x00101e46, 0x00000004, 0x05000036, 0x00102012, 0x00000002, 0x0010100a, 0x00000003, +0x05000036, 0x00102062, 0x00000002, 0x00101006, 0x00000009, 0x05000036, 0x00102082, 0x00000002, +0x0010100a, 0x0000000e, 0x05000036, 0x001020f2, 0x00000003, 0x00101e46, 0x00000007, 0x05000036, +0x001020f2, 0x00000004, 0x00101e46, 0x0000000b, 0x05000036, 0x00102012, 0x00000005, 0x00004001, +0x3f800000, 0x05000036, 0x00102022, 0x00000005, 0x00004001, 0x3f800000, 0x05000036, 0x00102012, +0x00000006, 0x00004001, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000015, 0x00000001, +0x00000000, 0x00000012, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, +0x00000005, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x0000000a, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, +}; + +static const D3D11_SIGNATURE_PARAMETER_DESC test_reflection_desc_vs_resultin[] = +{ + {"SV_position", 0, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x1, 0}, + {"BINORMAL", 0, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x0, 0}, + {"BLENDINDICES", 0, 2, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_UINT32, 0x1, 0x0, 0}, + {"BLENDWEIGHT", 0, 3, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0x1, 0}, + {"COLOR", 0, 4, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf, 0}, + {"COLOR", 1, 5, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x0, 0}, + {"NORMAL", 0, 6, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x0, 0}, + {"POSITION", 0, 7, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf, 0}, + {"POSITIONT", 0, 8, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x0, 0}, + {"PSIZE", 0, 9, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0x1, 0}, + {"TANGENT", 0, 10, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x0, 0}, + {"TEXCOORD", 0, 11, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf, 0}, + {"SV_VertexID", 0, 12, D3D_NAME_VERTEX_ID, D3D_REGISTER_COMPONENT_UINT32, 0x1, 0x0, 0}, + {"SV_InstanceID", 0, 13, D3D_NAME_INSTANCE_ID, D3D_REGISTER_COMPONENT_UINT32, 0x1, 0x0, 0}, + {"testin", 0, 14, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0x1, 0}, +}; + +static const D3D11_SIGNATURE_PARAMETER_DESC test_reflection_desc_vs_resultout[] = +{ + {"SV_position", 0, 0, D3D_NAME_POSITION, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x0, 0}, + {"COLOR", 0, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x0, 0}, + {"FOG", 0, 2, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe, 0}, + {"PSIZE", 0, 2, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x2, 0xd, 0}, + {"TESSFACTOR", 0, 2, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x4, 0xb, 0}, + {"testout", 0, 2, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x8, 0x7, 0}, + {"POSITION", 0, 3, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x0, 0}, + {"TEXCOORD", 0, 4, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x0, 0}, + {"SV_ClipDistance", 0, 5, D3D_NAME_CLIP_DISTANCE, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe, 0}, + {"SV_CullDistance", 0, 5, D3D_NAME_CULL_DISTANCE, D3D_REGISTER_COMPONENT_FLOAT32, 0x2, 0xd, 0}, + {"SV_InstanceID", 0, 6, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_UINT32, 0x1, 0xe, 0}, +}; + +static void test_reflection_desc_vs(void) +{ + HRESULT hr; + ULONG count; + ID3D11ShaderReflection *ref11; + D3D11_SHADER_DESC sdesc11 = {0}; + D3D11_SIGNATURE_PARAMETER_DESC desc = {0}; + const D3D11_SIGNATURE_PARAMETER_DESC *pdesc; + UINT ret; + unsigned int i; + + hr = pD3DReflect(test_reflection_desc_vs_blob, test_reflection_desc_vs_blob[6], &IID_ID3D11ShaderReflection, (void **)&ref11); + ok(hr == S_OK, "D3DReflect failed %x\n", hr); + + hr = ref11->lpVtbl->GetDesc(ref11, NULL); + ok(hr == E_FAIL, "GetDesc failed %x\n", hr); + + hr = ref11->lpVtbl->GetDesc(ref11, &sdesc11); + ok(hr == S_OK, "GetDesc failed %x\n", hr); + + ok(sdesc11.Version == 65601, "GetDesc failed, got %u, expected %u\n", sdesc11.Version, 65601); + ok(strcmp(sdesc11.Creator, (char*) shader_creator) == 0, "GetDesc failed, got \"%s\", expected \"%s\"\n", sdesc11.Creator, (char*)shader_creator); + ok(sdesc11.Flags == 256, "GetDesc failed, got %u, expected %u\n", sdesc11.Flags, 256); + ok(sdesc11.ConstantBuffers == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.ConstantBuffers, 0); + ok(sdesc11.BoundResources == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.BoundResources, 0); + ok(sdesc11.InputParameters == 15, "GetDesc failed, got %u, expected %u\n", sdesc11.InputParameters, 15); + ok(sdesc11.OutputParameters == 11, "GetDesc failed, got %u, expected %u\n", sdesc11.OutputParameters, 11); + ok(sdesc11.InstructionCount == 21, "GetDesc failed, got %u, expected %u\n", sdesc11.InstructionCount, 21); + ok(sdesc11.TempRegisterCount == 1, "GetDesc failed, got %u, expected %u\n", sdesc11.TempRegisterCount, 1); + ok(sdesc11.TempArrayCount == 5, "GetDesc failed, got %u, expected %u\n", sdesc11.TempArrayCount, 5); + ok(sdesc11.DefCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.DefCount, 0); + ok(sdesc11.DclCount == 18, "GetDesc failed, got %u, expected %u\n", sdesc11.DclCount, 18); + ok(sdesc11.TextureNormalInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.TextureNormalInstructions, 0); + ok(sdesc11.TextureLoadInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.TextureLoadInstructions, 0); + ok(sdesc11.TextureCompInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.TextureCompInstructions, 0); + ok(sdesc11.TextureBiasInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.TextureBiasInstructions, 0); + ok(sdesc11.TextureGradientInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.TextureGradientInstructions, 0); + ok(sdesc11.FloatInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.FloatInstructionCount, 0); + ok(sdesc11.IntInstructionCount == 1, "GetDesc failed, got %u, expected %u\n", sdesc11.IntInstructionCount, 1); + ok(sdesc11.UintInstructionCount == 1, "GetDesc failed, got %u, expected %u\n", sdesc11.UintInstructionCount, 1); + ok(sdesc11.StaticFlowControlCount == 1, "GetDesc failed, got %u, expected %u\n", sdesc11.StaticFlowControlCount, 1); + ok(sdesc11.DynamicFlowControlCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.DynamicFlowControlCount, 0); + ok(sdesc11.MacroInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.MacroInstructionCount, 0); + ok(sdesc11.ArrayInstructionCount == 6, "GetDesc failed, got %u, expected %u\n", sdesc11.ArrayInstructionCount, 6); + ok(sdesc11.CutInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.CutInstructionCount, 0); + ok(sdesc11.EmitInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.EmitInstructionCount, 0); + ok(sdesc11.GSOutputTopology == 0, "GetDesc failed, got %x, expected %x\n", sdesc11.GSOutputTopology, 0); + ok(sdesc11.GSMaxOutputVertexCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.GSMaxOutputVertexCount, 0); + ok(sdesc11.InputPrimitive == 0, "GetDesc failed, got %x, expected %x\n", sdesc11.InputPrimitive, 0); + ok(sdesc11.PatchConstantParameters == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.PatchConstantParameters, 0); + ok(sdesc11.cGSInstanceCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.cGSInstanceCount, 0); + ok(sdesc11.cControlPoints == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.cControlPoints, 0); + ok(sdesc11.HSOutputPrimitive == 0, "GetDesc failed, got %x, expected %x\n", sdesc11.HSOutputPrimitive, 0); + ok(sdesc11.HSPartitioning == 0, "GetDesc failed, got %x, expected %x\n", sdesc11.HSPartitioning, 0); + ok(sdesc11.TessellatorDomain == 0, "GetDesc failed, got %x, expected %x\n", sdesc11.TessellatorDomain, 0); + ok(sdesc11.cBarrierInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.cBarrierInstructions, 0); + ok(sdesc11.cInterlockedInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.cInterlockedInstructions, 0); + ok(sdesc11.cTextureStoreInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.cTextureStoreInstructions, 0); + + ret = ref11->lpVtbl->GetBitwiseInstructionCount(ref11); + ok(ret == 0, "GetBitwiseInstructionCount failed, got %u, expected %u\n", ret, 0); + + ret = ref11->lpVtbl->GetConversionInstructionCount(ref11); + ok(ret == 2, "GetConversionInstructionCount failed, got %u, expected %u\n", ret, 2); + + ret = ref11->lpVtbl->GetMovInstructionCount(ref11); + ok(ret == 10, "GetMovInstructionCount failed, got %u, expected %u\n", ret, 10); + + ret = ref11->lpVtbl->GetMovcInstructionCount(ref11); + ok(ret == 0, "GetMovcInstructionCount failed, got %u, expected %u\n", ret, 0); + + /* GetIn/OutputParameterDesc */ + for (i = 0; i < ARRAY_SIZE(test_reflection_desc_vs_resultin); ++i) + { + pdesc = &test_reflection_desc_vs_resultin[i]; + + hr = ref11->lpVtbl->GetInputParameterDesc(ref11, i, &desc); + ok(hr == S_OK, "GetInputParameterDesc(%u) failed, got %x, expected %x\n", i, hr, S_OK); + + ok(!strcmp(desc.SemanticName, pdesc->SemanticName), "GetInputParameterDesc(%u) SemanticName failed, got \"%s\", expected \"%s\"\n", + i, desc.SemanticName, pdesc->SemanticName); + ok(desc.SemanticIndex == pdesc->SemanticIndex, "GetInputParameterDesc(%u) SemanticIndex failed, got %u, expected %u\n", + i, desc.SemanticIndex, pdesc->SemanticIndex); + ok(desc.Register == pdesc->Register, "GetInputParameterDesc(%u) Register failed, got %u, expected %u\n", + i, desc.Register, pdesc->Register); + ok(desc.SystemValueType == pdesc->SystemValueType, "GetInputParameterDesc(%u) SystemValueType failed, got %x, expected %x\n", + i, desc.SystemValueType, pdesc->SystemValueType); + ok(desc.ComponentType == pdesc->ComponentType, "GetInputParameterDesc(%u) ComponentType failed, got %x, expected %x\n", + i, desc.ComponentType, pdesc->ComponentType); + ok(desc.Mask == pdesc->Mask, "GetInputParameterDesc(%u) Mask failed, got %x, expected %x\n", + i, desc.Mask, pdesc->Mask); + ok(desc.ReadWriteMask == pdesc->ReadWriteMask, "GetInputParameterDesc(%u) ReadWriteMask failed, got %x, expected %x\n", + i, desc.ReadWriteMask, pdesc->ReadWriteMask); + ok(desc.Stream == pdesc->Stream, "GetInputParameterDesc(%u) Stream failed, got %u, expected %u\n", + i, desc.Stream, pdesc->ReadWriteMask); + } + + for (i = 0; i < ARRAY_SIZE(test_reflection_desc_vs_resultout); ++i) + { + pdesc = &test_reflection_desc_vs_resultout[i]; + + hr = ref11->lpVtbl->GetOutputParameterDesc(ref11, i, &desc); + ok(hr == S_OK, "GetOutputParameterDesc(%u) failed, got %x, expected %x\n", i, hr, S_OK); + + ok(!strcmp(desc.SemanticName, pdesc->SemanticName), "GetOutputParameterDesc(%u) SemanticName failed, got \"%s\", expected \"%s\"\n", + i, desc.SemanticName, pdesc->SemanticName); + ok(desc.SemanticIndex == pdesc->SemanticIndex, "GetOutputParameterDesc(%u) SemanticIndex failed, got %u, expected %u\n", + i, desc.SemanticIndex, pdesc->SemanticIndex); + ok(desc.Register == pdesc->Register, "GetOutputParameterDesc(%u) Register failed, got %u, expected %u\n", + i, desc.Register, pdesc->Register); + ok(desc.SystemValueType == pdesc->SystemValueType, "GetOutputParameterDesc(%u) SystemValueType failed, got %x, expected %x\n", + i, desc.SystemValueType, pdesc->SystemValueType); + ok(desc.ComponentType == pdesc->ComponentType, "GetOutputParameterDesc(%u) ComponentType failed, got %x, expected %x\n", + i, desc.ComponentType, pdesc->ComponentType); + ok(desc.Mask == pdesc->Mask, "GetOutputParameterDesc(%u) Mask failed, got %x, expected %x\n", + i, desc.Mask, pdesc->Mask); + ok(desc.ReadWriteMask == pdesc->ReadWriteMask, "GetOutputParameterDesc(%u) ReadWriteMask failed, got %x, expected %x\n", + i, desc.ReadWriteMask, pdesc->ReadWriteMask); + ok(desc.Stream == pdesc->Stream, "GetOutputParameterDesc(%u) Stream failed, got %u, expected %u\n", + i, desc.Stream, pdesc->ReadWriteMask); + } + + count = ref11->lpVtbl->Release(ref11); + ok(count == 0, "Release failed %u\n", count); +} + +/* + * fxc.exe /E PS /Tps_4_1 /Fx + */ +#if 0 +Texture2D tex1; +Texture2D tex2; +SamplerState sam +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Wrap; + AddressV = Wrap; +}; +SamplerComparisonState samc +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = w1; + AddressV = Wrap; + ComparisonFunc = LESS; +}; +struct psin +{ + uint f : SV_RenderTargetArrayIndex; + uint g : SV_InstanceID; + uint h : SV_PrimitiveID; + float2 uv : TEXCOORD; + float4 a : COLOR3; + float b : VFACE; + float4 c : SV_position; + bool d : SV_Coverage; + bool e : SV_IsFrontFace; +}; +struct psout +{ + float a : SV_Target1; + float b : SV_Depth; + float x : SV_Target; + bool c : SV_Coverage; +}; +psout PS(psin p) +{ + psout a; + float4 x = tex1.Sample(sam, p.uv); + x += tex1.SampleCmp(samc, p.uv, 0.3f); + if (x.y < 0.1f) + x += tex2.SampleCmp(samc, p.uv, 0.4f); + else if (x.y < 0.2f) + x += tex2.SampleCmp(samc, p.uv, 0.1f); + else if (x.y < 0.3f) + x += tex2.SampleBias(sam, p.uv, 0.1f); + else if (x.y < 0.4f) + x += tex2.SampleBias(sam, p.uv, 0.2f); + else if (x.y < 0.5f) + x += tex2.SampleBias(sam, p.uv, 0.3f); + else + x += tex2.SampleBias(sam, p.uv, 0.4f); + x += tex2.SampleGrad(sam, p.uv, x.xy, x.xy); + x += tex2.SampleGrad(sam, p.uv, x.xz, x.xz); + x += tex2.SampleGrad(sam, p.uv, x.xz, x.zy); + x += tex2.SampleGrad(sam, p.uv, x.xz, x.zw); + x += tex2.SampleGrad(sam, p.uv, x.xz, x.wz); + a.a = x.y; + a.b = x.x; + a.x = x.x; + a.c = true; + return a; +} +#endif +static DWORD test_reflection_desc_ps_blob[] = { +0x43425844, 0x19e2f325, 0xf1ec39a3, 0x3c5a8b53, 0x5bd5fb65, 0x00000001, 0x000008d0, 0x00000005, +0x00000034, 0x0000011c, 0x00000254, 0x000002e4, 0x00000854, 0x46454452, 0x000000e0, 0x00000000, +0x00000000, 0x00000004, 0x0000001c, 0xffff0401, 0x00000100, 0x000000af, 0x0000009c, 0x00000003, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x000000a0, 0x00000003, +0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000002, 0x000000a5, 0x00000002, +0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000c, 0x000000aa, 0x00000002, +0x00000005, 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000c, 0x006d6173, 0x636d6173, +0x78657400, 0x65740031, 0x4d003278, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, +0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x4e475349, +0x00000130, 0x00000008, 0x00000008, 0x000000c8, 0x00000000, 0x00000004, 0x00000001, 0x00000000, +0x00000001, 0x000000e2, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000002, 0x000000f0, +0x00000000, 0x00000007, 0x00000001, 0x00000000, 0x00000004, 0x000000ff, 0x00000000, 0x00000009, +0x00000001, 0x00000000, 0x00000008, 0x0000010e, 0x00000000, 0x00000000, 0x00000003, 0x00000001, +0x00000303, 0x00000117, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000004, 0x0000011d, +0x00000003, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x00000123, 0x00000000, 0x00000001, +0x00000003, 0x00000003, 0x0000000f, 0x525f5653, 0x65646e65, 0x72615472, 0x41746567, 0x79617272, +0x65646e49, 0x56530078, 0x736e495f, 0x636e6174, 0x00444965, 0x505f5653, 0x696d6972, 0x65766974, +0x53004449, 0x73495f56, 0x6e6f7246, 0x63614674, 0x45540065, 0x4f4f4358, 0x56004452, 0x45434146, +0x4c4f4300, 0x5300524f, 0x6f705f56, 0x69746973, 0xab006e6f, 0x4e47534f, 0x00000088, 0x00000004, +0x00000008, 0x00000068, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000e01, 0x00000068, +0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000e01, 0x00000072, 0x00000000, 0x00000000, +0x00000001, 0xffffffff, 0x00000e01, 0x0000007e, 0x00000000, 0x00000000, 0x00000003, 0xffffffff, +0x00000e01, 0x545f5653, 0x65677261, 0x56530074, 0x766f435f, 0x67617265, 0x56530065, 0x7065445f, +0xab006874, 0x52444853, 0x00000568, 0x00000041, 0x0000015a, 0x0100086a, 0x0300005a, 0x00106000, +0x00000000, 0x0300085a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, +0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03000065, +0x00102012, 0x00000000, 0x03000065, 0x00102012, 0x00000001, 0x02000065, 0x0000f000, 0x02000065, +0x0000c001, 0x02000068, 0x00000003, 0x09000045, 0x001000f2, 0x00000000, 0x00101046, 0x00000001, +0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0b000046, 0x00100012, 0x00000001, 0x00101046, +0x00000001, 0x00107006, 0x00000000, 0x00106000, 0x00000001, 0x00004001, 0x3e99999a, 0x07000000, +0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, 0x00000001, 0x07000031, 0x00100012, +0x00000001, 0x0010001a, 0x00000000, 0x00004001, 0x3dcccccd, 0x0304001f, 0x0010000a, 0x00000001, +0x0b000046, 0x00100012, 0x00000001, 0x00101046, 0x00000001, 0x00107006, 0x00000001, 0x00106000, +0x00000001, 0x00004001, 0x3ecccccd, 0x07000000, 0x001000f2, 0x00000001, 0x00100e46, 0x00000000, +0x00100006, 0x00000001, 0x01000012, 0x07000031, 0x00100012, 0x00000002, 0x0010001a, 0x00000000, +0x00004001, 0x3e4ccccd, 0x0304001f, 0x0010000a, 0x00000002, 0x0b000046, 0x00100012, 0x00000002, +0x00101046, 0x00000001, 0x00107006, 0x00000001, 0x00106000, 0x00000001, 0x00004001, 0x3dcccccd, +0x07000000, 0x001000f2, 0x00000001, 0x00100e46, 0x00000000, 0x00100006, 0x00000002, 0x01000012, +0x07000031, 0x00100012, 0x00000002, 0x0010001a, 0x00000000, 0x00004001, 0x3e99999a, 0x0304001f, +0x0010000a, 0x00000002, 0x0b00004a, 0x001000f2, 0x00000002, 0x00101046, 0x00000001, 0x00107e46, +0x00000001, 0x00106000, 0x00000000, 0x00004001, 0x3dcccccd, 0x07000000, 0x001000f2, 0x00000001, +0x00100e46, 0x00000000, 0x00100e46, 0x00000002, 0x01000012, 0x07000031, 0x00100012, 0x00000002, +0x0010001a, 0x00000000, 0x00004001, 0x3ecccccd, 0x0304001f, 0x0010000a, 0x00000002, 0x0b00004a, +0x001000f2, 0x00000002, 0x00101046, 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000000, +0x00004001, 0x3e4ccccd, 0x07000000, 0x001000f2, 0x00000001, 0x00100e46, 0x00000000, 0x00100e46, +0x00000002, 0x01000012, 0x07000031, 0x00100012, 0x00000002, 0x0010001a, 0x00000000, 0x00004001, +0x3f000000, 0x0304001f, 0x0010000a, 0x00000002, 0x0b00004a, 0x001000f2, 0x00000002, 0x00101046, +0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000000, 0x00004001, 0x3e99999a, 0x07000000, +0x001000f2, 0x00000001, 0x00100e46, 0x00000000, 0x00100e46, 0x00000002, 0x01000012, 0x0b00004a, +0x001000f2, 0x00000002, 0x00101046, 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000000, +0x00004001, 0x3ecccccd, 0x07000000, 0x001000f2, 0x00000001, 0x00100e46, 0x00000000, 0x00100e46, +0x00000002, 0x01000015, 0x01000015, 0x01000015, 0x01000015, 0x01000015, 0x0d000049, 0x001000f2, +0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000000, 0x00100046, +0x00000001, 0x00100046, 0x00000001, 0x07000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, +0x00100e46, 0x00000001, 0x0d000049, 0x001000f2, 0x00000001, 0x00101046, 0x00000001, 0x00107e46, +0x00000001, 0x00106000, 0x00000000, 0x00100086, 0x00000000, 0x00100086, 0x00000000, 0x07000000, +0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0d000049, 0x001000f2, +0x00000001, 0x00101046, 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000000, 0x00100086, +0x00000000, 0x00100a66, 0x00000000, 0x07000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, +0x00100e46, 0x00000001, 0x0d000049, 0x001000f2, 0x00000001, 0x00101046, 0x00000001, 0x00107e46, +0x00000001, 0x00106000, 0x00000000, 0x00100086, 0x00000000, 0x00100ae6, 0x00000000, 0x07000000, +0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0d000049, 0x001000c2, +0x00000000, 0x00101046, 0x00000001, 0x001074e6, 0x00000001, 0x00106000, 0x00000000, 0x00100086, +0x00000000, 0x00100fb6, 0x00000000, 0x07000000, 0x00100032, 0x00000000, 0x00100ae6, 0x00000000, +0x00100046, 0x00000000, 0x05000036, 0x00102012, 0x00000001, 0x0010001a, 0x00000000, 0x04000036, +0x0000c001, 0x0010000a, 0x00000000, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, +0x04000036, 0x0000f001, 0x00004001, 0xffffffff, 0x0100003e, 0x54415453, 0x00000074, 0x00000032, +0x00000003, 0x00000000, 0x00000005, 0x00000011, 0x00000000, 0x00000000, 0x00000006, 0x00000005, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000003, +0x00000004, 0x00000005, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const D3D11_SIGNATURE_PARAMETER_DESC test_reflection_desc_ps_resultin[] = +{ + {"SV_RenderTargetArrayIndex", 0, 0, D3D_NAME_RENDER_TARGET_ARRAY_INDEX, D3D_REGISTER_COMPONENT_UINT32, 0x1, 0x0, 0}, + {"SV_InstanceID", 0, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_UINT32, 0x2, 0x0, 0}, + {"SV_PrimitiveID", 0, 0, D3D_NAME_PRIMITIVE_ID, D3D_REGISTER_COMPONENT_UINT32, 0x4, 0x0, 0}, + {"SV_IsFrontFace", 0, 0, D3D_NAME_IS_FRONT_FACE, D3D_REGISTER_COMPONENT_UINT32, 0x8, 0x0, 0}, + {"TEXCOORD", 0, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x3, 0x3, 0}, + {"VFACE", 0, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x4, 0x0, 0}, + {"COLOR", 3, 2, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x0, 0}, + {"SV_position", 0, 3, D3D_NAME_POSITION, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x0, 0}, +}; + +static const D3D11_SIGNATURE_PARAMETER_DESC test_reflection_desc_ps_resultout[] = +{ + {"SV_Target", 0, 0, D3D_NAME_TARGET, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe, 0}, + {"SV_Target", 1, 1, D3D_NAME_TARGET, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe, 0}, + {"SV_Coverage", 0, 0xffffffff, D3D_NAME_COVERAGE, D3D_REGISTER_COMPONENT_UINT32, 0x1, 0xe, 0}, + {"SV_Depth", 0, 0xffffffff, D3D_NAME_DEPTH, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe, 0}, +}; + +static void test_reflection_desc_ps(void) +{ + HRESULT hr; + ULONG count; + ID3D11ShaderReflection *ref11; + D3D11_SHADER_DESC sdesc11 = {0}; + D3D11_SIGNATURE_PARAMETER_DESC desc = {0}; + const D3D11_SIGNATURE_PARAMETER_DESC *pdesc; + UINT ret; + unsigned int i; + + hr = pD3DReflect(test_reflection_desc_ps_blob, test_reflection_desc_ps_blob[6], &IID_ID3D11ShaderReflection, (void **)&ref11); + ok(hr == S_OK, "D3DReflect failed %x\n", hr); + + hr = ref11->lpVtbl->GetDesc(ref11, &sdesc11); + ok(hr == S_OK, "GetDesc failed %x\n", hr); + + ok(sdesc11.Version == 65, "GetDesc failed, got %u, expected %u\n", sdesc11.Version, 65); + ok(strcmp(sdesc11.Creator, (char*) shader_creator) == 0, "GetDesc failed, got \"%s\", expected \"%s\"\n", sdesc11.Creator, (char*)shader_creator); + ok(sdesc11.Flags == 256, "GetDesc failed, got %u, expected %u\n", sdesc11.Flags, 256); + ok(sdesc11.ConstantBuffers == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.ConstantBuffers, 0); + ok(sdesc11.BoundResources == 4, "GetDesc failed, got %u, expected %u\n", sdesc11.BoundResources, 4); + ok(sdesc11.InputParameters == 8, "GetDesc failed, got %u, expected %u\n", sdesc11.InputParameters, 8); + ok(sdesc11.OutputParameters == 4, "GetDesc failed, got %u, expected %u\n", sdesc11.OutputParameters, 4); + ok(sdesc11.InstructionCount == 50, "GetDesc failed, got %u, expected %u\n", sdesc11.InstructionCount, 50); + ok(sdesc11.TempRegisterCount == 3, "GetDesc failed, got %u, expected %u\n", sdesc11.TempRegisterCount, 3); + ok(sdesc11.TempArrayCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.TempArrayCount, 0); + ok(sdesc11.DefCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.DefCount, 0); + ok(sdesc11.DclCount == 5, "GetDesc failed, got %u, expected %u\n", sdesc11.DclCount, 5); + ok(sdesc11.TextureNormalInstructions == 1, "GetDesc failed, got %u, expected %u\n", sdesc11.TextureNormalInstructions, 1); + ok(sdesc11.TextureLoadInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.TextureLoadInstructions, 0); + ok(sdesc11.TextureCompInstructions == 3, "GetDesc failed, got %u, expected %u\n", sdesc11.TextureCompInstructions, 3); + ok(sdesc11.TextureBiasInstructions == 4, "GetDesc failed, got %u, expected %u\n", sdesc11.TextureBiasInstructions, 4); + ok(sdesc11.TextureGradientInstructions == 5, "GetDesc failed, got %u, expected %u\n", sdesc11.TextureGradientInstructions, 5); + ok(sdesc11.FloatInstructionCount == 17, "GetDesc failed, got %u, expected %u\n", sdesc11.FloatInstructionCount, 17); + ok(sdesc11.IntInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.IntInstructionCount, 0); + ok(sdesc11.UintInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.UintInstructionCount, 0); + ok(sdesc11.StaticFlowControlCount == 6, "GetDesc failed, got %u, expected %u\n", sdesc11.StaticFlowControlCount, 6); + ok(sdesc11.DynamicFlowControlCount == 5, "GetDesc failed, got %u, expected %u\n", sdesc11.DynamicFlowControlCount, 5); + ok(sdesc11.MacroInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.MacroInstructionCount, 0); + ok(sdesc11.ArrayInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.ArrayInstructionCount, 0); + ok(sdesc11.CutInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.CutInstructionCount, 0); + ok(sdesc11.EmitInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.EmitInstructionCount, 0); + ok(sdesc11.GSOutputTopology == 0, "GetDesc failed, got %x, expected %x\n", sdesc11.GSOutputTopology, 0); + ok(sdesc11.GSMaxOutputVertexCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.GSMaxOutputVertexCount, 0); + ok(sdesc11.InputPrimitive == 0, "GetDesc failed, got %x, expected %x\n", sdesc11.InputPrimitive, 0); + ok(sdesc11.PatchConstantParameters == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.PatchConstantParameters, 0); + ok(sdesc11.cGSInstanceCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.cGSInstanceCount, 0); + ok(sdesc11.cControlPoints == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.cControlPoints, 0); + ok(sdesc11.HSOutputPrimitive == 0, "GetDesc failed, got %x, expected %x\n", sdesc11.HSOutputPrimitive, 0); + ok(sdesc11.HSPartitioning == 0, "GetDesc failed, got %x, expected %x\n", sdesc11.HSPartitioning, 0); + ok(sdesc11.TessellatorDomain == 0, "GetDesc failed, got %x, expected %x\n", sdesc11.TessellatorDomain, 0); + ok(sdesc11.cBarrierInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.cBarrierInstructions, 0); + ok(sdesc11.cInterlockedInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.cInterlockedInstructions, 0); + ok(sdesc11.cTextureStoreInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc11.cTextureStoreInstructions, 0); + + ret = ref11->lpVtbl->GetBitwiseInstructionCount(ref11); + ok(ret == 0, "GetBitwiseInstructionCount failed, got %u, expected %u\n", ret, 0); + + ret = ref11->lpVtbl->GetConversionInstructionCount(ref11); + ok(ret == 0, "GetConversionInstructionCount failed, got %u, expected %u\n", ret, 0); + + ret = ref11->lpVtbl->GetMovInstructionCount(ref11); + ok(ret == 24, "GetMovInstructionCount failed, got %u, expected %u\n", ret, 24); + + ret = ref11->lpVtbl->GetMovcInstructionCount(ref11); + ok(ret == 0, "GetMovcInstructionCount failed, got %u, expected %u\n", ret, 0); + + /* check invalid Get*ParameterDesc cases*/ + hr = ref11->lpVtbl->GetInputParameterDesc(ref11, 0, NULL); + ok(hr == E_INVALIDARG, "GetInputParameterDesc failed, got %x, expected %x\n", hr, E_INVALIDARG); + + hr = ref11->lpVtbl->GetInputParameterDesc(ref11, 0xffffffff, &desc); + ok(hr == E_INVALIDARG, "GetInputParameterDesc failed, got %x, expected %x\n", hr, E_INVALIDARG); + + hr = ref11->lpVtbl->GetOutputParameterDesc(ref11, 0, NULL); + ok(hr == E_INVALIDARG, "GetOutputParameterDesc failed, got %x, expected %x\n", hr, E_INVALIDARG); + + hr = ref11->lpVtbl->GetOutputParameterDesc(ref11, 0xffffffff, &desc); + ok(hr == E_INVALIDARG, "GetOutputParameterDesc failed, got %x, expected %x\n", hr, E_INVALIDARG); + + hr = ref11->lpVtbl->GetPatchConstantParameterDesc(ref11, 0, &desc); + ok(hr == E_INVALIDARG, "GetPatchConstantParameterDesc failed, got %x, expected %x\n", hr, E_INVALIDARG); + + /* GetIn/OutputParameterDesc */ + for (i = 0; i < ARRAY_SIZE(test_reflection_desc_ps_resultin); ++i) + { + pdesc = &test_reflection_desc_ps_resultin[i]; + + hr = ref11->lpVtbl->GetInputParameterDesc(ref11, i, &desc); + ok(hr == S_OK, "GetInputParameterDesc(%u) failed, got %x, expected %x\n", i, hr, S_OK); + + ok(!strcmp(desc.SemanticName, pdesc->SemanticName), "GetInputParameterDesc(%u) SemanticName failed, got \"%s\", expected \"%s\"\n", + i, desc.SemanticName, pdesc->SemanticName); + ok(desc.SemanticIndex == pdesc->SemanticIndex, "GetInputParameterDesc(%u) SemanticIndex failed, got %u, expected %u\n", + i, desc.SemanticIndex, pdesc->SemanticIndex); + ok(desc.Register == pdesc->Register, "GetInputParameterDesc(%u) Register failed, got %u, expected %u\n", + i, desc.Register, pdesc->Register); + ok(desc.SystemValueType == pdesc->SystemValueType, "GetInputParameterDesc(%u) SystemValueType failed, got %x, expected %x\n", + i, desc.SystemValueType, pdesc->SystemValueType); + ok(desc.ComponentType == pdesc->ComponentType, "GetInputParameterDesc(%u) ComponentType failed, got %x, expected %x\n", + i, desc.ComponentType, pdesc->ComponentType); + ok(desc.Mask == pdesc->Mask, "GetInputParameterDesc(%u) Mask failed, got %x, expected %x\n", + i, desc.Mask, pdesc->Mask); + ok(desc.ReadWriteMask == pdesc->ReadWriteMask, "GetInputParameterDesc(%u) ReadWriteMask failed, got %x, expected %x\n", + i, desc.ReadWriteMask, pdesc->ReadWriteMask); + ok(desc.Stream == pdesc->Stream, "GetInputParameterDesc(%u) Stream failed, got %u, expected %u\n", + i, desc.Stream, pdesc->ReadWriteMask); + } + + for (i = 0; i < ARRAY_SIZE(test_reflection_desc_ps_resultout); ++i) + { + pdesc = &test_reflection_desc_ps_resultout[i]; + + hr = ref11->lpVtbl->GetOutputParameterDesc(ref11, i, &desc); + ok(hr == S_OK, "GetOutputParameterDesc(%u) failed, got %x, expected %x\n", i, hr, S_OK); + + ok(!strcmp(desc.SemanticName, pdesc->SemanticName), "GetOutputParameterDesc(%u) SemanticName failed, got \"%s\", expected \"%s\"\n", + i, desc.SemanticName, pdesc->SemanticName); + ok(desc.SemanticIndex == pdesc->SemanticIndex, "GetOutputParameterDesc(%u) SemanticIndex failed, got %u, expected %u\n", + i, desc.SemanticIndex, pdesc->SemanticIndex); + ok(desc.Register == pdesc->Register, "GetOutputParameterDesc(%u) Register failed, got %u, expected %u\n", + i, desc.Register, pdesc->Register); + ok(desc.SystemValueType == pdesc->SystemValueType, "GetOutputParameterDesc(%u) SystemValueType failed, got %x, expected %x\n", + i, desc.SystemValueType, pdesc->SystemValueType); + ok(desc.ComponentType == pdesc->ComponentType, "GetOutputParameterDesc(%u) ComponentType failed, got %x, expected %x\n", + i, desc.ComponentType, pdesc->ComponentType); + ok(desc.Mask == pdesc->Mask, "GetOutputParameterDesc(%u) Mask failed, got %x, expected %x\n", + i, desc.Mask, pdesc->Mask); + ok(desc.ReadWriteMask == pdesc->ReadWriteMask, "GetOutputParameterDesc(%u) ReadWriteMask failed, got %x, expected %x\n", + i, desc.ReadWriteMask, pdesc->ReadWriteMask); + ok(desc.Stream == pdesc->Stream, "GetOutputParameterDesc(%u) Stream failed, got %u, expected %u\n", + i, desc.Stream, pdesc->ReadWriteMask); + } + + count = ref11->lpVtbl->Release(ref11); + ok(count == 0, "Release failed %u\n", count); +} + +/* + * fxc.exe /E PS /Tps_5_0 /Fx + */ +#if 0 +float4 PS() : SV_Target3 +{ + float4 a = float4(1.2f, 1.0f, 0.2f, 0.0f); + return a; +} +#endif +static const DWORD test_reflection_desc_ps_output_blob_0[] = { +0x43425844, 0x3e7b77e6, 0xe4e920b7, 0x9cad0533, 0x240117cc, 0x00000001, 0x0000018c, 0x00000005, +0x00000034, 0x0000008c, 0x0000009c, 0x000000d0, 0x00000110, 0x46454452, 0x00000050, 0x00000000, +0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f, +0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e, +0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, +0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000003, 0x00000000, 0x00000003, 0x00000003, +0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000038, 0x00000040, 0x0000000e, +0x03000065, 0x001020f2, 0x00000003, 0x08000036, 0x001020f2, 0x00000003, 0x00004002, 0x3f99999a, +0x3f800000, 0x3e4ccccd, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, +0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000 +}; + +/* + * fxc.exe /E PS /Tps_5_0 /Fx + */ +#if 0 +float PS() : SV_DepthLessEqual +{ + float a = 1.2f; + return a; +} +#endif +static const DWORD test_reflection_desc_ps_output_blob_1[] = { +0x43425844, 0xd8ead3ec, 0x61276ada, 0x70cdaa9e, 0x2cfd7f4c, 0x00000001, 0x000001c4, 0x00000005, +0x00000034, 0x000000ac, 0x000000bc, 0x000000f8, 0x00000128, 0x46454452, 0x00000070, 0x00000000, +0x00000000, 0x00000000, 0x0000003c, 0xffff0500, 0x00000100, 0x0000003c, 0x31314452, 0x0000003c, +0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, 0x7263694d, 0x666f736f, +0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e, +0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, +0x00000034, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0xffffffff, +0x00000e01, 0x445f5653, 0x68747065, 0x7373654c, 0x61757145, 0xabab006c, 0x58454853, 0x00000028, +0x00000050, 0x0000000a, 0x0100086a, 0x02000065, 0x00027001, 0x04000036, 0x00027001, 0x00004001, +0x3f99999a, 0x0100003e, 0x54415453, 0x00000094, 0x00000002, 0x00000000, 0x00000000, 0x00000001, +0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, +}; + +/* + * fxc.exe /E PS /Tps_5_0 /Fx + */ +#if 0 +float PS() : SV_DepthGreaterEqual +{ + float a = 1.2f; + return a; +} +#endif +static const DWORD test_reflection_desc_ps_output_blob_2[] = { +0x43425844, 0x9f61c8df, 0x612cbb1f, 0x9e1d039e, 0xf925a074, 0x00000001, 0x000001c8, 0x00000005, +0x00000034, 0x000000ac, 0x000000bc, 0x000000fc, 0x0000012c, 0x46454452, 0x00000070, 0x00000000, +0x00000000, 0x00000000, 0x0000003c, 0xffff0500, 0x00000100, 0x0000003c, 0x31314452, 0x0000003c, +0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, 0x7263694d, 0x666f736f, +0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e, +0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, +0x00000038, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0xffffffff, +0x00000e01, 0x445f5653, 0x68747065, 0x61657247, 0x45726574, 0x6c617571, 0xababab00, 0x58454853, +0x00000028, 0x00000050, 0x0000000a, 0x0100086a, 0x02000065, 0x00026001, 0x04000036, 0x00026001, +0x00004001, 0x3f99999a, 0x0100003e, 0x54415453, 0x00000094, 0x00000002, 0x00000000, 0x00000000, +0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, +}; + +/* + * fxc.exe /E PS /Tps_5_0 /Fx + */ +#if 0 +float PS() : sV_DePtH +{ + float a = 1.2f; + return a; +} +#endif +static const DWORD test_reflection_desc_ps_output_blob_3[] = { +0x43425844, 0x32cec0e6, 0x3873ed32, 0x2e86ffd0, 0x21bb00e8, 0x00000001, 0x000001bc, 0x00000005, +0x00000034, 0x000000ac, 0x000000bc, 0x000000f0, 0x00000120, 0x46454452, 0x00000070, 0x00000000, +0x00000000, 0x00000000, 0x0000003c, 0xffff0500, 0x00000100, 0x0000003c, 0x31314452, 0x0000003c, +0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, 0x7263694d, 0x666f736f, +0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e, +0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, +0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0xffffffff, +0x00000e01, 0x445f5673, 0x48745065, 0xababab00, 0x58454853, 0x00000028, 0x00000050, 0x0000000a, +0x0100086a, 0x02000065, 0x0000c001, 0x04000036, 0x0000c001, 0x00004001, 0x3f99999a, 0x0100003e, +0x54415453, 0x00000094, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, +0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +/* + * fxc.exe /E PS /Tps_4_0 /Fx + */ +#if 0 +float PS() : SV_Depth +{ + float a = 1.2f; + return a; +} +#endif +static const DWORD test_reflection_desc_ps_output_blob_4[] = { +0x43425844, 0x7af34874, 0x975f09ad, 0xf6e50764, 0xdfb1255f, 0x00000001, 0x00000178, 0x00000005, +0x00000034, 0x0000008c, 0x0000009c, 0x000000d0, 0x000000fc, 0x46454452, 0x00000050, 0x00000000, +0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f, +0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e, +0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, +0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0xffffffff, +0x00000e01, 0x445f5653, 0x68747065, 0xababab00, 0x52444853, 0x00000024, 0x00000040, 0x00000009, +0x02000065, 0x0000c001, 0x04000036, 0x0000c001, 0x00004001, 0x3f99999a, 0x0100003e, 0x54415453, +0x00000074, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, +0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +/* + * fxc.exe /E PS /Tps_4_0 /Fx + */ +#if 0 +bool PS() : SV_COVERAGE +{ + bool a = true; + return a; +} +#endif +static const DWORD test_reflection_desc_ps_output_blob_5[] = { +0x43425844, 0x40ae32a7, 0xe944bb1c, 0x1a2b1923, 0xea25962d, 0x00000001, 0x000001bc, 0x00000005, +0x00000034, 0x000000ac, 0x000000bc, 0x000000f0, 0x00000120, 0x46454452, 0x00000070, 0x00000000, +0x00000000, 0x00000000, 0x0000003c, 0xffff0500, 0x00000100, 0x0000003c, 0x31314452, 0x0000003c, +0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, 0x7263694d, 0x666f736f, +0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e, +0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, +0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0xffffffff, +0x00000e01, 0x435f5653, 0x5245564f, 0x00454741, 0x58454853, 0x00000028, 0x00000050, 0x0000000a, +0x0100086a, 0x02000065, 0x0000f000, 0x04000036, 0x0000f001, 0x00004001, 0xffffffff, 0x0100003e, +0x54415453, 0x00000094, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, +0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const DWORD *test_reflection_desc_ps_output_blob[] = { + test_reflection_desc_ps_output_blob_0, + test_reflection_desc_ps_output_blob_1, + test_reflection_desc_ps_output_blob_2, + test_reflection_desc_ps_output_blob_3, + test_reflection_desc_ps_output_blob_4, + test_reflection_desc_ps_output_blob_5, +}; + +static const D3D11_SIGNATURE_PARAMETER_DESC test_reflection_desc_ps_output_result[] = +{ + {"SV_Target", 3, 3, D3D_NAME_TARGET, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0, 0}, + {"SV_DepthLessEqual", 0, 0xffffffff, D3D_NAME_DEPTH_LESS_EQUAL, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe, 0}, + {"SV_DepthGreaterEqual", 0, 0xffffffff, D3D11_NAME_DEPTH_GREATER_EQUAL, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe, 0}, + {"sV_DePtH", 0, 0xffffffff, D3D_NAME_DEPTH, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe, 0}, + {"SV_Depth", 0, 0xffffffff, D3D_NAME_DEPTH, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe, 0}, + {"SV_COVERAGE", 0, 0xffffffff, D3D_NAME_COVERAGE, D3D_REGISTER_COMPONENT_UINT32, 0x1, 0xe, 0}, +}; + +static void test_reflection_desc_ps_output(void) +{ + HRESULT hr; + ULONG count; + ID3D11ShaderReflection *ref11; + D3D11_SIGNATURE_PARAMETER_DESC desc = {0}; + const D3D11_SIGNATURE_PARAMETER_DESC *pdesc; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(test_reflection_desc_ps_output_result); ++i) + { + hr = pD3DReflect(test_reflection_desc_ps_output_blob[i], test_reflection_desc_ps_output_blob[i][6], &IID_ID3D11ShaderReflection, (void **)&ref11); + ok(hr == S_OK, "(%u): D3DReflect failed %x\n", i, hr); + + pdesc = &test_reflection_desc_ps_output_result[i]; + + hr = ref11->lpVtbl->GetOutputParameterDesc(ref11, 0, &desc); + ok(hr == S_OK, "(%u): GetOutputParameterDesc failed, got %x, expected %x\n", i, hr, S_OK); + + ok(!strcmp(desc.SemanticName, pdesc->SemanticName), "(%u): GetOutputParameterDesc SemanticName failed, got \"%s\", expected \"%s\"\n", + i, desc.SemanticName, pdesc->SemanticName); + ok(desc.SemanticIndex == pdesc->SemanticIndex, "(%u): GetOutputParameterDesc SemanticIndex failed, got %u, expected %u\n", + i, desc.SemanticIndex, pdesc->SemanticIndex); + ok(desc.Register == pdesc->Register, "(%u): GetOutputParameterDesc Register failed, got %u, expected %u\n", + i, desc.Register, pdesc->Register); + ok(desc.SystemValueType == pdesc->SystemValueType, "(%u): GetOutputParameterDesc SystemValueType failed, got %x, expected %x\n", + i, desc.SystemValueType, pdesc->SystemValueType); + ok(desc.ComponentType == pdesc->ComponentType, "(%u): GetOutputParameterDesc ComponentType failed, got %x, expected %x\n", + i, desc.ComponentType, pdesc->ComponentType); + ok(desc.Mask == pdesc->Mask, "(%u): GetOutputParameterDesc Mask failed, got %x, expected %x\n", + i, desc.Mask, pdesc->Mask); + ok(desc.ReadWriteMask == pdesc->ReadWriteMask, "(%u): GetOutputParameterDesc ReadWriteMask failed, got %x, expected %x\n", + i, desc.ReadWriteMask, pdesc->ReadWriteMask); + ok(desc.Stream == pdesc->Stream, "(%u): GetOutputParameterDesc Stream failed, got %u, expected %u\n", + i, desc.Stream, pdesc->ReadWriteMask); + + count = ref11->lpVtbl->Release(ref11); + ok(count == 0, "(%u): Release failed %u\n", i, count); + } +} + +/* + * fxc.exe /E PS /Tps_4_0 /Fx + */ +#if 0 +Texture2D tex1; +SamplerState sam +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Wrap; + AddressV = Wrap; +}; +cbuffer c1 +{ + float x; + float y[2]; + int z; +}; +cbuffer c2 +{ + float t; +}; + +float4 PS(float2 uv : TEXCOORD0) : sv_target +{ + float4 q = tex1.Sample(sam, uv); + q.x = q.x + x; + q.w = q.w + y[0] + y[1] + t; + return q; +} +#endif +static DWORD test_reflection_bound_resources_blob[] = { +0x43425844, 0xe4af0279, 0x690268fc, 0x76bf6a72, 0xe5aff43b, 0x00000001, 0x000003f4, 0x00000005, +0x00000034, 0x000001e8, 0x0000021c, 0x00000250, 0x00000378, 0x46454452, 0x000001ac, 0x00000002, +0x000000ac, 0x00000004, 0x0000001c, 0xffff0400, 0x00000100, 0x0000017a, 0x0000009c, 0x00000003, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x000000a0, 0x00000002, +0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000c, 0x000000a5, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x000000a8, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x006d6173, 0x31786574, +0x00316300, 0xab003263, 0x000000a5, 0x00000003, 0x000000dc, 0x00000030, 0x00000000, 0x00000000, +0x000000a8, 0x00000001, 0x00000160, 0x00000010, 0x00000000, 0x00000000, 0x00000124, 0x00000000, +0x00000004, 0x00000002, 0x00000128, 0x00000000, 0x00000138, 0x00000010, 0x00000014, 0x00000002, +0x0000013c, 0x00000000, 0x0000014c, 0x00000024, 0x00000004, 0x00000000, 0x00000150, 0x00000000, +0xabab0078, 0x00030000, 0x00010001, 0x00000000, 0x00000000, 0xabab0079, 0x00030000, 0x00010001, +0x00000002, 0x00000000, 0xabab007a, 0x00020000, 0x00010001, 0x00000000, 0x00000000, 0x00000178, +0x00000000, 0x00000004, 0x00000002, 0x00000128, 0x00000000, 0x694d0074, 0x736f7263, 0x2074666f, +0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, 0x72656c69, 0x322e3920, 0x35392e39, +0x31332e32, 0xab003131, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, +0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, +0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, +0x0000000f, 0x745f7673, 0x65677261, 0xabab0074, 0x52444853, 0x00000120, 0x00000040, 0x00000048, +0x04000059, 0x00208e46, 0x00000000, 0x00000003, 0x04000059, 0x00208e46, 0x00000001, 0x00000001, +0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, +0x00101032, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, +0x001000f2, 0x00000000, 0x00101046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, +0x08000000, 0x00100082, 0x00000000, 0x0010003a, 0x00000000, 0x0020800a, 0x00000000, 0x00000001, +0x08000000, 0x00100082, 0x00000000, 0x0010003a, 0x00000000, 0x0020800a, 0x00000000, 0x00000002, +0x08000000, 0x00102082, 0x00000000, 0x0010003a, 0x00000000, 0x0020800a, 0x00000001, 0x00000000, +0x08000000, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, +0x05000036, 0x00102062, 0x00000000, 0x00100656, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, +0x00000007, 0x00000001, 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000000, 0x00000001, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const D3D11_SHADER_INPUT_BIND_DESC test_reflection_bound_resources_result[] = +{ + {"sam", D3D_SIT_SAMPLER, 0, 1, 0, 0, D3D_SRV_DIMENSION_UNKNOWN, 0}, + {"tex1", D3D_SIT_TEXTURE, 0, 1, 12, D3D_RETURN_TYPE_FLOAT, D3D_SRV_DIMENSION_TEXTURE2D, 0xffffffff}, + {"c1", D3D_SIT_CBUFFER, 0, 1, 0, 0, D3D_SRV_DIMENSION_UNKNOWN, 0}, + {"c2", D3D_SIT_CBUFFER, 1, 1, 0, 0, D3D_SRV_DIMENSION_UNKNOWN, 0}, +}; + +static void test_reflection_bound_resources(void) +{ + HRESULT hr; + ULONG count; + ID3D11ShaderReflection *ref11; + D3D11_SHADER_INPUT_BIND_DESC desc; + const D3D11_SHADER_INPUT_BIND_DESC *pdesc; + unsigned int i; + + hr = pD3DReflect(test_reflection_bound_resources_blob, test_reflection_bound_resources_blob[6], &IID_ID3D11ShaderReflection, (void **)&ref11); + ok(hr == S_OK, "D3DReflect failed %x\n", hr); + + /* check invalid cases */ + hr = ref11->lpVtbl->GetResourceBindingDesc(ref11, 0, NULL); + ok(hr == E_INVALIDARG, "GetResourceBindingDesc failed, got %x, expected %x\n", hr, E_INVALIDARG); + + hr = ref11->lpVtbl->GetResourceBindingDesc(ref11, 0xffffffff, &desc); + ok(hr == E_INVALIDARG, "GetResourceBindingDesc failed, got %x, expected %x\n", hr, E_INVALIDARG); + + hr = ref11->lpVtbl->GetResourceBindingDescByName(ref11, NULL, &desc); + ok(hr == E_INVALIDARG, "GetResourceBindingDescByName failed, got %x, expected %x\n", hr, E_INVALIDARG); + + hr = ref11->lpVtbl->GetResourceBindingDescByName(ref11, "sam", NULL); + ok(hr == E_INVALIDARG, "GetResourceBindingDescByName failed, got %x, expected %x\n", hr, E_INVALIDARG); + + hr = ref11->lpVtbl->GetResourceBindingDescByName(ref11, "invalid", NULL); + ok(hr == E_INVALIDARG, "GetResourceBindingDescByName failed, got %x, expected %x\n", hr, E_INVALIDARG); + + hr = ref11->lpVtbl->GetResourceBindingDescByName(ref11, "invalid", &desc); + ok(hr == E_INVALIDARG, "GetResourceBindingDescByName failed, got %x, expected %x\n", hr, E_INVALIDARG); + + /* GetResourceBindingDesc */ + for (i = 0; i < ARRAY_SIZE(test_reflection_bound_resources_result); ++i) + { + pdesc = &test_reflection_bound_resources_result[i]; + + hr = ref11->lpVtbl->GetResourceBindingDesc(ref11, i, &desc); + ok(hr == S_OK, "GetResourceBindingDesc(%u) failed, got %x, expected %x\n", i, hr, S_OK); + + ok(!strcmp(desc.Name, pdesc->Name), "GetResourceBindingDesc(%u) Name failed, got \"%s\", expected \"%s\"\n", + i, desc.Name, pdesc->Name); + ok(desc.Type == pdesc->Type, "GetResourceBindingDesc(%u) Type failed, got %x, expected %x\n", + i, desc.Type, pdesc->Type); + ok(desc.BindPoint == pdesc->BindPoint, "GetResourceBindingDesc(%u) BindPoint failed, got %u, expected %u\n", + i, desc.BindPoint, pdesc->BindPoint); + ok(desc.BindCount == pdesc->BindCount, "GetResourceBindingDesc(%u) BindCount failed, got %u, expected %u\n", + i, desc.BindCount, pdesc->BindCount); + ok(desc.uFlags == pdesc->uFlags, "GetResourceBindingDesc(%u) uFlags failed, got %u, expected %u\n", + i, desc.uFlags, pdesc->uFlags); + ok(desc.ReturnType == pdesc->ReturnType, "GetResourceBindingDesc(%u) ReturnType failed, got %x, expected %x\n", + i, desc.ReturnType, pdesc->ReturnType); + ok(desc.Dimension == pdesc->Dimension, "GetResourceBindingDesc(%u) Dimension failed, got %x, expected %x\n", + i, desc.Dimension, pdesc->Dimension); + ok(desc.NumSamples == pdesc->NumSamples, "GetResourceBindingDesc(%u) NumSamples failed, got %u, expected %u\n", + i, desc.NumSamples, pdesc->NumSamples); + } + + /* GetResourceBindingDescByName */ + for (i = 0; i < ARRAY_SIZE(test_reflection_bound_resources_result); ++i) + { + pdesc = &test_reflection_bound_resources_result[i]; + + hr = ref11->lpVtbl->GetResourceBindingDescByName(ref11, pdesc->Name, &desc); + ok(hr == S_OK, "GetResourceBindingDescByName(%u) failed, got %x, expected %x\n", i, hr, S_OK); + + ok(!strcmp(desc.Name, pdesc->Name), "GetResourceBindingDescByName(%u) Name failed, got \"%s\", expected \"%s\"\n", + i, desc.Name, pdesc->Name); + ok(desc.Type == pdesc->Type, "GetResourceBindingDescByName(%u) Type failed, got %x, expected %x\n", + i, desc.Type, pdesc->Type); + ok(desc.BindPoint == pdesc->BindPoint, "GetResourceBindingDescByName(%u) BindPoint failed, got %u, expected %u\n", + i, desc.BindPoint, pdesc->BindPoint); + ok(desc.BindCount == pdesc->BindCount, "GetResourceBindingDescByName(%u) BindCount failed, got %u, expected %u\n", + i, desc.BindCount, pdesc->BindCount); + ok(desc.uFlags == pdesc->uFlags, "GetResourceBindingDescByName(%u) uFlags failed, got %u, expected %u\n", + i, desc.uFlags, pdesc->uFlags); + ok(desc.ReturnType == pdesc->ReturnType, "GetResourceBindingDescByName(%u) ReturnType failed, got %x, expected %x\n", + i, desc.ReturnType, pdesc->ReturnType); + ok(desc.Dimension == pdesc->Dimension, "GetResourceBindingDescByName(%u) Dimension failed, got %x, expected %x\n", + i, desc.Dimension, pdesc->Dimension); + ok(desc.NumSamples == pdesc->NumSamples, "GetResourceBindingDescByName(%u) NumSamples failed, got %u, expected %u\n", + i, desc.NumSamples, pdesc->NumSamples); + } + + count = ref11->lpVtbl->Release(ref11); + ok(count == 0, "Release failed %u\n", count); +} + +/* + * fxc.exe /E PS /Tps_5_0 /Fx + */ +#if 0 +cbuffer c1 +{ + float a; + float b[2]; + int i; + struct s { + float a; + float b; + } t; +}; + +interface iTest +{ + float4 test(float2 vec); +}; + +class cTest : iTest +{ + bool m_on; + float4 test(float2 vec); +}; + +float4 cTest::test(float2 vec) +{ + float4 res; + if(m_on) + res = float4(vec.x, vec.y, vec.x+vec.y, 0); + else + res = 0; + return res; +} + +iTest g_Test; + + +float4 PS(float2 uv : TEXCOORD0) : sv_target +{ + float4 q = g_Test.test(uv); + q.x = q.x + t.a; + return q; +} +#endif +static DWORD test_reflection_constant_buffer_blob[] = { +0x43425844, 0xe6470e0d, 0x0d5698bb, 0x29373c30, 0x64a5d268, 0x00000001, 0x00000590, 0x00000006, +0x00000038, 0x00000318, 0x0000034c, 0x00000380, 0x000003d8, 0x000004f4, 0x46454452, 0x000002d8, +0x00000002, 0x00000060, 0x00000001, 0x0000003c, 0xffff0500, 0x00000100, 0x000002a4, 0x31314452, +0x0000003c, 0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000001, 0x0000005c, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0xab003163, +0x00000090, 0x00000001, 0x000000a0, 0x00000010, 0x00000000, 0x00000002, 0x0000005c, 0x00000004, +0x00000120, 0x00000040, 0x00000000, 0x00000000, 0x69685424, 0x696f5073, 0x7265746e, 0xababab00, +0x000000c8, 0x00000000, 0x00000001, 0x00000006, 0x000000fc, 0x00000000, 0xffffffff, 0x00000000, +0xffffffff, 0x00000000, 0x65545f67, 0x69007473, 0x74736554, 0xababab00, 0x00000006, 0x00000001, +0x00000000, 0x000000d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000cf, 0x00250007, +0x00040001, 0x00000000, 0x00000000, 0x000000d8, 0x00000000, 0x00000000, 0x00000000, 0x000000cf, +0x000001c0, 0x00000000, 0x00000004, 0x00000000, 0x000001c8, 0x00000000, 0xffffffff, 0x00000000, +0xffffffff, 0x00000000, 0x000001ec, 0x00000010, 0x00000014, 0x00000000, 0x000001f0, 0x00000000, +0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0x00000214, 0x00000024, 0x00000004, 0x00000000, +0x0000021c, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0x00000240, 0x00000030, +0x00000008, 0x00000002, 0x00000280, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, +0x6c660061, 0x0074616f, 0x00030000, 0x00010001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x000001c2, 0xabab0062, 0x00030000, 0x00010001, 0x00000002, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000001c2, 0x6e690069, 0xabab0074, 0x00020000, +0x00010001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000216, +0x00730074, 0x00030000, 0x00010001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x000001c2, 0x000001c0, 0x00000244, 0x00000000, 0x000001ec, 0x00000244, 0x00000004, +0x00000005, 0x00020001, 0x00020000, 0x00000268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000242, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, +0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00, 0x4e475349, 0x0000002c, +0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, +0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, +0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x745f7673, 0x65677261, 0xabab0074, +0x45434649, 0x00000050, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000040, 0x00000034, +0x00000024, 0x00000000, 0x4e47534f, 0x00000001, 0x00000001, 0x00000040, 0x00000044, 0x00000048, +0x00010000, 0x00000000, 0xabab0000, 0x00000000, 0x73655463, 0xabab0074, 0x58454853, 0x00000114, +0x00000050, 0x00000045, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, 0x03000091, +0x00000000, 0x00000000, 0x05000092, 0x00000000, 0x00000000, 0x00010001, 0x00000000, 0x03001062, +0x00101032, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x07000000, +0x00100042, 0x00000000, 0x0010101a, 0x00000000, 0x0010100a, 0x00000000, 0x05000036, 0x00100032, +0x00000000, 0x00101046, 0x00000000, 0x05000036, 0x00100082, 0x00000000, 0x00004001, 0x00000000, +0x05000036, 0x00100032, 0x00000001, 0x0011d516, 0x00000000, 0x0a000001, 0x001000f2, 0x00000000, +0x00100e46, 0x00000000, 0x04a08006, 0x0010001a, 0x00000001, 0x0010000a, 0x00000001, 0x08000000, +0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x0020800a, 0x00000000, 0x00000003, 0x05000036, +0x001020e2, 0x00000000, 0x00100e56, 0x00000000, 0x0100003e, 0x54415453, 0x00000094, 0x00000008, +0x00000002, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000001, 0x00000001, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const D3D11_SHADER_BUFFER_DESC test_reflection_constant_buffer_cb_result[] = +{ + {"$ThisPointer", D3D_CT_INTERFACE_POINTERS, 1, 16, 0}, + {"c1", D3D_CT_CBUFFER, 4, 64, 0}, +}; + +static const struct { + D3D11_SHADER_VARIABLE_DESC desc; + unsigned int type; +} test_reflection_constant_buffer_variable_result[] = +{ + {{"g_Test", 0, 1, 6, 0}, 0}, + {{"a", 0, 4, 0, 0}, 1}, + {{"b", 16, 20, 0, 0}, 2}, + {{"i", 36, 4, 0, 0}, 3}, + {{"t", 48, 8, 2, 0}, 4}, +}; + +static const D3D11_SHADER_TYPE_DESC test_reflection_constant_buffer_type_result[] = +{ + {D3D11_SVC_INTERFACE_POINTER, D3D11_SVT_INTERFACE_POINTER, 1, 4, 0, 1, 0, "iTest"}, + {D3D_SVC_SCALAR, D3D_SVT_FLOAT, 1, 1, 0, 1, 0, "float"}, + {D3D_SVC_SCALAR, D3D_SVT_FLOAT, 1, 1, 2, 1, 0, "float"}, + {D3D_SVC_SCALAR, D3D_SVT_INT, 1, 1, 0, 1, 0, "int"}, + {D3D_SVC_STRUCT, D3D_SVT_VOID, 1, 2, 0, 1, 0, "s"}, +}; + +static void test_reflection_constant_buffer(void) +{ + HRESULT hr; + ULONG count; + ID3D11ShaderReflection *ref11; + ID3D11ShaderReflectionConstantBuffer *cb11, *cb11_dummy = NULL, *cb11_valid = NULL; + ID3D11ShaderReflectionVariable *v11, *v11_dummy = NULL, *v11_valid = NULL; + ID3D11ShaderReflectionType *t11, *t, *t2, *t11_dummy = NULL, *t11_valid = NULL; + D3D11_SHADER_BUFFER_DESC cbdesc = {0}; + D3D11_SHADER_VARIABLE_DESC vdesc = {0}; + D3D11_SHADER_TYPE_DESC tdesc = {0}; + D3D11_SHADER_DESC sdesc = {0}; + const D3D11_SHADER_BUFFER_DESC *pcbdesc; + const D3D11_SHADER_VARIABLE_DESC *pvdesc; + const D3D11_SHADER_TYPE_DESC *ptdesc; + unsigned int i; + LPCSTR string; + + hr = pD3DReflect(test_reflection_constant_buffer_blob, test_reflection_constant_buffer_blob[6], &IID_ID3D11ShaderReflection, (void **)&ref11); + ok(hr == S_OK, "D3DReflect failed %x\n", hr); + + hr = ref11->lpVtbl->GetDesc(ref11, &sdesc); + ok(hr == S_OK, "GetDesc failed %x\n", hr); + + ok(sdesc.Version == 80, "GetDesc failed, got %u, expected %u\n", sdesc.Version, 80); + ok(strcmp(sdesc.Creator, (char*) shader_creator) == 0, "GetDesc failed, got \"%s\", expected \"%s\"\n", sdesc.Creator, (char*)shader_creator); + ok(sdesc.Flags == 256, "GetDesc failed, got %u, expected %u\n", sdesc.Flags, 256); + ok(sdesc.ConstantBuffers == 2, "GetDesc failed, got %u, expected %u\n", sdesc.ConstantBuffers, 2); + ok(sdesc.BoundResources == 1, "GetDesc failed, got %u, expected %u\n", sdesc.BoundResources, 1); + ok(sdesc.InputParameters == 1, "GetDesc failed, got %u, expected %u\n", sdesc.InputParameters, 1); + ok(sdesc.OutputParameters == 1, "GetDesc failed, got %u, expected %u\n", sdesc.OutputParameters, 1); + ok(sdesc.InstructionCount == 8, "GetDesc failed, got %u, expected %u\n", sdesc.InstructionCount, 8); + ok(sdesc.TempRegisterCount == 2, "GetDesc failed, got %u, expected %u\n", sdesc.TempRegisterCount, 2); + ok(sdesc.TempArrayCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc.TempArrayCount, 0); + ok(sdesc.DefCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc.DefCount, 0); + ok(sdesc.DclCount == 2, "GetDesc failed, got %u, expected %u\n", sdesc.DclCount, 2); + ok(sdesc.TextureNormalInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc.TextureNormalInstructions, 0); + ok(sdesc.TextureLoadInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc.TextureLoadInstructions, 0); + ok(sdesc.TextureCompInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc.TextureCompInstructions, 0); + ok(sdesc.TextureBiasInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc.TextureBiasInstructions, 0); + ok(sdesc.TextureGradientInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc.TextureGradientInstructions, 0); + ok(sdesc.FloatInstructionCount == 2, "GetDesc failed, got %u, expected %u\n", sdesc.FloatInstructionCount, 2); + ok(sdesc.IntInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc.IntInstructionCount, 0); + ok(sdesc.UintInstructionCount == 1, "GetDesc failed, got %u, expected %u\n", sdesc.UintInstructionCount, 1); + ok(sdesc.StaticFlowControlCount == 1, "GetDesc failed, got %u, expected %u\n", sdesc.StaticFlowControlCount, 1); + ok(sdesc.DynamicFlowControlCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc.DynamicFlowControlCount, 0); + ok(sdesc.MacroInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc.MacroInstructionCount, 0); + ok(sdesc.ArrayInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc.ArrayInstructionCount, 0); + ok(sdesc.CutInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc.CutInstructionCount, 0); + ok(sdesc.EmitInstructionCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc.EmitInstructionCount, 0); + ok(sdesc.GSOutputTopology == 0, "GetDesc failed, got %x, expected %x\n", sdesc.GSOutputTopology, 0); + ok(sdesc.GSMaxOutputVertexCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc.GSMaxOutputVertexCount, 0); + ok(sdesc.InputPrimitive == 0, "GetDesc failed, got %x, expected %x\n", sdesc.InputPrimitive, 0); + ok(sdesc.PatchConstantParameters == 0, "GetDesc failed, got %u, expected %u\n", sdesc.PatchConstantParameters, 0); + ok(sdesc.cGSInstanceCount == 0, "GetDesc failed, got %u, expected %u\n", sdesc.cGSInstanceCount, 0); + ok(sdesc.cControlPoints == 0, "GetDesc failed, got %u, expected %u\n", sdesc.cControlPoints, 0); + ok(sdesc.HSOutputPrimitive == 0, "GetDesc failed, got %x, expected %x\n", sdesc.HSOutputPrimitive, 0); + ok(sdesc.HSPartitioning == 0, "GetDesc failed, got %x, expected %x\n", sdesc.HSPartitioning, 0); + ok(sdesc.TessellatorDomain == 0, "GetDesc failed, got %x, expected %x\n", sdesc.TessellatorDomain, 0); + ok(sdesc.cBarrierInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc.cBarrierInstructions, 0); + ok(sdesc.cInterlockedInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc.cInterlockedInstructions, 0); + ok(sdesc.cTextureStoreInstructions == 0, "GetDesc failed, got %u, expected %u\n", sdesc.cTextureStoreInstructions, 0); + + /* get the dummys for comparison */ + cb11_dummy = ref11->lpVtbl->GetConstantBufferByIndex(ref11, 0xffffffff); + ok(cb11_dummy != NULL, "GetConstantBufferByIndex failed\n"); + + v11_dummy = cb11_dummy->lpVtbl->GetVariableByIndex(cb11_dummy, 0xffffffff); + ok(v11_dummy != NULL, "GetVariableByIndex failed\n"); + + t11_dummy = v11_dummy->lpVtbl->GetType(v11_dummy); + ok(t11_dummy != NULL, "GetType failed\n"); + + /* get the valid variables */ + cb11_valid = ref11->lpVtbl->GetConstantBufferByIndex(ref11, 1); + ok(cb11_valid != cb11_dummy && cb11_valid, "GetConstantBufferByIndex failed\n"); + + v11_valid = cb11_valid->lpVtbl->GetVariableByIndex(cb11_valid, 0); + ok(v11_valid != v11_dummy && v11_valid, "GetVariableByIndex failed\n"); + + t11_valid = v11_valid->lpVtbl->GetType(v11_valid); + ok(t11_valid != t11_dummy && t11_valid, "GetType failed\n"); + + /* reflection calls */ + cb11 = ref11->lpVtbl->GetConstantBufferByName(ref11, "invalid"); + ok(cb11_dummy == cb11, "GetConstantBufferByName failed, got %p, expected %p\n", cb11, cb11_dummy); + + cb11 = ref11->lpVtbl->GetConstantBufferByName(ref11, NULL); + ok(cb11_dummy == cb11, "GetConstantBufferByName failed, got %p, expected %p\n", cb11, cb11_dummy); + + v11 = ref11->lpVtbl->GetVariableByName(ref11, NULL); + ok(v11_dummy == v11, "GetVariableByIndex failed, got %p, expected %p\n", v11, v11_dummy); + + v11 = ref11->lpVtbl->GetVariableByName(ref11, "invalid"); + ok(v11_dummy == v11, "GetVariableByName failed, got %p, expected %p\n", v11, v11_dummy); + + v11 = ref11->lpVtbl->GetVariableByName(ref11, "a"); + ok(v11_valid == v11, "GetVariableByName failed, got %p, expected %p\n", v11, v11_valid); + + /* constant buffer calls */ + v11 = cb11_dummy->lpVtbl->GetVariableByName(cb11_dummy, NULL); + ok(v11_dummy == v11, "GetVariableByName failed, got %p, expected %p\n", v11, v11_dummy); + + v11 = cb11_dummy->lpVtbl->GetVariableByName(cb11_dummy, "invalid"); + ok(v11_dummy == v11, "GetVariableByName failed, got %p, expected %p\n", v11, v11_dummy); + + v11 = cb11_valid->lpVtbl->GetVariableByName(cb11_valid, NULL); + ok(v11_dummy == v11, "GetVariableByName failed, got %p, expected %p\n", v11, v11_dummy); + + v11 = cb11_valid->lpVtbl->GetVariableByName(cb11_valid, "invalid"); + ok(v11_dummy == v11, "GetVariableByName failed, got %p, expected %p\n", v11, v11_dummy); + + v11 = cb11_valid->lpVtbl->GetVariableByName(cb11_valid, "a"); + ok(v11_valid == v11, "GetVariableByName failed, got %p, expected %p\n", v11, v11_valid); + + hr = cb11_dummy->lpVtbl->GetDesc(cb11_dummy, NULL); + ok(hr == E_FAIL, "GetDesc failed, got %x, expected %x\n", hr, E_FAIL); + + hr = cb11_dummy->lpVtbl->GetDesc(cb11_dummy, &cbdesc); + ok(hr == E_FAIL, "GetDesc failed, got %x, expected %x\n", hr, E_FAIL); + + hr = cb11_valid->lpVtbl->GetDesc(cb11_valid, NULL); + ok(hr == E_FAIL, "GetDesc failed, got %x, expected %x\n", hr, E_FAIL); + + /* variable calls */ + hr = v11_dummy->lpVtbl->GetDesc(v11_dummy, NULL); + ok(hr == E_FAIL, "GetDesc failed, got %x, expected %x\n", hr, E_FAIL); + + hr = v11_dummy->lpVtbl->GetDesc(v11_dummy, &vdesc); + ok(hr == E_FAIL, "GetDesc failed, got %x, expected %x\n", hr, E_FAIL); + + hr = v11_valid->lpVtbl->GetDesc(v11_valid, NULL); + ok(hr == E_FAIL, "GetDesc failed, got %x, expected %x\n", hr, E_FAIL); + + /* type calls */ + hr = t11_dummy->lpVtbl->GetDesc(t11_dummy, NULL); + ok(hr == E_FAIL, "GetDesc failed, got %x, expected %x\n", hr, E_FAIL); + + hr = t11_dummy->lpVtbl->GetDesc(t11_dummy, &tdesc); + ok(hr == E_FAIL, "GetDesc failed, got %x, expected %x\n", hr, E_FAIL); + + hr = t11_valid->lpVtbl->GetDesc(t11_valid, NULL); + ok(hr == E_FAIL, "GetDesc failed, got %x, expected %x\n", hr, E_FAIL); + + string = t11_dummy->lpVtbl->GetMemberTypeName(t11_dummy, 0xffffffff); + ok(!strcmp(string, "$Invalid"), "GetMemberTypeName failed, got \"%s\", expected \"%s\"\n", string, "$Invalid"); + + string = t11_valid->lpVtbl->GetMemberTypeName(t11_valid, 0xffffffff); + ok(!string, "GetMemberTypeName failed, got \"%s\", expected NULL\n", string); + + t11 = t11_dummy->lpVtbl->GetMemberTypeByIndex(t11_dummy, 0xffffffff); + ok(t11_dummy == t11, "GetMemberTypeByIndex failed, got %p, expected %p\n", t11, t11_dummy); + + t11 = t11_valid->lpVtbl->GetMemberTypeByIndex(t11_valid, 0xffffffff); + ok(t11_dummy == t11, "GetMemberTypeByIndex failed, got %p, expected %p\n", t11, t11_dummy); + + t11 = t11_dummy->lpVtbl->GetMemberTypeByName(t11_dummy, NULL); + ok(t11_dummy == t11, "GetMemberTypeByName failed, got %p, expected %p\n", t11, t11_dummy); + + t11 = t11_dummy->lpVtbl->GetMemberTypeByName(t11_dummy, "invalid"); + ok(t11_dummy == t11, "GetMemberTypeByName failed, got %p, expected %p\n", t11, t11_dummy); + + t11 = t11_valid->lpVtbl->GetMemberTypeByName(t11_valid, NULL); + ok(t11_dummy == t11, "GetMemberTypeByName failed, got %p, expected %p\n", t11, t11_dummy); + + t11 = t11_valid->lpVtbl->GetMemberTypeByName(t11_valid, "invalid"); + ok(t11_dummy == t11, "GetMemberTypeByName failed, got %p, expected %p\n", t11, t11_dummy); + + hr = t11_dummy->lpVtbl->IsEqual(t11_dummy, t11_dummy); + ok(hr == E_FAIL, "IsEqual failed, got %x, expected %x\n", hr, E_FAIL); + + hr = t11_valid->lpVtbl->IsEqual(t11_valid, t11_dummy); + ok(hr == S_FALSE, "IsEqual failed, got %x, expected %x\n", hr, S_FALSE); + + hr = t11_dummy->lpVtbl->IsEqual(t11_dummy, t11_valid); + ok(hr == E_FAIL, "IsEqual failed, got %x, expected %x\n", hr, E_FAIL); + + hr = t11_valid->lpVtbl->IsEqual(t11_valid, t11_valid); + ok(hr == S_OK, "IsEqual failed, got %x, expected %x\n", hr, S_OK); + + /* constant buffers */ + for (i = 0; i < ARRAY_SIZE(test_reflection_constant_buffer_cb_result); ++i) + { + pcbdesc = &test_reflection_constant_buffer_cb_result[i]; + + cb11 = ref11->lpVtbl->GetConstantBufferByIndex(ref11, i); + ok(cb11_dummy != cb11, "GetConstantBufferByIndex(%u) failed\n", i); + + hr = cb11->lpVtbl->GetDesc(cb11, &cbdesc); + ok(hr == S_OK, "GetDesc(%u) failed, got %x, expected %x\n", i, hr, S_OK); + + ok(!strcmp(cbdesc.Name, pcbdesc->Name), "GetDesc(%u) Name failed, got \"%s\", expected \"%s\"\n", + i, cbdesc.Name, pcbdesc->Name); + ok(cbdesc.Type == pcbdesc->Type, "GetDesc(%u) Type failed, got %x, expected %x\n", + i, cbdesc.Type, pcbdesc->Type); + ok(cbdesc.Variables == pcbdesc->Variables, "GetDesc(%u) Variables failed, got %u, expected %u\n", + i, cbdesc.Variables, pcbdesc->Variables); + ok(cbdesc.Size == pcbdesc->Size, "GetDesc(%u) Size failed, got %u, expected %u\n", + i, cbdesc.Size, pcbdesc->Size); + ok(cbdesc.uFlags == pcbdesc->uFlags, "GetDesc(%u) uFlags failed, got %u, expected %u\n", + i, cbdesc.uFlags, pcbdesc->uFlags); + } + + /* variables */ + for (i = 0; i < ARRAY_SIZE(test_reflection_constant_buffer_variable_result); ++i) + { + pvdesc = &test_reflection_constant_buffer_variable_result[i].desc; + + v11 = ref11->lpVtbl->GetVariableByName(ref11, pvdesc->Name); + ok(v11_dummy != v11, "GetVariableByName(%u) failed\n", i); + + hr = v11->lpVtbl->GetDesc(v11, &vdesc); + ok(hr == S_OK, "GetDesc(%u) failed, got %x, expected %x\n", i, hr, S_OK); + + ok(!strcmp(vdesc.Name, pvdesc->Name), "GetDesc(%u) Name failed, got \"%s\", expected \"%s\"\n", + i, vdesc.Name, pvdesc->Name); + ok(vdesc.StartOffset == pvdesc->StartOffset, "GetDesc(%u) StartOffset failed, got %u, expected %u\n", + i, vdesc.StartOffset, pvdesc->StartOffset); + ok(vdesc.Size == pvdesc->Size, "GetDesc(%u) Size failed, got %u, expected %u\n", + i, vdesc.Size, pvdesc->Size); + ok(vdesc.uFlags == pvdesc->uFlags, "GetDesc(%u) uFlags failed, got %u, expected %u\n", + i, vdesc.uFlags, pvdesc->uFlags); + ok(vdesc.DefaultValue == pvdesc->DefaultValue, "GetDesc(%u) DefaultValue failed\n", i); + + /* types */ + ptdesc = &test_reflection_constant_buffer_type_result[test_reflection_constant_buffer_variable_result[i].type]; + + t11 = v11->lpVtbl->GetType(v11); + ok(t11_dummy != t11, "GetType(%u) failed\n", i); + + hr = t11->lpVtbl->GetDesc(t11, &tdesc); + ok(hr == S_OK, "GetDesc(%u) failed, got %x, expected %x\n", i, hr, S_OK); + + ok(tdesc.Class == ptdesc->Class, "GetDesc(%u) Class failed, got %x, expected %x\n", + i, tdesc.Class, ptdesc->Class); + ok(tdesc.Type == ptdesc->Type, "GetDesc(%u) Type failed, got %x, expected %x\n", + i, tdesc.Type, ptdesc->Type); + ok(tdesc.Rows == ptdesc->Rows, "GetDesc(%u) Rows failed, got %x, expected %x\n", + i, tdesc.Rows, ptdesc->Rows); + ok(tdesc.Columns == ptdesc->Columns, "GetDesc(%u) Columns failed, got %u, expected %u\n", + i, tdesc.Columns, ptdesc->Columns); + ok(tdesc.Elements == ptdesc->Elements, "GetDesc(%u) Elements failed, got %u, expected %u\n", + i, tdesc.Elements, ptdesc->Elements); + ok(tdesc.Offset == ptdesc->Offset, "GetDesc(%u) Offset failed, got %u, expected %u\n", + i, tdesc.Offset, ptdesc->Offset); + ok(!strcmp(tdesc.Name, ptdesc->Name), "GetDesc(%u) Name failed, got %s, expected %s\n", + i, tdesc.Name, ptdesc->Name); + } + + /* types */ + v11 = ref11->lpVtbl->GetVariableByName(ref11, "t"); + ok(v11_dummy != v11, "GetVariableByName failed\n"); + + t11 = v11->lpVtbl->GetType(v11); + ok(t11 != t11_dummy, "GetType failed\n"); + + t = t11->lpVtbl->GetMemberTypeByIndex(t11, 0); + ok(t != t11_dummy, "GetMemberTypeByIndex failed\n"); + + t2 = t11->lpVtbl->GetMemberTypeByName(t11, "a"); + ok(t == t2, "GetMemberTypeByName failed, got %p, expected %p\n", t2, t); + + string = t11->lpVtbl->GetMemberTypeName(t11, 0); + ok(!strcmp(string, "a"), "GetMemberTypeName failed, got \"%s\", expected \"%s\"\n", string, "a"); + + t = t11->lpVtbl->GetMemberTypeByIndex(t11, 1); + ok(t != t11_dummy, "GetMemberTypeByIndex failed\n"); + + t2 = t11->lpVtbl->GetMemberTypeByName(t11, "b"); + ok(t == t2, "GetMemberTypeByName failed, got %p, expected %p\n", t2, t); + + string = t11->lpVtbl->GetMemberTypeName(t11, 1); + ok(!strcmp(string, "b"), "GetMemberTypeName failed, got \"%s\", expected \"%s\"\n", string, "b"); + + /* float vs float (in struct) */ + hr = t11->lpVtbl->IsEqual(t11, t11_valid); + ok(hr == S_FALSE, "IsEqual failed, got %x, expected %x\n", hr, S_FALSE); + + hr = t11_valid->lpVtbl->IsEqual(t11_valid, t11); + ok(hr == S_FALSE, "IsEqual failed, got %x, expected %x\n", hr, S_FALSE); + + /* float vs float */ + t = t11->lpVtbl->GetMemberTypeByIndex(t11, 0); + ok(t != t11_dummy, "GetMemberTypeByIndex failed\n"); + + t2 = t11->lpVtbl->GetMemberTypeByIndex(t11, 1); + ok(t2 != t11_dummy, "GetMemberTypeByIndex failed\n"); + + hr = t->lpVtbl->IsEqual(t, t2); + ok(hr == S_OK, "IsEqual failed, got %x, expected %x\n", hr, S_OK); + + count = ref11->lpVtbl->Release(ref11); + ok(count == 0, "Release failed %u\n", count); +} + +static BOOL load_d3dcompiler(void) +{ + HMODULE module; + + if (!(module = LoadLibraryA("d3dcompiler_43.dll"))) return FALSE; + + pD3DReflect = (void*)GetProcAddress(module, "D3DReflect"); + return TRUE; +} + +START_TEST(reflection) +{ + if (!load_d3dcompiler()) + { + win_skip("Could not load d3dcompiler_43.dll\n"); + return; + } + +#ifndef __REACTOS__ + test_reflection_references(); +#endif + test_reflection_desc_vs(); + test_reflection_desc_ps(); + test_reflection_desc_ps_output(); + test_reflection_bound_resources(); + test_reflection_constant_buffer(); +} diff --git a/modules/rostests/winetests/d3dcompiler_43/testlist.c b/modules/rostests/winetests/d3dcompiler_43/testlist.c new file mode 100644 index 00000000000..9177e7f96e0 --- /dev/null +++ b/modules/rostests/winetests/d3dcompiler_43/testlist.c @@ -0,0 +1,18 @@ +/* Automatically generated by make depend; DO NOT EDIT!! */ + +#define STANDALONE +#include <wine/test.h> + +extern void func_asm(void); +extern void func_blob(void); +extern void func_hlsl(void); +extern void func_reflection(void); + +const struct test winetest_testlist[] = +{ + { "asm", func_asm }, + { "blob", func_blob }, + { "hlsl", func_hlsl }, + { "reflection", func_reflection }, + { 0, 0 } +};
5 years, 1 month
1
0
0
0
← Newer
1
2
3
4
5
6
7
8
9
...
18
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Results per page:
10
25
50
100
200