Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- v2: Supersede 180028~180032. Fix test failures. Style changes.
dlls/d3d8/directx.c | 7 ++++++- dlls/d3d9/directx.c | 20 ++++++++++++++++---- dlls/ddraw/ddraw.c | 16 +++++++++++++++- dlls/ddraw/ddraw_private.h | 2 ++ dlls/dxgi/output.c | 6 +++--- dlls/wined3d/directx.c | 23 +++++++++++++---------- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 3 +++ include/wine/wined3d.h | 6 +++--- 9 files changed, 62 insertions(+), 23 deletions(-)
diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index 0f283b55354..7e9b72eea30 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -150,13 +150,18 @@ static HRESULT WINAPI d3d8_EnumAdapterModes(IDirect3D8 *iface, UINT adapter, UIN { struct d3d8 *d3d8 = impl_from_IDirect3D8(iface); struct wined3d_display_mode wined3d_mode; + unsigned int output_idx; HRESULT hr;
TRACE("iface %p, adapter %u, mode_idx %u, mode %p.\n", iface, adapter, mode_idx, mode);
+ output_idx = adapter; + if (output_idx >= d3d8->wined3d_output_count) + return D3DERR_INVALIDCALL; + wined3d_mutex_lock(); - hr = wined3d_enum_adapter_modes(d3d8->wined3d, adapter, WINED3DFMT_UNKNOWN, + hr = wined3d_output_get_mode(d3d8->wined3d_outputs[output_idx], WINED3DFMT_UNKNOWN, WINED3D_SCANLINE_ORDERING_UNKNOWN, mode_idx, &wined3d_mode); wined3d_mutex_unlock();
diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c index 3e9fabf758b..00632019c7d 100644 --- a/dlls/d3d9/directx.c +++ b/dlls/d3d9/directx.c @@ -170,17 +170,23 @@ static HRESULT WINAPI d3d9_EnumAdapterModes(IDirect3D9Ex *iface, UINT adapter, { struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface); struct wined3d_display_mode wined3d_mode; + unsigned int output_idx; HRESULT hr;
TRACE("iface %p, adapter %u, format %#x, mode_idx %u, mode %p.\n", iface, adapter, format, mode_idx, mode);
+ output_idx = adapter; + if (output_idx >= d3d9->wined3d_output_count) + return D3DERR_INVALIDCALL; + if (format != D3DFMT_X8R8G8B8 && format != D3DFMT_R5G6B5) return D3DERR_INVALIDCALL;
wined3d_mutex_lock(); - hr = wined3d_enum_adapter_modes(d3d9->wined3d, adapter, wined3dformat_from_d3dformat(format), - WINED3D_SCANLINE_ORDERING_UNKNOWN, mode_idx, &wined3d_mode); + hr = wined3d_output_get_mode(d3d9->wined3d_outputs[output_idx], + wined3dformat_from_d3dformat(format), WINED3D_SCANLINE_ORDERING_UNKNOWN, mode_idx, + &wined3d_mode); wined3d_mutex_unlock();
if (SUCCEEDED(hr)) @@ -454,17 +460,23 @@ static HRESULT WINAPI d3d9_EnumAdapterModesEx(IDirect3D9Ex *iface, { struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface); struct wined3d_display_mode wined3d_mode; + unsigned int output_idx; HRESULT hr;
TRACE("iface %p, adapter %u, filter %p, mode_idx %u, mode %p.\n", iface, adapter, filter, mode_idx, mode);
+ output_idx = adapter; + if (output_idx >= d3d9->wined3d_output_count) + return D3DERR_INVALIDCALL; + if (filter->Format != D3DFMT_X8R8G8B8 && filter->Format != D3DFMT_R5G6B5) return D3DERR_INVALIDCALL;
wined3d_mutex_lock(); - hr = wined3d_enum_adapter_modes(d3d9->wined3d, adapter, wined3dformat_from_d3dformat(filter->Format), - filter->ScanLineOrdering, mode_idx, &wined3d_mode); + hr = wined3d_output_get_mode(d3d9->wined3d_outputs[output_idx], + wined3dformat_from_d3dformat(filter->Format), filter->ScanLineOrdering, mode_idx, + &wined3d_mode); wined3d_mutex_unlock();
if (SUCCEEDED(hr)) diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index d744df8c918..9f51cd2ca6f 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -2404,7 +2404,7 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags, for(fmt = 0; fmt < ARRAY_SIZE(checkFormatList); fmt++) { modenum = 0; - while (wined3d_enum_adapter_modes(ddraw->wined3d, WINED3DADAPTER_DEFAULT, checkFormatList[fmt], + while (wined3d_output_get_mode(ddraw->wined3d_output, checkFormatList[fmt], WINED3D_SCANLINE_ORDERING_UNKNOWN, modenum++, &mode) == WINED3D_OK) { BOOL found = FALSE; @@ -5003,6 +5003,20 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de } }
+ if (!(ddraw->wined3d_adapter = wined3d_get_adapter(ddraw->wined3d, WINED3DADAPTER_DEFAULT))) + { + WARN("Failed to get the default wined3d adapter.\n"); + wined3d_decref(ddraw->wined3d); + return E_FAIL; + } + + if (!(ddraw->wined3d_output = wined3d_adapter_get_output(ddraw->wined3d_adapter, 0))) + { + WARN("Failed to get the default wined3d output.\n"); + wined3d_decref(ddraw->wined3d); + return E_FAIL; + } + if (FAILED(hr = wined3d_get_device_caps(ddraw->wined3d, WINED3DADAPTER_DEFAULT, device_type, &caps))) { ERR("Failed to get device caps, hr %#x.\n", hr); diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 42a7a85e4ec..515a622e37a 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -94,6 +94,8 @@ struct ddraw LONG ref7, ref4, ref2, ref3, ref1, numIfaces;
struct wined3d *wined3d; + struct wined3d_adapter *wined3d_adapter; + struct wined3d_output *wined3d_output; struct wined3d_device *wined3d_device; DWORD flags; LONG device_state; diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c index 866bcb2f7fa..063d72e13fa 100644 --- a/dlls/dxgi/output.c +++ b/dlls/dxgi/output.c @@ -143,10 +143,10 @@ static HRESULT dxgi_output_get_display_mode_list(struct dxgi_output *output,
for (i = 0; i < *mode_count; ++i) { - if (FAILED(hr = wined3d_enum_adapter_modes(wined3d, output->adapter->ordinal, - wined3d_format, WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &mode))) + if (FAILED(hr = wined3d_output_get_mode(output->wined3d_output, wined3d_format, + WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &mode))) { - WARN("Failed to enum adapter mode %u, hr %#x.\n", i, hr); + WARN("Failed to get output mode %u, hr %#x.\n", i, hr); wined3d_mutex_unlock(); return hr; } diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index cf8616310fc..66877350883 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -116,7 +116,8 @@ static void wined3d_output_cleanup(const struct wined3d_output *output) D3DKMTCloseAdapter(&close_adapter_desc); }
-static HRESULT wined3d_output_init(struct wined3d_output *output, const WCHAR *device_name) +static HRESULT wined3d_output_init(struct wined3d_output *output, struct wined3d_adapter *adapter, + const WCHAR *device_name) { D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_desc; D3DKMT_CREATEDEVICE create_device_desc = {{0}}; @@ -136,6 +137,8 @@ static HRESULT wined3d_output_init(struct wined3d_output *output, const WCHAR *d return E_FAIL; }
+ lstrcpyW(output->device_name, device_name); + output->adapter = adapter; output->kmt_adapter = open_adapter_desc.hAdapter; output->kmt_device = create_device_desc.hDevice; output->vidpn_source_id = open_adapter_desc.VidPnSourceId; @@ -1002,9 +1005,9 @@ UINT CDECL wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT ad }
/* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */ -HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT adapter_idx, +HRESULT CDECL wined3d_output_get_mode(const struct wined3d_output *output, enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering, - UINT mode_idx, struct wined3d_display_mode *mode) + unsigned int mode_idx, struct wined3d_display_mode *mode) { const struct wined3d_adapter *adapter; const struct wined3d_format *format; @@ -1013,13 +1016,13 @@ HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT ada UINT i = 0; int j = 0;
- TRACE("wined3d %p, adapter_idx %u, format %s, scanline_ordering %#x, mode_idx %u, mode %p.\n", - wined3d, adapter_idx, debug_d3dformat(format_id), scanline_ordering, mode_idx, mode); + TRACE("output %p, format %s, scanline_ordering %#x, mode_idx %u, mode %p.\n", + output, debug_d3dformat(format_id), scanline_ordering, mode_idx, mode);
- if (!mode || adapter_idx >= wined3d->adapter_count) + if (!mode) return WINED3DERR_INVALIDCALL;
- adapter = wined3d->adapters[adapter_idx]; + adapter = output->adapter; format = wined3d_get_format(adapter, format_id, WINED3D_BIND_RENDER_TARGET); format_bits = format->byte_count * CHAR_BIT;
@@ -1028,7 +1031,7 @@ HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT ada
while (i <= mode_idx) { - if (!EnumDisplaySettingsExW(adapter->device_name, j++, &m, 0)) + if (!EnumDisplaySettingsExW(output->device_name, j++, &m, 0)) { WARN("Invalid mode_idx %u.\n", mode_idx); return WINED3DERR_INVALIDCALL; @@ -1107,7 +1110,7 @@ HRESULT CDECL wined3d_find_closest_matching_adapter_mode(const struct wined3d *w
for (i = 0; i < mode_count; ++i) { - if (FAILED(hr = wined3d_enum_adapter_modes(wined3d, adapter_idx, + if (FAILED(hr = wined3d_output_get_mode(&wined3d->adapters[adapter_idx]->outputs[0], mode->format_id, WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &modes[i]))) { heap_free(matching_modes); @@ -2851,7 +2854,7 @@ BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int ordinal, return FALSE; }
- if (FAILED(hr = wined3d_output_init(&adapter->outputs[0], adapter->device_name))) + if (FAILED(hr = wined3d_output_init(&adapter->outputs[0], adapter, display_device.DeviceName))) { ERR("Failed to initialise output, hr %#x.\n", hr); goto done; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index c891c446080..7af7a8615f9 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -9,7 +9,6 @@ @ cdecl wined3d_check_device_type(ptr long long long long long) @ cdecl wined3d_create(long) @ cdecl wined3d_decref(ptr) -@ cdecl wined3d_enum_adapter_modes(ptr long long long long ptr) @ cdecl wined3d_find_closest_matching_adapter_mode(ptr long ptr) @ cdecl wined3d_get_adapter(ptr long) @ cdecl wined3d_get_adapter_count(ptr) @@ -178,6 +177,7 @@ @ cdecl wined3d_device_update_texture(ptr ptr ptr) @ cdecl wined3d_device_validate_device(ptr ptr)
+@ cdecl wined3d_output_get_mode(ptr long long long ptr) @ cdecl wined3d_output_release_ownership(ptr) @ cdecl wined3d_output_take_ownership(ptr long)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 1a23b9e4435..4c7ea1f1628 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2898,6 +2898,9 @@ struct wined3d_adapter_ops
struct wined3d_output { + WCHAR device_name[CCHDEVICENAME]; + struct wined3d_adapter *adapter; + D3DKMT_HANDLE kmt_adapter; D3DKMT_HANDLE kmt_device; D3DDDI_VIDEO_PRESENT_SOURCE_ID vidpn_source_id; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index b724424bce1..893fb7409e0 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2258,9 +2258,6 @@ HRESULT __cdecl wined3d_check_device_type(const struct wined3d *wined3d, UINT ad enum wined3d_format_id backbuffer_format_id, BOOL windowed); struct wined3d * __cdecl wined3d_create(DWORD flags); ULONG __cdecl wined3d_decref(struct wined3d *wined3d); -HRESULT __cdecl wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT adapter_idx, - enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering, - UINT mode_idx, struct wined3d_display_mode *mode); HRESULT __cdecl wined3d_find_closest_matching_adapter_mode(const struct wined3d *wined3d, unsigned int adapter_idx, struct wined3d_display_mode *mode); struct wined3d_adapter * __cdecl wined3d_get_adapter(const struct wined3d *wined3d, @@ -2529,6 +2526,9 @@ HRESULT __cdecl wined3d_device_update_texture(struct wined3d_device *device, struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture); HRESULT __cdecl wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes);
+HRESULT __cdecl wined3d_output_get_mode(const struct wined3d_output *output, + enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering, + unsigned int mode_idx, struct wined3d_display_mode *mode); void __cdecl wined3d_output_release_ownership(const struct wined3d_output *output); HRESULT __cdecl wined3d_output_take_ownership(const struct wined3d_output *output, BOOL exclusive);