diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index fb308d0776a..c4180d6fc16 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -2423,10 +2423,41 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CheckFormatSupport(ID3D11Device *i static HRESULT STDMETHODCALLTYPE d3d11_device_CheckMultisampleQualityLevels(ID3D11Device *iface, DXGI_FORMAT format, UINT sample_count, UINT *quality_level_count) { - FIXME("iface %p, format %u, sample_count %u, quality_level_count %p stub!\n", - iface, format, sample_count, quality_level_count); + struct d3d_device *device = impl_from_ID3D11Device(iface); + struct wined3d_device_creation_parameters params; + struct wined3d *wined3d; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, format %s, sample_count %u, quality_level_count %p.\n", + iface, debug_dxgi_format(format), sample_count, quality_level_count); + + if (!quality_level_count) + return E_INVALIDARG; + + *quality_level_count = 0; + + if (!sample_count) + return E_FAIL; + if (sample_count == 1) + { + *quality_level_count = 1; + return S_OK; + } + if (sample_count > D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT) + return E_FAIL; + + wined3d_mutex_lock(); + wined3d = wined3d_device_get_wined3d(device->wined3d_device); + wined3d_device_get_creation_parameters(device->wined3d_device, ¶ms); + hr = wined3d_check_device_multisample_type(wined3d, params.adapter_idx, params.device_type, + wined3dformat_from_dxgi_format(format), TRUE, sample_count, quality_level_count); + wined3d_mutex_unlock(); + + if (hr == WINED3DERR_INVALIDCALL) + return E_INVALIDARG; + if (hr == WINED3DERR_NOTAVAILABLE) + return S_OK; + return hr; } static void STDMETHODCALLTYPE d3d11_device_CheckCounterInfo(ID3D11Device *iface, D3D11_COUNTER_INFO *info) diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 8ea0a766176..ca68e3c6cd5 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -4838,7 +4838,7 @@ static void test_multisample_init(void) } hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 2, &count); - todo_wine ok(SUCCEEDED(hr), "Failed to get quality levels, hr %#x.\n", hr); + ok(SUCCEEDED(hr), "Failed to get quality levels, hr %#x.\n", hr); if (!count) { skip("Multisampling not supported for DXGI_FORMAT_R8G8B8A8_UNORM, skipping tests.\n"); @@ -4870,7 +4870,6 @@ static void test_multisample_init(void) hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &multi); ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); - ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); ID3D11DeviceContext_ResolveSubresource(context, (ID3D11Resource *)backbuffer, 0, (ID3D11Resource *)multi, 0, DXGI_FORMAT_R8G8B8A8_UNORM); @@ -4890,7 +4889,7 @@ static void test_multisample_init(void) break; } release_texture_readback(&rb); - ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y); + todo_wine ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y); ID3D11DeviceContext_Release(context); ID3D11RenderTargetView_Release(rtview); diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index 0ca0dd358d4..3ff0c7a9e8b 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -289,6 +289,9 @@ static HRESULT WINAPI d3d8_CheckDeviceMultiSampleType(IDirect3D8 *iface, UINT ad TRACE("iface %p, adapter %u, device_type %#x, format %#x, windowed %#x, multisample_type %#x.\n", iface, adapter, device_type, format, windowed, multisample_type); + if (multisample_type > D3DMULTISAMPLE_16_SAMPLES) + return D3DERR_INVALIDCALL; + wined3d_mutex_lock(); hr = wined3d_check_device_multisample_type(d3d8->wined3d, adapter, device_type, wined3dformat_from_d3dformat(format), windowed, diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c index fb096c43afe..93e8631a010 100644 --- a/dlls/d3d9/directx.c +++ b/dlls/d3d9/directx.c @@ -305,6 +305,9 @@ static HRESULT WINAPI d3d9_CheckDeviceMultiSampleType(IDirect3D9Ex *iface, UINT TRACE("iface %p, adapter %u, device_type %#x, format %#x, windowed %#x, multisample_type %#x, levels %p.\n", iface, adapter, device_type, format, windowed, multisample_type, levels); + if (multisample_type > D3DMULTISAMPLE_16_SAMPLES) + return D3DERR_INVALIDCALL; + wined3d_mutex_lock(); hr = wined3d_check_device_multisample_type(d3d9->wined3d, adapter, device_type, wined3dformat_from_d3dformat(format), windowed, multisample_type, levels); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 8f39c3bdf87..039a867c79c 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4923,6 +4923,13 @@ void CDECL wined3d_device_get_creation_parameters(const struct wined3d_device *d *parameters = device->create_parms; } +struct wined3d * CDECL wined3d_device_get_wined3d(const struct wined3d_device *device) +{ + TRACE("device %p.\n", device); + + return device->wined3d; +} + void CDECL wined3d_device_set_gamma_ramp(const struct wined3d_device *device, UINT swapchain_idx, DWORD flags, const struct wined3d_gamma_ramp *ramp) { diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index c7b63f1b24f..1407da6a826 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -4421,8 +4421,13 @@ HRESULT CDECL wined3d_check_device_multisample_type(const struct wined3d *wined3 return WINED3DERR_INVALIDCALL; if (surface_format_id == WINED3DFMT_UNKNOWN) return WINED3DERR_INVALIDCALL; - if (multisample_type < WINED3D_MULTISAMPLE_NONE || multisample_type > WINED3D_MULTISAMPLE_16_SAMPLES) + if (multisample_type < WINED3D_MULTISAMPLE_NONE) return WINED3DERR_INVALIDCALL; + if (multisample_type > WINED3D_MULTISAMPLE_16_SAMPLES) + { + FIXME("multisample_type %u not handled yet.\n", multisample_type); + return WINED3DERR_NOTAVAILABLE; + } if (multisample_type && !(format->multisample_types & 1u << (multisample_type - 1))) hr = WINED3DERR_NOTAVAILABLE; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 8df2d374cc6..86d03f03bc9 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -99,6 +99,7 @@ @ cdecl wined3d_device_get_vs_consts_i(ptr long ptr long) @ cdecl wined3d_device_get_vs_resource_view(ptr long) @ cdecl wined3d_device_get_vs_sampler(ptr long) +@ cdecl wined3d_device_get_wined3d(ptr) @ cdecl wined3d_device_incref(ptr) @ cdecl wined3d_device_init_3d(ptr ptr) @ cdecl wined3d_device_init_gdi(ptr ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index ebb1338ed27..8f9d80af4a2 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2223,6 +2223,7 @@ HRESULT __cdecl wined3d_device_get_vs_consts_i(const struct wined3d_device *devi struct wined3d_shader_resource_view * __cdecl wined3d_device_get_vs_resource_view(const struct wined3d_device *device, UINT idx); struct wined3d_sampler * __cdecl wined3d_device_get_vs_sampler(const struct wined3d_device *device, UINT idx); +struct wined3d * __cdecl wined3d_device_get_wined3d(const struct wined3d_device *device); ULONG __cdecl wined3d_device_incref(struct wined3d_device *device); HRESULT __cdecl wined3d_device_init_3d(struct wined3d_device *device, struct wined3d_swapchain_desc *swapchain_desc); HRESULT __cdecl wined3d_device_init_gdi(struct wined3d_device *device, struct wined3d_swapchain_desc *swapchain_desc);