Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2021
- 83 participants
- 2620 messages
[PATCH 2/7] dinput8/tests: Add older dinput HID force-feedback tests.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/dinput8/tests/Makefile.in | 2 +-
dlls/dinput8/tests/hid.c | 360 ++++++++++++++++++++++++---------
2 files changed, 262 insertions(+), 100 deletions(-)
diff --git a/dlls/dinput8/tests/Makefile.in b/dlls/dinput8/tests/Makefile.in
index 579cf3d2f4b..18624b9d523 100644
--- a/dlls/dinput8/tests/Makefile.in
+++ b/dlls/dinput8/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = dinput8.dll
-IMPORTS = dinput8 ole32 user32 hid advapi32 uuid crypt32 newdev setupapi wintrust
+IMPORTS = dinput8 dinput ole32 user32 hid advapi32 uuid crypt32 newdev setupapi wintrust
driver_hid_IMPORTS = winecrt0 ntoskrnl hal hidclass
driver_hid_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index 57fc7272369..59111db7f3a 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -3321,18 +3321,37 @@ static BOOL CALLBACK find_test_device( const DIDEVICEINSTANCEW *devinst, void *c
return DIENUM_CONTINUE;
}
+struct check_objects_todos
+{
+ BOOL type;
+ BOOL guid;
+ BOOL usage;
+};
+
struct check_objects_params
{
+ DWORD version;
UINT index;
UINT expect_count;
const DIDEVICEOBJECTINSTANCEW *expect_objs;
+ const struct check_objects_todos *todo_objs;
+ BOOL todo_extra;
};
static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *args )
{
static const DIDEVICEOBJECTINSTANCEW unexpected_obj = {0};
+ static const struct check_objects_todos todo_none = {0};
struct check_objects_params *params = args;
const DIDEVICEOBJECTINSTANCEW *exp = params->expect_objs + params->index;
+ const struct check_objects_todos *todo;
+
+ if (!params->todo_objs) todo = &todo_none;
+ else todo = params->todo_objs + params->index;
+
+ todo_wine_if( params->todo_extra && params->index >= params->expect_count )
+ ok( params->index < params->expect_count, "unexpected extra object\n" );
+ if (params->index >= params->expect_count) return DIENUM_STOP;
winetest_push_context( "obj[%d]", params->index );
@@ -3340,8 +3359,11 @@ static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *ar
if (params->index >= params->expect_count) exp = &unexpected_obj;
check_member( *obj, *exp, "%u", dwSize );
+ todo_wine_if( todo->guid )
check_member_guid( *obj, *exp, guidType );
+ todo_wine_if( params->version < 0x700 && (obj->dwType & DIDFT_BUTTON) )
check_member( *obj, *exp, "%#x", dwOfs );
+ todo_wine_if( todo->type )
check_member( *obj, *exp, "%#x", dwType );
check_member( *obj, *exp, "%#x", dwFlags );
if (!localized) todo_wine check_member_wstr( *obj, *exp, tszName );
@@ -3350,6 +3372,7 @@ static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *ar
check_member( *obj, *exp, "%u", wCollectionNumber );
check_member( *obj, *exp, "%u", wDesignatorIndex );
check_member( *obj, *exp, "%#04x", wUsagePage );
+ todo_wine_if( todo->usage )
check_member( *obj, *exp, "%#04x", wUsage );
check_member( *obj, *exp, "%#04x", dwDimension );
check_member( *obj, *exp, "%#04x", wExponent );
@@ -3709,6 +3732,7 @@ static void test_simple_joystick(void)
struct check_objects_params check_objects_params =
{
+ .version = DIRECTINPUT_VERSION,
.expect_count = ARRAY_SIZE(expect_objects),
.expect_objs = expect_objects,
};
@@ -5303,7 +5327,7 @@ static BOOL test_device_types(void)
return success;
}
-static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
+static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWORD version )
{
struct hid_expect expect_download[] =
{
@@ -5326,7 +5350,7 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 3,
.report_len = 11,
- .report_buf = {0x03,0x01,0x01,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0xd5},
+ .report_buf = {0x03,0x01,0x01,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0xd5},
},
/* start command when DIEP_START is set */
{
@@ -5395,9 +5419,9 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
.report_buf = {1, 0x01},
};
static const DWORD expect_axes_init[2] = {0};
- static const DIEFFECT expect_desc_init =
+ const DIEFFECT expect_desc_init =
{
- .dwSize = sizeof(DIEFFECT),
+ .dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5),
.dwTriggerButton = -1,
.rgdwAxes = (void *)expect_axes_init,
};
@@ -5428,9 +5452,9 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
.dwPhase = 3000,
.dwPeriod = 4000,
};
- static const DIEFFECT expect_desc =
+ const DIEFFECT expect_desc =
{
- .dwSize = sizeof(DIEFFECT),
+ .dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5),
.dwFlags = DIEFF_SPHERICAL | DIEFF_OBJECTIDS,
.dwDuration = 1000,
.dwSamplePeriod = 2000,
@@ -5474,19 +5498,30 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
ok( hr == DI_OK, "EnumCreatedEffectObjects returned %#x\n", hr );
ok( check_params.count == 1, "got count %u, expected 1\n", check_params.count );
- hr = IDirectInputEffect_Initialize( effect, NULL, DIRECTINPUT_VERSION, &GUID_Sine );
+ hr = IDirectInputEffect_Initialize( effect, NULL, version, &GUID_Sine );
ok( hr == DIERR_INVALIDPARAM, "Initialize returned %#x\n", hr );
+ hr = IDirectInputEffect_Initialize( effect, instance, 0x800 - (version - 0x700), &GUID_Sine );
+ if (version == 0x800)
+ {
+ todo_wine
+ ok( hr == DIERR_BETADIRECTINPUTVERSION, "Initialize returned %#x\n", hr );
+ }
+ else
+ {
+ todo_wine
+ ok( hr == DIERR_OLDDIRECTINPUTVERSION, "Initialize returned %#x\n", hr );
+ }
hr = IDirectInputEffect_Initialize( effect, instance, 0, &GUID_Sine );
todo_wine
ok( hr == DIERR_NOTINITIALIZED, "Initialize returned %#x\n", hr );
- hr = IDirectInputEffect_Initialize( effect, instance, DIRECTINPUT_VERSION, NULL );
+ hr = IDirectInputEffect_Initialize( effect, instance, version, NULL );
ok( hr == E_POINTER, "Initialize returned %#x\n", hr );
- hr = IDirectInputEffect_Initialize( effect, instance, DIRECTINPUT_VERSION, &GUID_NULL );
+ hr = IDirectInputEffect_Initialize( effect, instance, version, &GUID_NULL );
ok( hr == DIERR_DEVICENOTREG, "Initialize returned %#x\n", hr );
- hr = IDirectInputEffect_Initialize( effect, instance, DIRECTINPUT_VERSION, &GUID_Sine );
+ hr = IDirectInputEffect_Initialize( effect, instance, version, &GUID_Sine );
ok( hr == DI_OK, "Initialize returned %#x\n", hr );
- hr = IDirectInputEffect_Initialize( effect, instance, DIRECTINPUT_VERSION, &GUID_Square );
+ hr = IDirectInputEffect_Initialize( effect, instance, version, &GUID_Square );
ok( hr == DI_OK, "Initialize returned %#x\n", hr );
hr = IDirectInputEffect_GetEffectGuid( effect, NULL );
@@ -5502,7 +5537,15 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
ok( hr == DI_OK, "GetParameters returned %#x\n", hr );
hr = IDirectInputEffect_GetParameters( effect, &desc, 0 );
ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#x\n", hr );
- desc.dwSize = sizeof(DIEFFECT);
+ desc.dwSize = sizeof(DIEFFECT_DX5) + 2;
+ hr = IDirectInputEffect_GetParameters( effect, &desc, 0 );
+ ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#x\n", hr );
+ desc.dwSize = sizeof(DIEFFECT_DX5);
+ hr = IDirectInputEffect_GetParameters( effect, &desc, 0 );
+ ok( hr == DI_OK, "GetParameters returned %#x\n", hr );
+ hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_STARTDELAY );
+ ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#x\n", hr );
+ desc.dwSize = sizeof(DIEFFECT_DX6);
hr = IDirectInputEffect_GetParameters( effect, &desc, 0 );
ok( hr == DI_OK, "GetParameters returned %#x\n", hr );
@@ -5522,18 +5565,21 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
ok( hr == DI_OK, "GetParameters returned %#x\n", hr );
check_member( desc, expect_desc_init, "%u", dwDuration );
memset( &desc, 0xcd, sizeof(desc) );
- desc.dwSize = sizeof(DIEFFECT);
+ desc.dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5);
desc.dwFlags = 0;
- flags = DIEP_GAIN | DIEP_SAMPLEPERIOD | DIEP_STARTDELAY | DIEP_TRIGGERREPEATINTERVAL;
+ desc.dwStartDelay = 0xdeadbeef;
+ flags = DIEP_GAIN | DIEP_SAMPLEPERIOD | DIEP_TRIGGERREPEATINTERVAL |
+ (version >= 0x700 ? DIEP_STARTDELAY : 0);
hr = IDirectInputEffect_GetParameters( effect, &desc, flags );
ok( hr == DI_OK, "GetParameters returned %#x\n", hr );
check_member( desc, expect_desc_init, "%u", dwSamplePeriod );
check_member( desc, expect_desc_init, "%u", dwGain );
- check_member( desc, expect_desc_init, "%u", dwStartDelay );
+ if (version >= 0x700) check_member( desc, expect_desc_init, "%u", dwStartDelay );
+ else ok( desc.dwStartDelay == 0xdeadbeef, "got dwStartDelay %#x\n", desc.dwStartDelay );
check_member( desc, expect_desc_init, "%u", dwTriggerRepeatInterval );
memset( &desc, 0xcd, sizeof(desc) );
- desc.dwSize = sizeof(DIEFFECT);
+ desc.dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5);
desc.dwFlags = 0;
desc.lpEnvelope = NULL;
hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_ENVELOPE );
@@ -5552,7 +5598,7 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
desc.lpEnvelope = NULL;
desc.cbTypeSpecificParams = 0;
desc.lpvTypeSpecificParams = NULL;
- hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_ALLPARAMS );
+ hr = IDirectInputEffect_GetParameters( effect, &desc, version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5 );
ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#x\n", hr );
hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_TRIGGERBUTTON );
ok( hr == DIERR_INVALIDPARAM, "GetParameters returned %#x\n", hr );
@@ -5606,7 +5652,7 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
desc.lpEnvelope = &envelope;
desc.cbTypeSpecificParams = sizeof(periodic);
desc.lpvTypeSpecificParams = &periodic;
- hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_ALLPARAMS );
+ hr = IDirectInputEffect_GetParameters( effect, &desc, version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5 );
ok( hr == DI_OK, "GetParameters returned %#x\n", hr );
check_member( desc, expect_desc_init, "%u", dwDuration );
check_member( desc, expect_desc_init, "%u", dwSamplePeriod );
@@ -5621,7 +5667,8 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
check_member( desc, expect_desc_init, "%p", lpEnvelope );
todo_wine
check_member( desc, expect_desc_init, "%u", cbTypeSpecificParams );
- check_member( desc, expect_desc_init, "%u", dwStartDelay );
+ if (version >= 0x700) check_member( desc, expect_desc_init, "%u", dwStartDelay );
+ else ok( desc.dwStartDelay == 0xcdcdcdcd, "got dwStartDelay %#x\n", desc.dwStartDelay );
set_hid_expect( file, &expect_dc_reset, sizeof(expect_dc_reset) );
hr = IDirectInputDevice8_Unacquire( device );
@@ -5644,7 +5691,7 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
memset( &desc, 0, sizeof(desc) );
hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_NODOWNLOAD );
ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#x\n", hr );
- desc.dwSize = sizeof(DIEFFECT);
+ desc.dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5);
hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_NODOWNLOAD );
ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#x\n", hr );
@@ -5681,12 +5728,13 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
hr = IDirectInputEffect_Unload( effect );
ok( hr == DI_NOEFFECT, "Unload returned %#x\n", hr );
- hr = IDirectInputEffect_SetParameters( effect, &expect_desc,
- DIEP_GAIN | DIEP_SAMPLEPERIOD | DIEP_STARTDELAY |
- DIEP_TRIGGERREPEATINTERVAL | DIEP_NODOWNLOAD );
+ flags = DIEP_GAIN | DIEP_SAMPLEPERIOD | DIEP_TRIGGERREPEATINTERVAL | DIEP_NODOWNLOAD;
+ if (version >= 0x700) flags |= DIEP_STARTDELAY;
+ hr = IDirectInputEffect_SetParameters( effect, &expect_desc, flags );
ok( hr == DI_DOWNLOADSKIPPED, "SetParameters returned %#x\n", hr );
desc.dwDuration = 0;
- flags = DIEP_DURATION | DIEP_GAIN | DIEP_SAMPLEPERIOD | DIEP_STARTDELAY | DIEP_TRIGGERREPEATINTERVAL;
+ flags = DIEP_DURATION | DIEP_GAIN | DIEP_SAMPLEPERIOD | DIEP_TRIGGERREPEATINTERVAL;
+ if (version >= 0x700) flags |= DIEP_STARTDELAY;
hr = IDirectInputEffect_GetParameters( effect, &desc, flags );
ok( hr == DI_OK, "GetParameters returned %#x\n", hr );
check_member( desc, expect_desc, "%u", dwDuration );
@@ -5698,7 +5746,8 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
check_member( desc, expect_desc_init, "%p", rglDirection );
check_member( desc, expect_desc_init, "%p", lpEnvelope );
check_member( desc, expect_desc_init, "%u", cbTypeSpecificParams );
- check_member( desc, expect_desc, "%u", dwStartDelay );
+ if (version >= 0x700) check_member( desc, expect_desc, "%u", dwStartDelay );
+ else ok( desc.dwStartDelay == 0, "got dwStartDelay %#x\n", desc.dwStartDelay );
hr = IDirectInputEffect_Download( effect );
ok( hr == DIERR_INCOMPLETEEFFECT, "Download returned %#x\n", hr );
@@ -5737,7 +5786,8 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
desc.lpEnvelope = NULL;
desc.cbTypeSpecificParams = 0;
desc.lpvTypeSpecificParams = NULL;
- hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_ALLPARAMS | DIEP_NODOWNLOAD );
+ flags = version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5;
+ hr = IDirectInputEffect_SetParameters( effect, &desc, flags | DIEP_NODOWNLOAD );
ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#x\n", hr );
hr = IDirectInputEffect_SetParameters( effect, &desc, DIEP_TRIGGERBUTTON | DIEP_NODOWNLOAD );
ok( hr == DIERR_INVALIDPARAM, "SetParameters returned %#x\n", hr );
@@ -5989,7 +6039,7 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file )
ok( ref == 0, "Release returned %d\n", ref );
}
-static void test_condition_effect( IDirectInputDevice8W *device, HANDLE file )
+static void test_condition_effect( IDirectInputDevice8W *device, HANDLE file, DWORD version )
{
struct hid_expect expect_create[] =
{
@@ -6012,7 +6062,7 @@ static void test_condition_effect( IDirectInputDevice8W *device, HANDLE file )
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 3,
.report_len = 11,
- .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0x00},
+ .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0x00},
},
};
struct hid_expect expect_create_1[] =
@@ -6029,7 +6079,7 @@ static void test_condition_effect( IDirectInputDevice8W *device, HANDLE file )
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 3,
.report_len = 11,
- .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x00,0x00},
+ .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x00,0x00},
},
};
struct hid_expect expect_create_2[] =
@@ -6046,7 +6096,7 @@ static void test_condition_effect( IDirectInputDevice8W *device, HANDLE file )
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 3,
.report_len = 11,
- .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,0x06,0x00,0x01,0x55,0x00},
+ .report_buf = {0x03,0x01,0x03,0x08,0x01,0x00,version >= 0x700 ? 0x06 : 0x00,0x00,0x01,0x55,0x00},
},
};
struct hid_expect expect_destroy =
@@ -6101,9 +6151,9 @@ static void test_condition_effect( IDirectInputDevice8W *device, HANDLE file )
.lDeadBand = -12000,
},
};
- static const DIEFFECT expect_desc =
+ const DIEFFECT expect_desc =
{
- .dwSize = sizeof(DIEFFECT),
+ .dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5),
.dwFlags = DIEFF_SPHERICAL | DIEFF_OBJECTIDS,
.dwDuration = 1000,
.dwSamplePeriod = 2000,
@@ -6127,7 +6177,7 @@ static void test_condition_effect( IDirectInputDevice8W *device, HANDLE file )
DWORD axes[4] = {0};
DIEFFECT desc =
{
- .dwSize = sizeof(DIEFFECT),
+ .dwSize = version >= 0x700 ? sizeof(DIEFFECT_DX6) : sizeof(DIEFFECT_DX5),
.dwFlags = DIEFF_SPHERICAL | DIEFF_OBJECTIDS,
.cAxes = 4,
.rgdwAxes = axes,
@@ -6155,7 +6205,7 @@ static void test_condition_effect( IDirectInputDevice8W *device, HANDLE file )
ok( IsEqualGUID( &guid, &GUID_Spring ), "got guid %s, expected %s\n", debugstr_guid( &guid ),
debugstr_guid( &GUID_Spring ) );
- hr = IDirectInputEffect_GetParameters( effect, &desc, DIEP_ALLPARAMS );
+ hr = IDirectInputEffect_GetParameters( effect, &desc, version >= 0x700 ? DIEP_ALLPARAMS : DIEP_ALLPARAMS_DX5 );
ok( hr == DI_OK, "GetParameters returned %#x\n", hr );
check_member( desc, expect_desc, "%u", dwDuration );
check_member( desc, expect_desc, "%u", dwSamplePeriod );
@@ -6168,7 +6218,8 @@ static void test_condition_effect( IDirectInputDevice8W *device, HANDLE file )
check_member( desc, expect_desc, "%d", rglDirection[0] );
check_member( desc, expect_desc, "%d", rglDirection[1] );
check_member( desc, expect_desc, "%u", cbTypeSpecificParams );
- check_member( desc, expect_desc, "%u", dwStartDelay );
+ if (version >= 0x700) check_member( desc, expect_desc, "%u", dwStartDelay );
+ else ok( desc.dwStartDelay == 0, "got dwStartDelay %#x\n", desc.dwStartDelay );
check_member( envelope, expect_envelope, "%u", dwAttackLevel );
check_member( envelope, expect_envelope, "%u", dwAttackTime );
check_member( envelope, expect_envelope, "%u", dwFadeLevel );
@@ -6222,7 +6273,7 @@ static void test_condition_effect( IDirectInputDevice8W *device, HANDLE file )
set_hid_expect( file, NULL, 0 );
}
-static void test_force_feedback_joystick( void )
+static void test_force_feedback_joystick( DWORD version )
{
#include "psh_hid_macros.h"
const unsigned char report_descriptor[] = {
@@ -6550,12 +6601,13 @@ static void test_force_feedback_joystick( void )
{
.InputReportByteLength = 5,
};
- static const DIDEVCAPS expect_caps =
+ const DIDEVCAPS expect_caps =
{
.dwSize = sizeof(DIDEVCAPS),
.dwFlags = DIDC_FORCEFEEDBACK | DIDC_ATTACHED | DIDC_EMULATED | DIDC_STARTDELAY |
DIDC_FFFADE | DIDC_FFATTACK | DIDC_DEADBAND | DIDC_SATURATION,
- .dwDevType = DIDEVTYPE_HID | (DI8DEVTYPEJOYSTICK_LIMITED << 8) | DI8DEVTYPE_JOYSTICK,
+ .dwDevType = version >= 0x800 ? DIDEVTYPE_HID | (DI8DEVTYPEJOYSTICK_LIMITED << 8) | DI8DEVTYPE_JOYSTICK
+ : DIDEVTYPE_HID | (DIDEVTYPEJOYSTICK_UNKNOWN << 8) | DIDEVTYPE_JOYSTICK,
.dwAxes = 3,
.dwButtons = 2,
.dwFFSamplePeriod = 1000000,
@@ -6576,13 +6628,76 @@ static void test_force_feedback_joystick( void )
.dwSize = sizeof(DIDEVICEINSTANCEW),
.guidInstance = expect_guid_product,
.guidProduct = expect_guid_product,
- .dwDevType = DIDEVTYPE_HID | (DI8DEVTYPEJOYSTICK_LIMITED << 8) | DI8DEVTYPE_JOYSTICK,
+ .dwDevType = version >= 0x800 ? DIDEVTYPE_HID | (DI8DEVTYPEJOYSTICK_LIMITED << 8) | DI8DEVTYPE_JOYSTICK
+ : DIDEVTYPE_HID | (DIDEVTYPEJOYSTICK_UNKNOWN << 8) | DIDEVTYPE_JOYSTICK,
.tszInstanceName = L"Wine test root driver",
.tszProductName = L"Wine test root driver",
.guidFFDriver = IID_IDirectInputPIDDriver,
.wUsagePage = HID_USAGE_PAGE_GENERIC,
.wUsage = HID_USAGE_GENERIC_JOYSTICK,
};
+ const DIDEVICEOBJECTINSTANCEW expect_objects_5[] =
+ {
+ {
+ .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
+ .guidType = GUID_XAxis,
+ .dwType = DIDFT_ABSAXIS|DIDFT_MAKEINSTANCE(0)|DIDFT_FFACTUATOR,
+ .dwFlags = DIDOI_ASPECTPOSITION|DIDOI_FFACTUATOR,
+ .tszName = L"X Axis",
+ .wCollectionNumber = 1,
+ .wUsagePage = HID_USAGE_PAGE_GENERIC,
+ .wUsage = HID_USAGE_GENERIC_X,
+ .wReportId = 1,
+ },
+ {
+ .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
+ .guidType = GUID_YAxis,
+ .dwOfs = 0x4,
+ .dwType = DIDFT_ABSAXIS|DIDFT_MAKEINSTANCE(1)|DIDFT_FFACTUATOR,
+ .dwFlags = DIDOI_ASPECTPOSITION|DIDOI_FFACTUATOR,
+ .tszName = L"Y Axis",
+ .wCollectionNumber = 1,
+ .wUsagePage = HID_USAGE_PAGE_GENERIC,
+ .wUsage = HID_USAGE_GENERIC_Y,
+ .wReportId = 1,
+ },
+ {
+ .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
+ .guidType = GUID_ZAxis,
+ .dwOfs = 0x8,
+ .dwType = DIDFT_ABSAXIS|DIDFT_MAKEINSTANCE(2)|DIDFT_FFACTUATOR,
+ .dwFlags = DIDOI_ASPECTPOSITION|DIDOI_FFACTUATOR,
+ .tszName = L"Z Axis",
+ .wCollectionNumber = 1,
+ .wUsagePage = HID_USAGE_PAGE_GENERIC,
+ .wUsage = HID_USAGE_GENERIC_Z,
+ .wReportId = 1,
+ },
+ {
+ .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
+ .guidType = GUID_Button,
+ .dwOfs = 0x30,
+ .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(0)|DIDFT_FFEFFECTTRIGGER,
+ .dwFlags = DIDOI_FFEFFECTTRIGGER,
+ .tszName = L"Button 0",
+ .wCollectionNumber = 1,
+ .wUsagePage = HID_USAGE_PAGE_BUTTON,
+ .wUsage = 0x1,
+ .wReportId = 1,
+ },
+ {
+ .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
+ .guidType = GUID_Button,
+ .dwOfs = 0x31,
+ .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(1)|DIDFT_FFEFFECTTRIGGER,
+ .dwFlags = DIDOI_FFEFFECTTRIGGER,
+ .tszName = L"Button 1",
+ .wCollectionNumber = 1,
+ .wUsagePage = HID_USAGE_PAGE_BUTTON,
+ .wUsage = 0x2,
+ .wReportId = 1,
+ },
+ };
const DIDEVICEOBJECTINSTANCEW expect_objects[] =
{
{
@@ -6623,7 +6738,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Button,
- .dwOfs = 0x64,
+ .dwOfs = version >= 0x800 ? 0x64 : 0x10,
.dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(0)|DIDFT_FFEFFECTTRIGGER,
.dwFlags = DIDOI_FFEFFECTTRIGGER,
.tszName = L"Button 0",
@@ -6635,7 +6750,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Button,
- .dwOfs = 0x65,
+ .dwOfs = version >= 0x800 ? 0x65 : 0x11,
.dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(1)|DIDFT_FFEFFECTTRIGGER,
.dwFlags = DIDOI_FFEFFECTTRIGGER,
.tszName = L"Button 1",
@@ -6647,7 +6762,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x6c,
+ .dwOfs = version >= 0x800 ? 0x6c : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(12)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"DC Device Reset",
@@ -6659,7 +6774,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x10,
+ .dwOfs = version >= 0x800 ? 0x10 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(13)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Effect Block Index",
@@ -6671,7 +6786,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x6d,
+ .dwOfs = version >= 0x800 ? 0x6d : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(14)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Op Effect Start",
@@ -6683,7 +6798,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x6e,
+ .dwOfs = version >= 0x800 ? 0x6e : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(15)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Op Effect Start Solo",
@@ -6695,7 +6810,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x6f,
+ .dwOfs = version >= 0x800 ? 0x6f : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(16)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Op Effect Stop",
@@ -6707,7 +6822,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x14,
+ .dwOfs = version >= 0x800 ? 0x14 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(17)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Loop Count",
@@ -6719,7 +6834,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x18,
+ .dwOfs = version >= 0x800 ? 0x18 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(18)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Effect Block Index",
@@ -6731,7 +6846,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x70,
+ .dwOfs = version >= 0x800 ? 0x70 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(19)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"ET Square",
@@ -6743,7 +6858,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x71,
+ .dwOfs = version >= 0x800 ? 0x71 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(20)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"ET Sine",
@@ -6755,7 +6870,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x72,
+ .dwOfs = version >= 0x800 ? 0x72 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(21)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"ET Spring",
@@ -6767,7 +6882,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x73,
+ .dwOfs = version >= 0x800 ? 0x73 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(22)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Z Axis",
@@ -6779,7 +6894,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x74,
+ .dwOfs = version >= 0x800 ? 0x74 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(23)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Y Axis",
@@ -6791,7 +6906,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x75,
+ .dwOfs = version >= 0x800 ? 0x75 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(24)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"X Axis",
@@ -6803,7 +6918,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x76,
+ .dwOfs = version >= 0x800 ? 0x76 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(25)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Direction Enable",
@@ -6815,7 +6930,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x1c,
+ .dwOfs = version >= 0x800 ? 0x1c : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(26)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Start Delay",
@@ -6829,7 +6944,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x20,
+ .dwOfs = version >= 0x800 ? 0x20 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(27)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Duration",
@@ -6843,7 +6958,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x24,
+ .dwOfs = version >= 0x800 ? 0x24 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(28)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Trigger Button",
@@ -6855,7 +6970,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x28,
+ .dwOfs = version >= 0x800 ? 0x28 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(29)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Unknown 29",
@@ -6868,7 +6983,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x2c,
+ .dwOfs = version >= 0x800 ? 0x2c : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(30)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Unknown 30",
@@ -6881,7 +6996,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x30,
+ .dwOfs = version >= 0x800 ? 0x30 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(31)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Magnitude",
@@ -6893,7 +7008,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x34,
+ .dwOfs = version >= 0x800 ? 0x34 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(32)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Fade Level",
@@ -6905,7 +7020,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x38,
+ .dwOfs = version >= 0x800 ? 0x38 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(33)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Attack Level",
@@ -6917,7 +7032,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x3c,
+ .dwOfs = version >= 0x800 ? 0x3c : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(34)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Fade Time",
@@ -6931,7 +7046,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x40,
+ .dwOfs = version >= 0x800 ? 0x40 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(35)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Attack Time",
@@ -6945,7 +7060,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x44,
+ .dwOfs = version >= 0x800 ? 0x44 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(36)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Unknown 36",
@@ -6957,7 +7072,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x48,
+ .dwOfs = version >= 0x800 ? 0x48 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(37)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Unknown 37",
@@ -6969,7 +7084,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x4c,
+ .dwOfs = version >= 0x800 ? 0x4c : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(38)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"CP Offset",
@@ -6981,7 +7096,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x50,
+ .dwOfs = version >= 0x800 ? 0x50 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(39)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Negative Coefficient",
@@ -6993,7 +7108,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x54,
+ .dwOfs = version >= 0x800 ? 0x54 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(40)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Positive Coefficient",
@@ -7005,7 +7120,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x58,
+ .dwOfs = version >= 0x800 ? 0x58 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(41)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Negative Saturation",
@@ -7017,7 +7132,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x5c,
+ .dwOfs = version >= 0x800 ? 0x5c : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(42)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Positive Saturation",
@@ -7029,7 +7144,7 @@ static void test_force_feedback_joystick( void )
{
.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
.guidType = GUID_Unknown,
- .dwOfs = 0x60,
+ .dwOfs = version >= 0x800 ? 0x60 : 0,
.dwType = DIDFT_NODATA|DIDFT_MAKEINSTANCE(43)|DIDFT_OUTPUT,
.dwFlags = 0x80008000,
.tszName = L"Dead Band",
@@ -7199,10 +7314,19 @@ static void test_force_feedback_joystick( void )
}
};
+ struct check_objects_todos todo_objects_5[ARRAY_SIZE(expect_objects_5)] =
+ {
+ {.guid = TRUE, .type = TRUE, .usage = TRUE},
+ {0},
+ {.guid = TRUE, .type = TRUE, .usage = TRUE},
+ };
struct check_objects_params check_objects_params =
{
- .expect_count = ARRAY_SIZE(expect_objects),
- .expect_objs = expect_objects,
+ .version = version,
+ .expect_count = version < 0x700 ? ARRAY_SIZE(expect_objects_5) : ARRAY_SIZE(expect_objects),
+ .expect_objs = version < 0x700 ? expect_objects_5 : expect_objects,
+ .todo_objs = version < 0x700 ? todo_objects_5 : NULL,
+ .todo_extra = version < 0x700 ? TRUE : FALSE,
};
struct check_effects_params check_effects_params =
{
@@ -7234,13 +7358,16 @@ static void test_force_feedback_joystick( void )
IDirectInputDevice8W *device;
DIEFFESCAPE escape = {0};
DIDEVCAPS caps = {0};
- IDirectInput8W *di;
- char buffer[1024];
+ IDirectInput8W *di8;
+ IDirectInputW *di;
ULONG res, ref;
+ char buffer[1024];
HANDLE file;
HRESULT hr;
HWND hwnd;
+ winetest_push_context( "version %#x", version );
+
GetCurrentDirectoryW( ARRAY_SIZE(cwd), cwd );
GetTempPathW( ARRAY_SIZE(tempdir), tempdir );
SetCurrentDirectoryW( tempdir );
@@ -7248,24 +7375,59 @@ static void test_force_feedback_joystick( void )
cleanup_registry_keys();
if (!dinput_driver_start( report_descriptor, sizeof(report_descriptor), &hid_caps )) goto done;
- hr = DirectInput8Create( instance, DIRECTINPUT_VERSION, &IID_IDirectInput8W, (void **)&di, NULL );
- if (FAILED(hr))
+ if (version >= 0x800)
{
- win_skip( "DirectInput8Create returned %#x\n", hr );
- goto done;
- }
+ hr = DirectInput8Create( instance, version, &IID_IDirectInput8W, (void **)&di8, NULL );
+ if (FAILED(hr))
+ {
+ win_skip( "DirectInput8Create returned %#x\n", hr );
+ goto done;
+ }
- hr = IDirectInput8_EnumDevices( di, DI8DEVCLASS_ALL, find_test_device, &devinst, DIEDFL_ALLDEVICES );
- ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr );
- if (!IsEqualGUID( &devinst.guidProduct, &expect_guid_product ))
+ hr = IDirectInput8_EnumDevices( di8, DI8DEVCLASS_ALL, find_test_device, &devinst, DIEDFL_ALLDEVICES );
+ ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr );
+ if (!IsEqualGUID( &devinst.guidProduct, &expect_guid_product ))
+ {
+ win_skip( "device not found, skipping tests\n" );
+ ref = IDirectInput8_Release( di8 );
+ ok( ref == 0, "Release returned %d\n", ref );
+ goto done;
+ }
+
+ hr = IDirectInput8_CreateDevice( di8, &expect_guid_product, &device, NULL );
+ ok( hr == DI_OK, "CreateDevice returned %#x\n", hr );
+
+ ref = IDirectInput8_Release( di8 );
+ todo_wine
+ ok( ref == 0, "Release returned %d\n", ref );
+ }
+ else
{
- win_skip( "device not found, skipping tests\n" );
- IDirectInput8_Release( di );
- goto done;
- }
+ hr = DirectInputCreateEx( instance, version, &IID_IDirectInput2W, (void **)&di, NULL );
+ if (FAILED(hr))
+ {
+ win_skip( "DirectInputCreateEx returned %#x\n", hr );
+ goto done;
+ }
- hr = IDirectInput8_CreateDevice( di, &expect_guid_product, &device, NULL );
- ok( hr == DI_OK, "CreateDevice returned %#x\n", hr );
+ hr = IDirectInput_EnumDevices( di, 0, find_test_device, &devinst, DIEDFL_ALLDEVICES );
+ ok( hr == DI_OK, "EnumDevices returned: %#x\n", hr );
+ if (!IsEqualGUID( &devinst.guidProduct, &expect_guid_product ))
+ {
+ win_skip( "device not found, skipping tests\n" );
+
+ ref = IDirectInput_Release( di );
+ ok( ref == 0, "Release returned %d\n", ref );
+ goto done;
+ }
+
+ hr = IDirectInput_CreateDevice( di, &expect_guid_product, (IDirectInputDeviceW **)&device, NULL );
+ ok( hr == DI_OK, "CreateDevice returned %#x\n", hr );
+
+ ref = IDirectInput_Release( di );
+ todo_wine
+ ok( ref == 0, "Release returned %d\n", ref );
+ }
hr = IDirectInputDevice8_GetDeviceInfo( device, &devinst );
ok( hr == DI_OK, "GetDeviceInfo returned %#x\n", hr );
@@ -7435,11 +7597,11 @@ static void test_force_feedback_joystick( void )
objdata.dwData = 0x80;
res = 1;
hr = IDirectInputDevice8_SendDeviceData( device, sizeof(DIDEVICEOBJECTDATA), &objdata, &res, 0 );
- todo_wine
- ok( hr == DIERR_INVALIDPARAM, "SendDeviceData returned %#x\n", hr );
+ if (version < 0x800) ok( hr == DI_OK, "SendDeviceData returned %#x\n", hr );
+ else todo_wine ok( hr == DIERR_INVALIDPARAM, "SendDeviceData returned %#x\n", hr );
- test_periodic_effect( device, file );
- test_condition_effect( device, file );
+ test_periodic_effect( device, file, version );
+ test_condition_effect( device, file, version );
set_hid_expect( file, &expect_dc_reset, sizeof(expect_dc_reset) );
hr = IDirectInputDevice8_Unacquire( device );
@@ -7452,13 +7614,11 @@ static void test_force_feedback_joystick( void )
DestroyWindow( hwnd );
CloseHandle( file );
- ref = IDirectInput8_Release( di );
- ok( ref == 0, "Release returned %d\n", ref );
-
done:
pnp_driver_stop();
cleanup_registry_keys();
SetCurrentDirectoryW( cwd );
+ winetest_pop_context();
}
START_TEST( hid )
@@ -7504,7 +7664,9 @@ START_TEST( hid )
if (test_device_types())
{
test_simple_joystick();
- test_force_feedback_joystick();
+ test_force_feedback_joystick( 0x500 );
+ test_force_feedback_joystick( 0x700 );
+ test_force_feedback_joystick( 0x800 );
}
CoUninitialize();
--
2.33.1
Nov. 10, 2021
[PATCH 1/7] dinput8/tests: Make test_device_input tests more predictable.
by Rémi Bernon
Using a notification event to wait for input, addressing spurious
failures or timeouts.
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/dinput8/tests/device.c | 101 ++++++++++++++++++++++++------------
1 file changed, 67 insertions(+), 34 deletions(-)
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
index 3cad4ce256c..5ae9e225dc9 100644
--- a/dlls/dinput8/tests/device.c
+++ b/dlls/dinput8/tests/device.c
@@ -90,67 +90,100 @@ static void flush_events(void)
}
}
-static void test_device_input(IDirectInputDevice8A *lpdid, DWORD event_type, DWORD event, UINT_PTR expected)
+static void test_device_input( IDirectInputDevice8A *device, DWORD type, DWORD code, UINT_PTR expected )
{
HRESULT hr;
DIDEVICEOBJECTDATA obj_data;
- DWORD data_size = 1;
+ DWORD res, data_size = 1;
+ HANDLE event;
int i;
- hr = IDirectInputDevice8_Acquire(lpdid);
- ok (SUCCEEDED(hr), "Failed to acquire device hr=%08x\n", hr);
+ event = CreateEventW( NULL, FALSE, FALSE, NULL );
+ ok( event != NULL, "CreateEventW failed, error %u\n", GetLastError() );
- if (event_type == INPUT_KEYBOARD)
- keybd_event(0, event, KEYEVENTF_SCANCODE, 0);
+ IDirectInputDevice_Unacquire( device );
- if (event_type == INPUT_MOUSE)
- mouse_event( event, 0, 0, 0, 0);
+ hr = IDirectInputDevice8_SetEventNotification( device, event );
+ ok( hr == DI_OK, "SetEventNotification returned %#x\n", hr );
- flush_events();
- IDirectInputDevice8_Poll(lpdid);
- hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0);
+ hr = IDirectInputDevice8_Acquire( device );
+ ok( hr == DI_OK, "Acquire returned %#x\n", hr );
- if (data_size != 1)
+ if (type == INPUT_KEYBOARD)
{
- win_skip("We're not able to inject input into Windows dinput8 with events\n");
- IDirectInputDevice_Unacquire(lpdid);
- return;
+ keybd_event( 0, code, KEYEVENTF_SCANCODE, 0 );
+ res = WaitForSingleObject( event, 100 );
+ ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#x\n", res );
+
+ keybd_event( 0, code, KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, 0 );
+ res = WaitForSingleObject( event, 100 );
+ ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#x\n", res );
+ }
+ if (type == INPUT_MOUSE)
+ {
+ mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
+ res = WaitForSingleObject( event, 100 );
+ ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#x\n", res );
+
+ mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
+ res = WaitForSingleObject( event, 100 );
+ ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#x\n", res );
}
- ok (obj_data.uAppData == expected, "Retrieval of action failed uAppData=%lu expected=%lu\n", obj_data.uAppData, expected);
+ hr = IDirectInputDevice8_GetDeviceData( device, sizeof(obj_data), &obj_data, &data_size, 0 );
+ ok( hr == DI_OK, "GetDeviceData returned %#x\n", hr );
+ ok( data_size == 1, "got data size %u, expected 1\n", data_size );
+ ok( obj_data.uAppData == expected, "got action uAppData %p, expected %p\n",
+ (void *)obj_data.uAppData, (void *)expected );
/* Check for buffer overflow */
for (i = 0; i < 17; i++)
- if (event_type == INPUT_KEYBOARD)
+ {
+ if (type == INPUT_KEYBOARD)
{
- keybd_event( VK_SPACE, DIK_SPACE, 0, 0);
- keybd_event( VK_SPACE, DIK_SPACE, KEYEVENTF_KEYUP, 0);
- }
- else if (event_type == INPUT_MOUSE)
- {
- mouse_event(MOUSEEVENTF_LEFTDOWN, 1, 1, 0, 0);
- mouse_event(MOUSEEVENTF_LEFTUP, 1, 1, 0, 0);
- }
+ keybd_event( VK_SPACE, DIK_SPACE, 0, 0 );
+ res = WaitForSingleObject( event, 100 );
+ ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#x\n", res );
- flush_events();
- IDirectInputDevice8_Poll(lpdid);
+ keybd_event( VK_SPACE, DIK_SPACE, KEYEVENTF_KEYUP, 0 );
+ res = WaitForSingleObject( event, 100 );
+ ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#x\n", res );
+ }
+ if (type == INPUT_MOUSE)
+ {
+ mouse_event( MOUSEEVENTF_LEFTDOWN, 1, 1, 0, 0 );
+ res = WaitForSingleObject( event, 100 );
+ ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#x\n", res );
+
+ mouse_event( MOUSEEVENTF_LEFTUP, 1, 1, 0, 0 );
+ res = WaitForSingleObject( event, 100 );
+ ok( res == WAIT_OBJECT_0, "WaitForSingleObject returned %#x\n", res );
+ }
+ }
data_size = 1;
- hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0);
- ok(hr == DI_BUFFEROVERFLOW, "GetDeviceData() failed: %08x\n", hr);
+ hr = IDirectInputDevice8_GetDeviceData( device, sizeof(obj_data), &obj_data, &data_size, 0 );
+ ok( hr == DI_BUFFEROVERFLOW, "GetDeviceData returned %#x\n", hr );
data_size = 1;
- hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0);
- ok(hr == DI_OK && data_size == 1, "GetDeviceData() failed: %08x cnt:%d\n", hr, data_size);
+ hr = IDirectInputDevice8_GetDeviceData( device, sizeof(obj_data), &obj_data, &data_size, 0 );
+ ok( hr == DI_OK, "GetDeviceData returned %#x\n", hr );
+ ok( data_size == 1, "got data_size %u, expected 1\n", data_size );
/* drain device's queue */
while (data_size == 1)
{
- hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0);
- ok(hr == DI_OK, "GetDeviceData() failed: %08x cnt:%d\n", hr, data_size);
+ hr = IDirectInputDevice8_GetDeviceData( device, sizeof(obj_data), &obj_data, &data_size, 0 );
+ ok( hr == DI_OK, "GetDeviceData returned %#x\n", hr );
if (hr != DI_OK) break;
}
- IDirectInputDevice_Unacquire(lpdid);
+ hr = IDirectInputDevice_Unacquire( device );
+ ok( hr == DI_OK, "Unacquire returned %#x\n", hr );
+
+ hr = IDirectInputDevice8_SetEventNotification( device, NULL );
+ ok( hr == DI_OK, "SetEventNotification returned %#x\n", hr );
+
+ CloseHandle( event );
}
static void test_build_action_map(IDirectInputDevice8A *lpdid, DIACTIONFORMATA *lpdiaf,
--
2.33.1
Nov. 10, 2021
[PATCH v2 2/2] services: Terminate all service processes on shutdown.
by Rémi Bernon
Instead of waiting for wineserver to kills them on shutdown, after a
2s delay.
This saves another ~2s on the prefix shutdown time, as measured with:
time bash -c 'wine cmd /c exit |& tee /dev/null'
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
programs/services/services.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/programs/services/services.c b/programs/services/services.c
index 39cd9ee4ffa..d969cf81ab9 100644
--- a/programs/services/services.c
+++ b/programs/services/services.c
@@ -520,6 +520,7 @@ static void scmdatabase_wait_terminate(struct scmdatabase *db)
{
struct process_entry *process = grab_process(LIST_ENTRY(ptr, struct process_entry, entry));
+ process_terminate(process);
scmdatabase_unlock(db);
WaitForSingleObject(process->process, INFINITE);
scmdatabase_lock(db);
--
2.33.1
Nov. 10, 2021
[PATCH v2 1/2] server: Wait for process exit more often and using increasing delay.
by Rémi Bernon
Instead of waiting for 1s before considering it dead, when most of the
time the process dies quickly, delaying desktop or wineserver shutdown.
This saves ~2s on the prefix shutdown time, as measured with:
time bash -c 'wine cmd /c exit |& tee /dev/null'
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
v2: Rebase on upstream HEAD.
server/process.c | 19 +++++++++++++++----
server/process.h | 1 +
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/server/process.c b/server/process.c
index 48b5d6d6dd4..343ad78270c 100644
--- a/server/process.c
+++ b/server/process.c
@@ -595,10 +595,20 @@ static void process_died( struct process *process )
static void process_sigkill( void *private )
{
struct process *process = private;
+ int signal = 0;
- process->sigkill_timeout = NULL;
- kill( process->unix_pid, SIGKILL );
- process_died( process );
+ process->sigkill_delay *= 2;
+ if (process->sigkill_delay >= TICKS_PER_SEC / 2)
+ signal = SIGKILL;
+
+ if (!kill( process->unix_pid, signal ) && !signal)
+ process->sigkill_timeout = add_timeout_user( -process->sigkill_delay, process_sigkill, process );
+ else
+ {
+ process->sigkill_delay = TICKS_PER_SEC / 64;
+ process->sigkill_timeout = NULL;
+ process_died( process );
+ }
}
/* start the sigkill timer for a process upon exit */
@@ -606,7 +616,7 @@ static void start_sigkill_timer( struct process *process )
{
grab_object( process );
if (process->unix_pid != -1)
- process->sigkill_timeout = add_timeout_user( -TICKS_PER_SEC, process_sigkill, process );
+ process->sigkill_timeout = add_timeout_user( -process->sigkill_delay, process_sigkill, process );
else
process_died( process );
}
@@ -630,6 +640,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
process->handles = NULL;
process->msg_fd = NULL;
process->sigkill_timeout = NULL;
+ process->sigkill_delay = TICKS_PER_SEC / 64;
process->unix_pid = -1;
process->exit_code = STILL_ACTIVE;
process->running_threads = 0;
diff --git a/server/process.h b/server/process.h
index 55e4d6dced6..22ee8178368 100644
--- a/server/process.h
+++ b/server/process.h
@@ -53,6 +53,7 @@ struct process
process_id_t group_id; /* group id of the process */
unsigned int session_id; /* session id */
struct timeout_user *sigkill_timeout; /* timeout for final SIGKILL */
+ timeout_t sigkill_delay; /* delay before final SIGKILL */
unsigned short machine; /* client machine type */
int unix_pid; /* Unix pid for final SIGKILL */
int exit_code; /* process exit code */
--
2.33.1
Nov. 10, 2021
Re: [PATCH 2/2] services: Terminate all service processes on shutdown.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=101627
Your paranoid android.
=== debiant2 (build log) ===
error: patch failed: server/process.h:53
Task: Patch failed to apply
=== debiant2 (build log) ===
error: patch failed: server/process.h:53
Task: Patch failed to apply
Nov. 10, 2021
Re: [PATCH 1/2] server: Wait for process exit more often and using increasing delay.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=101626
Your paranoid android.
=== debiant2 (build log) ===
error: patch failed: server/process.h:53
Task: Patch failed to apply
=== debiant2 (build log) ===
error: patch failed: server/process.h:53
Task: Patch failed to apply
Nov. 10, 2021
[PATCH 2/2] services: Terminate all service processes on shutdown.
by Rémi Bernon
Instead of waiting for wineserver to kills them on shutdown, after a
2s delay.
This saves another ~2s on the prefix shutdown time, as measured with:
time bash -c 'wine cmd /c exit |& tee /dev/null'
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
programs/services/services.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/programs/services/services.c b/programs/services/services.c
index 39cd9ee4ffa..d969cf81ab9 100644
--- a/programs/services/services.c
+++ b/programs/services/services.c
@@ -520,6 +520,7 @@ static void scmdatabase_wait_terminate(struct scmdatabase *db)
{
struct process_entry *process = grab_process(LIST_ENTRY(ptr, struct process_entry, entry));
+ process_terminate(process);
scmdatabase_unlock(db);
WaitForSingleObject(process->process, INFINITE);
scmdatabase_lock(db);
--
2.33.1
Nov. 10, 2021
[PATCH 1/2] server: Wait for process exit more often and using increasing delay.
by Rémi Bernon
Instead of waiting for 1s before considering it dead, when most of the
time the process dies quickly, delaying desktop or wineserver shutdown.
This saves ~2s on the prefix shutdown time, as measured with:
time bash -c 'wine cmd /c exit |& tee /dev/null'
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
server/process.c | 19 +++++++++++++++----
server/process.h | 1 +
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/server/process.c b/server/process.c
index c8b32bd98b5..9e9d3f094cd 100644
--- a/server/process.c
+++ b/server/process.c
@@ -595,10 +595,20 @@ static void process_died( struct process *process )
static void process_sigkill( void *private )
{
struct process *process = private;
+ int signal = 0;
- process->sigkill_timeout = NULL;
- kill( process->unix_pid, SIGKILL );
- process_died( process );
+ process->sigkill_delay *= 2;
+ if (process->sigkill_delay >= TICKS_PER_SEC / 2)
+ signal = SIGKILL;
+
+ if (!kill( process->unix_pid, signal ) && !signal)
+ process->sigkill_timeout = add_timeout_user( -process->sigkill_delay, process_sigkill, process );
+ else
+ {
+ process->sigkill_delay = TICKS_PER_SEC / 64;
+ process->sigkill_timeout = NULL;
+ process_died( process );
+ }
}
/* start the sigkill timer for a process upon exit */
@@ -606,7 +616,7 @@ static void start_sigkill_timer( struct process *process )
{
grab_object( process );
if (process->unix_pid != -1)
- process->sigkill_timeout = add_timeout_user( -TICKS_PER_SEC, process_sigkill, process );
+ process->sigkill_timeout = add_timeout_user( -process->sigkill_delay, process_sigkill, process );
else
process_died( process );
}
@@ -630,6 +640,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
process->handles = NULL;
process->msg_fd = NULL;
process->sigkill_timeout = NULL;
+ process->sigkill_delay = TICKS_PER_SEC / 64;
process->unix_pid = -1;
process->exit_code = STILL_ACTIVE;
process->running_threads = 0;
diff --git a/server/process.h b/server/process.h
index ef1c1206350..1cf554b920b 100644
--- a/server/process.h
+++ b/server/process.h
@@ -53,6 +53,7 @@ struct process
process_id_t group_id; /* group id of the process */
unsigned int session_id; /* session id */
struct timeout_user *sigkill_timeout; /* timeout for final SIGKILL */
+ timeout_t sigkill_delay; /* delay before final SIGKILL */
unsigned short machine; /* client machine type */
int unix_pid; /* Unix pid for final SIGKILL */
int nice_limit; /* RLIMIT_NICE of the process */
--
2.33.1
Nov. 10, 2021
[PATCH vkd3d 4/4] vkd3d-shader/spirv: Support UAV counter descriptor arrays.
by Conor McCarthy
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
---
include/vkd3d_shader.h | 4 +-
libs/vkd3d-shader/spirv.c | 83 ++++++++++++++++++---------------------
2 files changed, 39 insertions(+), 48 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 791ac037..1eae0bbe 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -537,9 +537,7 @@ struct vkd3d_shader_descriptor_offset_info
/**
* Pointer to an array of offsets into the descriptor arrays referenced by
* the 'uav_counters' array in struct vkd3d_shader_interface_info. This
- * works the same way as \ref binding_offsets above. UAV counter arrays are
- * not supported in this version of vkd3d-shader, and therefore this field
- * must either be NULL or specify 0 offsets.
+ * works the same way as \ref binding_offsets above.
*/
const struct vkd3d_shader_descriptor_offset *uav_counter_offsets;
};
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 869d7382..3e1baf64 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1990,6 +1990,7 @@ struct vkd3d_symbol_resource_data
unsigned int structure_stride;
bool raw;
uint32_t uav_counter_id;
+ struct vkd3d_descriptor_array_symbol uav_counter_array;
};
struct vkd3d_symbol_sampler_data
@@ -2410,8 +2411,6 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
if ((offset_info = vkd3d_find_struct(shader_interface->next, DESCRIPTOR_OFFSET_INFO)))
{
compiler->offset_info = *offset_info;
- if (offset_info->uav_counter_offsets)
- WARN("Ignoring UAV counter offsets %p.\n", offset_info->uav_counter_offsets);
}
}
@@ -2602,6 +2601,7 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
if (is_uav_counter)
{
assert(descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV);
+ binding_offsets = compiler->offset_info.uav_counter_offsets;
for (i = 0; i < shader_interface->uav_counter_count; ++i)
{
const struct vkd3d_shader_uav_counter_binding *current = &shader_interface->uav_counters[i];
@@ -2609,7 +2609,8 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->shader_visibility))
continue;
- if (current->register_space != range->space || current->register_index != range->first)
+ if (current->register_space != range->space || current->register_index > range->first
+ || current->binding.count <= register_last - current->register_index)
continue;
if (current->offset)
@@ -2620,16 +2621,9 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
range->first, range->space, current->offset);
}
- if (current->binding.count != 1)
- {
- FIXME("Descriptor arrays are not supported.\n");
- vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING,
- "Descriptor binding for UAV counter %u, space %u has unsupported ‘count’ %u.",
- range->first, range->space, current->binding.count);
- }
-
- binding_address->binding_base_idx = current->register_index;
- binding_address->push_constant_index = ~0u;
+ binding_address->binding_base_idx = current->register_index
+ - (binding_offsets ? binding_offsets[i].static_offset : 0);
+ binding_address->push_constant_index = binding_offsets ? binding_offsets[i].dynamic_offset_index : ~0u;
return current->binding;
}
if (shader_interface->uav_counter_count)
@@ -2692,18 +2686,6 @@ static void vkd3d_dxbc_compiler_emit_descriptor_binding(struct vkd3d_dxbc_compil
vkd3d_spirv_build_op_decorate1(builder, variable_id, SpvDecorationBinding, binding->binding);
}
-static void vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(struct vkd3d_dxbc_compiler *compiler,
- uint32_t variable_id, const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range,
- enum vkd3d_shader_resource_type resource_type, bool is_uav_counter)
-{
- struct vkd3d_shader_descriptor_binding binding;
- struct vkd3d_descriptor_binding_address binding_address; /* Values not used. */
-
- binding = vkd3d_dxbc_compiler_get_descriptor_binding(compiler, reg, range, resource_type, is_uav_counter,
- &binding_address);
- vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, variable_id, &binding);
-}
-
static void vkd3d_dxbc_compiler_decorate_nonuniform(struct vkd3d_dxbc_compiler *compiler,
uint32_t expression_id)
{
@@ -2938,6 +2920,7 @@ static bool vkd3d_dxbc_compiler_get_register_name(char *buffer, unsigned int buf
return true;
}
+/* TODO: UAV counters: vkd3d_spirv_build_op_name(builder, counter_var_id, "u%u_counter", reg->idx[0].offset); */
static void vkd3d_dxbc_compiler_emit_register_debug_name(struct vkd3d_spirv_builder *builder,
uint32_t id, const struct vkd3d_shader_register *reg)
{
@@ -5596,7 +5579,7 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com
static uint32_t vkd3d_dxbc_compiler_build_descriptor_variable(struct vkd3d_dxbc_compiler *compiler,
SpvStorageClass storage_class, uint32_t type_id, const struct vkd3d_shader_register *reg,
const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type,
- struct vkd3d_descriptor_array_symbol *array_symbol)
+ bool is_uav_counter, struct vkd3d_descriptor_array_symbol *array_symbol)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
struct vkd3d_descriptor_binding_address binding_address;
@@ -5606,7 +5589,7 @@ static uint32_t vkd3d_dxbc_compiler_build_descriptor_variable(struct vkd3d_dxbc_
struct rb_entry *entry;
binding = vkd3d_dxbc_compiler_get_descriptor_binding(compiler, reg, range,
- resource_type, false, &binding_address);
+ resource_type, is_uav_counter, &binding_address);
array_symbol->binding_base_idx = binding_address.binding_base_idx;
if (binding.count == 1 && range->first == binding_address.binding_base_idx && range->last != ~0u
@@ -5697,7 +5680,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi
vkd3d_spirv_build_op_name(builder, struct_id, "cb%u_struct", cb->size);
var_id = vkd3d_dxbc_compiler_build_descriptor_variable(compiler, storage_class, struct_id,
- reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, &array_symbol);
+ reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, false, &array_symbol);
vkd3d_symbol_make_register(®_symbol, reg);
vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class,
@@ -5759,7 +5742,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com
type_id = vkd3d_spirv_get_op_type_sampler(builder);
var_id = vkd3d_dxbc_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg,
- &sampler->range, VKD3D_SHADER_RESOURCE_NONE, &array_symbol);
+ &sampler->range, VKD3D_SHADER_RESOURCE_NONE, false, &array_symbol);
vkd3d_symbol_make_register(®_symbol, reg);
vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class,
@@ -5930,6 +5913,8 @@ static void vkd3d_dxbc_compiler_emit_combined_sampler_declarations(struct vkd3d_
symbol.info.resource.structure_stride = structure_stride;
symbol.info.resource.raw = raw;
symbol.info.resource.uav_counter_id = 0;
+ symbol.info.resource.uav_counter_array.symbol = NULL;
+ symbol.info.resource.uav_counter_array.binding_base_idx = 0;
vkd3d_dxbc_compiler_put_symbol(compiler, &symbol);
}
}
@@ -5938,12 +5923,12 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type,
enum vkd3d_data_type resource_data_type, unsigned int structure_stride, bool raw)
{
- uint32_t counter_type_id, type_id, ptr_type_id, var_id, counter_var_id = 0;
+ struct vkd3d_descriptor_array_symbol array_symbol, counter_array_symbol = {NULL, 0};
+ uint32_t counter_type_id, type_id, var_id, counter_var_id = 0;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
SpvStorageClass storage_class = SpvStorageClassUniformConstant;
const struct vkd3d_shader_register *reg = &resource->reg.reg;
const struct vkd3d_spirv_resource_type *resource_type_info;
- struct vkd3d_descriptor_array_symbol array_symbol;
enum vkd3d_shader_component_type sampled_type;
struct vkd3d_symbol resource_symbol;
bool is_uav;
@@ -5988,7 +5973,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
}
var_id = vkd3d_dxbc_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg,
- &resource->range, resource_type, &array_symbol);
+ &resource->range, resource_type, false, &array_symbol);
if (is_uav)
{
@@ -6009,7 +5994,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
{
vkd3d_spirv_enable_capability(builder, SpvCapabilityAtomicStorage);
storage_class = SpvStorageClassAtomicCounter;
- ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, counter_type_id);
+ type_id = counter_type_id;
}
else if (compiler->ssbo_uavs)
{
@@ -6024,20 +6009,11 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
vkd3d_spirv_build_op_member_decorate1(builder, struct_id, 0, SpvDecorationOffset, 0);
storage_class = SpvStorageClassUniform;
- ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, struct_id);
- }
- else
- {
- ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id);
+ type_id = struct_id;
}
- counter_var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
- ptr_type_id, storage_class, 0);
-
- vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(compiler,
- counter_var_id, reg, &resource->range, resource_type, true);
-
- vkd3d_spirv_build_op_name(builder, counter_var_id, "u%u_counter", reg->idx[0].offset);
+ counter_var_id = vkd3d_dxbc_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg,
+ &resource->range, resource_type, true, &counter_array_symbol);
}
}
@@ -6051,6 +6027,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
resource_symbol.info.resource.structure_stride = structure_stride;
resource_symbol.info.resource.raw = raw;
resource_symbol.info.resource.uav_counter_id = counter_var_id;
+ resource_symbol.info.resource.uav_counter_array = counter_array_symbol;
vkd3d_dxbc_compiler_put_symbol(compiler, &resource_symbol);
}
@@ -8869,6 +8846,22 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c
}
else
{
+ if (resource_symbol->info.resource.uav_counter_array.symbol)
+ {
+ const struct vkd3d_symbol_descriptor_array_data *array_data;
+ uint32_t index_id;
+
+ index_id = vkd3d_dxbc_compiler_get_descriptor_index(compiler, &src->reg,
+ &resource_symbol->info.resource.uav_counter_array,
+ resource_symbol->info.resource.resource_type_info->resource_type);
+
+ array_data = &resource_symbol->info.resource.uav_counter_array.symbol->info.descriptor_array;
+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, array_data->storage_class,
+ array_data->contained_type_id);
+
+ counter_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, counter_id, &index_id, 1);
+ }
+
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassImage, type_id);
coordinate_id = sample_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder,
--
2.32.0
Nov. 10, 2021
[PATCH vkd3d v2 3/4] vkd3d-shader/spirv: Support runtime descriptor array offsets using push constants.
by Conor McCarthy
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
---
v2: Add a check for push constant offsets in
vkd3d_dxbc_compiler_build_descriptor_variable() omitted in the previous
version.
---
include/vkd3d_shader.h | 36 +++++++++++++++----
libs/vkd3d-shader/spirv.c | 71 ++++++++++++++++++++++++++++++++------
libs/vkd3d/state.c | 14 ++++++--
libs/vkd3d/vkd3d_private.h | 2 +-
4 files changed, 102 insertions(+), 21 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 4a51b3f4..791ac037 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -458,6 +458,12 @@ struct vkd3d_shader_transform_feedback_info
unsigned int buffer_stride_count;
};
+struct vkd3d_shader_descriptor_offset
+{
+ unsigned int static_offset;
+ unsigned int dynamic_offset_index;
+};
+
/**
* A chained structure containing descriptor offsets.
*
@@ -477,10 +483,28 @@ struct vkd3d_shader_descriptor_offset_info
const void *next;
/**
- * Pointer to an array of offsets into the descriptor arrays referenced by
- * the 'bindings' array in struct vkd3d_shader_interface_info. This allows
- * mapping multiple shader resource arrays to a single binding point in
- * the target environment.
+ * Byte offset within the push constants of an array of 32-bit
+ * descriptor array offsets. See the description of 'binding_offsets'
+ * below.
+ */
+ unsigned int descriptor_table_offset;
+ /** Size, in elements, of the descriptor table push constant array. */
+ unsigned int descriptor_table_count;
+
+ /**
+ * Pointer to an array of struct vkd3d_shader_descriptor_offset objects.
+ * The 'static_offset' field contains an offset into the descriptor arrays
+ * referenced by the 'bindings' array in struct vkd3d_shader_interface_info.
+ * This allows mapping multiple shader resource arrays to a single binding
+ * point in the target environment.
+ *
+ * 'dynamic_offset_index' in struct vkd3d_shader_descriptor_offset allows
+ * offsets to be set at runtime. The 32-bit descriptor table push constant
+ * at this index will be added to 'static_offset' to calculate the final
+ * binding offset.
+ *
+ * If runtime offsets are not required, set all 'dynamic_offset_index'
+ * values to \c ~0u and 'descriptor_table_count' to zero.
*
* For example, to map Direct3D constant buffer registers 'cb0[0:3]' and
* 'cb1[6:7]' to descriptors 8-12 and 4-5 in the Vulkan descriptor array in
@@ -508,7 +532,7 @@ struct vkd3d_shader_descriptor_offset_info
* This field may be NULL, in which case the corresponding offsets are
* specified to be 0.
*/
- const unsigned int *binding_offsets;
+ const struct vkd3d_shader_descriptor_offset *binding_offsets;
/**
* Pointer to an array of offsets into the descriptor arrays referenced by
@@ -517,7 +541,7 @@ struct vkd3d_shader_descriptor_offset_info
* not supported in this version of vkd3d-shader, and therefore this field
* must either be NULL or specify 0 offsets.
*/
- const unsigned int *uav_counter_offsets;
+ const struct vkd3d_shader_descriptor_offset *uav_counter_offsets;
};
/** The format of a shader to be compiled or scanned. */
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index bd551f66..869d7382 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1958,6 +1958,7 @@ struct vkd3d_symbol_descriptor_array
uint32_t ptr_type_id;
unsigned int set;
unsigned int binding;
+ unsigned int push_constant_index;
};
struct vkd3d_symbol_register_data
@@ -1996,6 +1997,12 @@ struct vkd3d_symbol_sampler_data
struct vkd3d_shader_register_range range;
};
+struct vkd3d_descriptor_binding_address
+{
+ unsigned int binding_base_idx;
+ unsigned int push_constant_index;
+};
+
struct vkd3d_symbol_descriptor_array_data
{
SpvStorageClass storage_class;
@@ -2242,7 +2249,9 @@ struct vkd3d_dxbc_compiler
struct vkd3d_shader_interface_info shader_interface;
struct vkd3d_shader_descriptor_offset_info offset_info;
+ unsigned int descriptor_offsets_member_idx;
struct vkd3d_push_constant_buffer_binding *push_constants;
+ unsigned int push_constants_var_id;
const struct vkd3d_shader_spirv_target_info *spirv_target_info;
bool after_declarations_section;
@@ -2561,11 +2570,11 @@ static struct vkd3d_string_buffer *vkd3d_shader_register_range_string(struct vkd
static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor_binding(
struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg,
const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type,
- bool is_uav_counter, unsigned int *binding_base_idx)
+ bool is_uav_counter, struct vkd3d_descriptor_binding_address *binding_address)
{
const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface;
unsigned int register_last = (range->last == ~0u) ? range->first : range->last;
- const unsigned int *binding_offsets = compiler->offset_info.binding_offsets;
+ const struct vkd3d_shader_descriptor_offset *binding_offsets = compiler->offset_info.binding_offsets;
enum vkd3d_shader_descriptor_type descriptor_type;
enum vkd3d_shader_binding_flag resource_type_flag;
struct vkd3d_shader_descriptor_binding binding;
@@ -2619,7 +2628,8 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
range->first, range->space, current->binding.count);
}
- *binding_base_idx = current->register_index;
+ binding_address->binding_base_idx = current->register_index;
+ binding_address->push_constant_index = ~0u;
return current->binding;
}
if (shader_interface->uav_counter_count)
@@ -2646,7 +2656,9 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
|| current->binding.count <= register_last - current->register_index)
continue;
- *binding_base_idx = current->register_index - (binding_offsets ? binding_offsets[i] : 0);
+ binding_address->binding_base_idx = current->register_index
+ - (binding_offsets ? binding_offsets[i].static_offset : 0);
+ binding_address->push_constant_index = binding_offsets ? binding_offsets[i].dynamic_offset_index : ~0u;
return current->binding;
}
if (shader_interface->binding_count)
@@ -2663,7 +2675,8 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
}
done:
- *binding_base_idx = range->first;
+ binding_address->binding_base_idx = range->first;
+ binding_address->push_constant_index = ~0u;
binding.set = 0;
binding.count = 1;
binding.binding = compiler->binding_idx++;
@@ -2684,10 +2697,10 @@ static void vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(struct vkd3d_dxb
enum vkd3d_shader_resource_type resource_type, bool is_uav_counter)
{
struct vkd3d_shader_descriptor_binding binding;
- unsigned int binding_base_idx; /* Value not used. */
+ struct vkd3d_descriptor_binding_address binding_address; /* Values not used. */
binding = vkd3d_dxbc_compiler_get_descriptor_binding(compiler, reg, range, resource_type, is_uav_counter,
- &binding_base_idx);
+ &binding_address);
vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, variable_id, &binding);
}
@@ -3255,10 +3268,11 @@ static uint32_t vkd3d_dxbc_compiler_get_descriptor_index(struct vkd3d_dxbc_compi
const struct vkd3d_shader_register *reg, const struct vkd3d_descriptor_array_symbol *array_symbol,
enum vkd3d_shader_resource_type resource_type)
{
+ const struct vkd3d_symbol_descriptor_array *array_key = &array_symbol->symbol->key.descriptor_array;
struct vkd3d_shader_register_index index = reg->idx[1];
uint32_t index_id;
- if (index.rel_addr)
+ if (index.rel_addr || array_key->push_constant_index != ~0u)
{
if (!vkd3d_dxbc_compiler_enable_descriptor_indexing(compiler, reg->type, resource_type))
{
@@ -3272,6 +3286,21 @@ static uint32_t vkd3d_dxbc_compiler_get_descriptor_index(struct vkd3d_dxbc_compi
index.offset -= array_symbol->binding_base_idx;
index_id = vkd3d_dxbc_compiler_emit_register_addressing(compiler, &index);
+ if (array_key->push_constant_index != ~0u && compiler->offset_info.descriptor_table_count)
+ {
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ uint32_t type_id, ptr_type_id, ptr_id, offset_id, index_ids[2];
+
+ index_ids[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, compiler->descriptor_offsets_member_idx);
+ index_ids[1] = vkd3d_dxbc_compiler_get_constant_uint(compiler, array_key->push_constant_index);
+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPushConstant, type_id);
+ ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id,
+ compiler->push_constants_var_id, index_ids, 2);
+ offset_id = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone);
+ index_id = vkd3d_spirv_build_op_iadd(builder, type_id, index_id, offset_id);
+ }
+
return index_id;
}
@@ -5489,7 +5518,7 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com
struct vkd3d_symbol reg_symbol;
uint32_t *member_ids;
- count = 0;
+ count = !!compiler->offset_info.descriptor_table_count;
for (i = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i)
{
const struct vkd3d_push_constant_buffer_binding *cb = &compiler->push_constants[i];
@@ -5518,6 +5547,16 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com
++j;
}
+ if (compiler->offset_info.descriptor_table_count)
+ {
+ uint32_t type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
+ length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, compiler->offset_info.descriptor_table_count);
+ member_ids[j] = vkd3d_spirv_build_op_type_array(builder, type_id, length_id);
+ vkd3d_spirv_build_op_decorate1(builder, member_ids[j], SpvDecorationArrayStride, 4);
+ compiler->descriptor_offsets_member_idx = j;
+ assert(j == count - 1);
+ }
+
struct_id = vkd3d_spirv_build_op_type_struct(builder, member_ids, count);
vkd3d_spirv_build_op_decorate(builder, struct_id, SpvDecorationBlock, NULL, 0);
vkd3d_spirv_build_op_name(builder, struct_id, "push_cb");
@@ -5526,6 +5565,7 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com
pointer_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, struct_id);
var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
pointer_type_id, storage_class, 0);
+ compiler->push_constants_var_id = var_id;
for (i = 0, j = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i)
{
@@ -5546,6 +5586,11 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com
++j;
}
+ if (compiler->offset_info.descriptor_table_count)
+ {
+ vkd3d_spirv_build_op_member_decorate1(builder, struct_id, compiler->descriptor_offsets_member_idx,
+ SpvDecorationOffset, compiler->offset_info.descriptor_table_offset);
+ }
}
static uint32_t vkd3d_dxbc_compiler_build_descriptor_variable(struct vkd3d_dxbc_compiler *compiler,
@@ -5554,15 +5599,18 @@ static uint32_t vkd3d_dxbc_compiler_build_descriptor_variable(struct vkd3d_dxbc_
struct vkd3d_descriptor_array_symbol *array_symbol)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ struct vkd3d_descriptor_binding_address binding_address;
struct vkd3d_shader_descriptor_binding binding;
uint32_t array_type_id, ptr_type_id, var_id;
struct vkd3d_symbol symbol;
struct rb_entry *entry;
binding = vkd3d_dxbc_compiler_get_descriptor_binding(compiler, reg, range,
- resource_type, false, &array_symbol->binding_base_idx);
+ resource_type, false, &binding_address);
+ array_symbol->binding_base_idx = binding_address.binding_base_idx;
- if (binding.count == 1 && range->first == array_symbol->binding_base_idx && range->last != ~0u)
+ if (binding.count == 1 && range->first == binding_address.binding_base_idx && range->last != ~0u
+ && binding_address.push_constant_index == ~0u)
{
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id);
var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
@@ -5586,6 +5634,7 @@ static uint32_t vkd3d_dxbc_compiler_build_descriptor_variable(struct vkd3d_dxbc_
symbol.key.descriptor_array.ptr_type_id = ptr_type_id;
symbol.key.descriptor_array.set = binding.set;
symbol.key.descriptor_array.binding = binding.binding;
+ symbol.key.descriptor_array.push_constant_index = binding_address.push_constant_index;
if ((entry = rb_get(&compiler->symbol_table, &symbol)))
{
array_symbol->symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index 413b0a30..fbfe7bb5 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -609,7 +609,8 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *
unsigned int descriptor_count, struct vkd3d_descriptor_set_context *context)
{
struct vkd3d_shader_resource_binding *mapping
- = &root_signature->descriptor_mapping[context->descriptor_index++];
+ = &root_signature->descriptor_mapping[context->descriptor_index];
+ struct vkd3d_shader_descriptor_offset *offset = &root_signature->descriptor_offsets[context->descriptor_index++];
mapping->type = descriptor_type;
mapping->register_space = register_space;
@@ -619,6 +620,8 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *
mapping->binding.set = root_signature->vk_set_count;
mapping->binding.binding = context->descriptor_binding++;
mapping->binding.count = descriptor_count;
+ offset->static_offset = 0;
+ offset->dynamic_offset_index = ~0u;
if (context->unbounded_offset != UINT_MAX)
d3d12_root_signature_append_descriptor_set_layout(root_signature, context, 0);
@@ -718,7 +721,7 @@ static void d3d12_root_signature_map_vk_unbounded_binding(struct d3d12_root_sign
enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context)
{
struct vkd3d_shader_resource_binding *mapping = &root_signature->descriptor_mapping[context->descriptor_index];
- unsigned int *offset = &root_signature->descriptor_offsets[context->descriptor_index++];
+ struct vkd3d_shader_descriptor_offset *offset = &root_signature->descriptor_offsets[context->descriptor_index++];
mapping->type = range->type;
mapping->register_space = range->register_space;
@@ -729,7 +732,8 @@ static void d3d12_root_signature_map_vk_unbounded_binding(struct d3d12_root_sign
|| range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) && !buffer_descriptor);
mapping->binding.binding = range->binding;
mapping->binding.count = range->vk_binding_count;
- *offset = descriptor_offset;
+ offset->static_offset = descriptor_offset;
+ offset->dynamic_offset_index = ~0u;
}
static void d3d12_root_signature_map_descriptor_unbounded_binding(struct d3d12_root_signature *root_signature,
@@ -1930,6 +1934,8 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
{
offset_info.type = VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO;
offset_info.next = NULL;
+ offset_info.descriptor_table_offset = 0;
+ offset_info.descriptor_table_count = 0;
offset_info.binding_offsets = root_signature->descriptor_offsets;
offset_info.uav_counter_offsets = NULL;
vkd3d_prepend_struct(&target_info, &offset_info);
@@ -2696,6 +2702,8 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
{
offset_info.type = VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO;
offset_info.next = NULL;
+ offset_info.descriptor_table_offset = 0;
+ offset_info.descriptor_table_count = 0;
offset_info.binding_offsets = root_signature->descriptor_offsets;
offset_info.uav_counter_offsets = NULL;
vkd3d_prepend_struct(&shader_interface, &offset_info);
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 23af9e32..e9631313 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -737,7 +737,7 @@ struct d3d12_root_signature
unsigned int binding_count;
struct vkd3d_shader_resource_binding *descriptor_mapping;
- unsigned int *descriptor_offsets;
+ struct vkd3d_shader_descriptor_offset *descriptor_offsets;
unsigned int root_constant_count;
struct vkd3d_shader_push_constant_buffer *root_constants;
--
2.32.0
Nov. 10, 2021