dxgi: Add feature level support.
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a2c57a2a8a
commit
ffce30bc31
@ -101,11 +101,23 @@ static HRESULT WINAPI layer_create(enum dxgi_device_layer_id id, void **layer_ba
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void WINAPI layer_set_feature_level(enum dxgi_device_layer_id id, void *device,
|
||||||
|
D3D_FEATURE_LEVEL feature_level)
|
||||||
|
{
|
||||||
|
TRACE("id %#x, device %p, feature_level %u.\n", id, device, feature_level);
|
||||||
|
|
||||||
|
if (id != DXGI_DEVICE_LAYER_D3D10_DEVICE)
|
||||||
|
{
|
||||||
|
WARN("Unknown layer id %#x.\n", id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT WINAPI D3D11CoreRegisterLayers(void)
|
HRESULT WINAPI D3D11CoreRegisterLayers(void)
|
||||||
{
|
{
|
||||||
static const struct dxgi_device_layer layers[] =
|
static const struct dxgi_device_layer layers[] =
|
||||||
{
|
{
|
||||||
{DXGI_DEVICE_LAYER_D3D10_DEVICE, layer_init, layer_get_size, layer_create},
|
{DXGI_DEVICE_LAYER_D3D10_DEVICE, layer_init, layer_get_size, layer_create, layer_set_feature_level},
|
||||||
};
|
};
|
||||||
|
|
||||||
DXGID3D10RegisterLayers(layers, sizeof(layers)/sizeof(*layers));
|
DXGID3D10RegisterLayers(layers, sizeof(layers)/sizeof(*layers));
|
||||||
@ -116,6 +128,7 @@ HRESULT WINAPI D3D11CoreRegisterLayers(void)
|
|||||||
HRESULT WINAPI D3D11CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter, UINT flags,
|
HRESULT WINAPI D3D11CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter, UINT flags,
|
||||||
const D3D_FEATURE_LEVEL *feature_levels, UINT levels, ID3D11Device **device)
|
const D3D_FEATURE_LEVEL *feature_levels, UINT levels, ID3D11Device **device)
|
||||||
{
|
{
|
||||||
|
static const D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_10_0;
|
||||||
IUnknown *dxgi_device;
|
IUnknown *dxgi_device;
|
||||||
HMODULE d3d11;
|
HMODULE d3d11;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
@ -126,7 +139,7 @@ HRESULT WINAPI D3D11CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapte
|
|||||||
FIXME("Ignoring feature levels.\n");
|
FIXME("Ignoring feature levels.\n");
|
||||||
|
|
||||||
d3d11 = GetModuleHandleA("d3d11.dll");
|
d3d11 = GetModuleHandleA("d3d11.dll");
|
||||||
hr = DXGID3D10CreateDevice(d3d11, factory, adapter, flags, 0, (void **)&dxgi_device);
|
hr = DXGID3D10CreateDevice(d3d11, factory, adapter, flags, &level, 1, (void **)&dxgi_device);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
WARN("Failed to create device, returning %#x.\n", hr);
|
WARN("Failed to create device, returning %#x.\n", hr);
|
||||||
|
@ -453,10 +453,12 @@ struct dxgi_device_layer
|
|||||||
UINT (WINAPI *get_size)(enum dxgi_device_layer_id id, struct layer_get_size_args *args, DWORD unknown0);
|
UINT (WINAPI *get_size)(enum dxgi_device_layer_id id, struct layer_get_size_args *args, DWORD unknown0);
|
||||||
HRESULT (WINAPI *create)(enum dxgi_device_layer_id id, void **layer_base, DWORD unknown0,
|
HRESULT (WINAPI *create)(enum dxgi_device_layer_id id, void **layer_base, DWORD unknown0,
|
||||||
void *device_object, REFIID riid, void **device_layer);
|
void *device_object, REFIID riid, void **device_layer);
|
||||||
|
void (WINAPI *set_feature_level)(enum dxgi_device_layer_id id, void *device,
|
||||||
|
D3D_FEATURE_LEVEL feature_level);
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, IDXGIAdapter *adapter,
|
HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, IDXGIAdapter *adapter,
|
||||||
UINT flags, void *unknown0, void **device);
|
unsigned int flags, const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count, void **device);
|
||||||
HRESULT WINAPI DXGID3D10RegisterLayers(const struct dxgi_device_layer *layers, UINT layer_count);
|
HRESULT WINAPI DXGID3D10RegisterLayers(const struct dxgi_device_layer *layers, UINT layer_count);
|
||||||
|
|
||||||
#endif /* __WINE_D3D11_PRIVATE_H */
|
#endif /* __WINE_D3D11_PRIVATE_H */
|
||||||
|
@ -200,6 +200,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc(IDXGIAdapter1 *iface, DXGI
|
|||||||
static HRESULT STDMETHODCALLTYPE dxgi_adapter_CheckInterfaceSupport(IDXGIAdapter1 *iface,
|
static HRESULT STDMETHODCALLTYPE dxgi_adapter_CheckInterfaceSupport(IDXGIAdapter1 *iface,
|
||||||
REFGUID guid, LARGE_INTEGER *umd_version)
|
REFGUID guid, LARGE_INTEGER *umd_version)
|
||||||
{
|
{
|
||||||
|
static const D3D_FEATURE_LEVEL feature_level = D3D_FEATURE_LEVEL_10_0;
|
||||||
struct dxgi_adapter *adapter = impl_from_IDXGIAdapter1(iface);
|
struct dxgi_adapter *adapter = impl_from_IDXGIAdapter1(iface);
|
||||||
struct wined3d_adapter_identifier adapter_id;
|
struct wined3d_adapter_identifier adapter_id;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
@ -214,7 +215,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_CheckInterfaceSupport(IDXGIAdapter
|
|||||||
return DXGI_ERROR_UNSUPPORTED;
|
return DXGI_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr = dxgi_check_d3d10_support(adapter->parent, adapter)))
|
if (!dxgi_check_feature_level_support(adapter->parent, adapter, &feature_level, 1))
|
||||||
return DXGI_ERROR_UNSUPPORTED;
|
return DXGI_ERROR_UNSUPPORTED;
|
||||||
|
|
||||||
if (umd_version)
|
if (umd_version)
|
||||||
|
@ -366,13 +366,15 @@ static const struct IWineDXGIDeviceVtbl dxgi_device_vtbl =
|
|||||||
};
|
};
|
||||||
|
|
||||||
HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *layer,
|
HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *layer,
|
||||||
IDXGIFactory *factory, IDXGIAdapter *adapter)
|
IDXGIFactory *factory, IDXGIAdapter *adapter,
|
||||||
|
const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count)
|
||||||
{
|
{
|
||||||
struct wined3d_device_parent *wined3d_device_parent;
|
struct wined3d_device_parent *wined3d_device_parent;
|
||||||
struct wined3d_swapchain_desc swapchain_desc;
|
struct wined3d_swapchain_desc swapchain_desc;
|
||||||
IWineDXGIDeviceParent *dxgi_device_parent;
|
IWineDXGIDeviceParent *dxgi_device_parent;
|
||||||
struct dxgi_adapter *dxgi_adapter;
|
struct dxgi_adapter *dxgi_adapter;
|
||||||
struct dxgi_factory *dxgi_factory;
|
struct dxgi_factory *dxgi_factory;
|
||||||
|
D3D_FEATURE_LEVEL feature_level;
|
||||||
void *layer_base;
|
void *layer_base;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
@ -416,12 +418,13 @@ HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *l
|
|||||||
wined3d_device_parent = IWineDXGIDeviceParent_get_wined3d_device_parent(dxgi_device_parent);
|
wined3d_device_parent = IWineDXGIDeviceParent_get_wined3d_device_parent(dxgi_device_parent);
|
||||||
IWineDXGIDeviceParent_Release(dxgi_device_parent);
|
IWineDXGIDeviceParent_Release(dxgi_device_parent);
|
||||||
|
|
||||||
if (FAILED(hr = dxgi_check_d3d10_support(dxgi_factory, dxgi_adapter)))
|
if (!(feature_level = dxgi_check_feature_level_support(dxgi_factory, dxgi_adapter,
|
||||||
|
feature_levels, level_count)))
|
||||||
{
|
{
|
||||||
IUnknown_Release(device->child_layer);
|
IUnknown_Release(device->child_layer);
|
||||||
wined3d_private_store_cleanup(&device->private_store);
|
wined3d_private_store_cleanup(&device->private_store);
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
return hr;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FIXME("Ignoring adapter type.\n");
|
FIXME("Ignoring adapter type.\n");
|
||||||
@ -437,6 +440,8 @@ HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *l
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layer->set_feature_level(layer->id, device->child_layer, feature_level);
|
||||||
|
|
||||||
memset(&swapchain_desc, 0, sizeof(swapchain_desc));
|
memset(&swapchain_desc, 0, sizeof(swapchain_desc));
|
||||||
swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD;
|
swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD;
|
||||||
swapchain_desc.device_window = dxgi_factory_get_device_window(dxgi_factory);
|
swapchain_desc.device_window = dxgi_factory_get_device_window(dxgi_factory);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@ stdcall CreateDXGIFactory(ptr ptr)
|
@ stdcall CreateDXGIFactory(ptr ptr)
|
||||||
@ stdcall CreateDXGIFactory1(ptr ptr)
|
@ stdcall CreateDXGIFactory1(ptr ptr)
|
||||||
@ stdcall DXGID3D10CreateDevice(ptr ptr ptr long ptr ptr)
|
@ stdcall DXGID3D10CreateDevice(ptr ptr ptr long ptr long ptr)
|
||||||
@ stdcall DXGID3D10RegisterLayers(ptr long)
|
@ stdcall DXGID3D10RegisterLayers(ptr long)
|
||||||
|
@ -125,7 +125,7 @@ static HRESULT register_d3d10core_layers(HMODULE d3d10core)
|
|||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, IDXGIAdapter *adapter,
|
HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, IDXGIAdapter *adapter,
|
||||||
UINT flags, void *unknown0, void **device)
|
unsigned int flags, const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count, void **device)
|
||||||
{
|
{
|
||||||
struct layer_get_size_args get_size_args;
|
struct layer_get_size_args get_size_args;
|
||||||
struct dxgi_device *dxgi_device;
|
struct dxgi_device *dxgi_device;
|
||||||
@ -134,8 +134,10 @@ HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, I
|
|||||||
DWORD count;
|
DWORD count;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("d3d10core %p, factory %p, adapter %p, flags %#x, unknown0 %p, device %p.\n",
|
TRACE("d3d10core %p, factory %p, adapter %p, flags %#x, feature_levels %p, level_count %u, device %p.\n",
|
||||||
d3d10core, factory, adapter, flags, unknown0, device);
|
d3d10core, factory, adapter, flags, feature_levels, level_count, device);
|
||||||
|
|
||||||
|
FIXME("Ignoring flags.\n");
|
||||||
|
|
||||||
hr = register_d3d10core_layers(d3d10core);
|
hr = register_d3d10core_layers(d3d10core);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
@ -178,7 +180,7 @@ HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, I
|
|||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = dxgi_device_init(dxgi_device, &d3d10_layer, factory, adapter);
|
hr = dxgi_device_init(dxgi_device, &d3d10_layer, factory, adapter, feature_levels, level_count);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
WARN("Failed to initialize device, hr %#x.\n", hr);
|
WARN("Failed to initialize device, hr %#x.\n", hr);
|
||||||
|
@ -73,6 +73,8 @@ struct dxgi_device_layer
|
|||||||
UINT (WINAPI *get_size)(enum dxgi_device_layer_id id, struct layer_get_size_args *args, DWORD unknown0);
|
UINT (WINAPI *get_size)(enum dxgi_device_layer_id id, struct layer_get_size_args *args, DWORD unknown0);
|
||||||
HRESULT (WINAPI *create)(enum dxgi_device_layer_id id, void **layer_base, DWORD unknown0,
|
HRESULT (WINAPI *create)(enum dxgi_device_layer_id id, void **layer_base, DWORD unknown0,
|
||||||
void *device_object, REFIID riid, void **device_layer);
|
void *device_object, REFIID riid, void **device_layer);
|
||||||
|
void (WINAPI *set_feature_level)(enum dxgi_device_layer_id id, void *device,
|
||||||
|
D3D_FEATURE_LEVEL feature_level);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TRACE helper functions */
|
/* TRACE helper functions */
|
||||||
@ -120,7 +122,8 @@ struct dxgi_device
|
|||||||
};
|
};
|
||||||
|
|
||||||
HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *layer,
|
HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *layer,
|
||||||
IDXGIFactory *factory, IDXGIAdapter *adapter) DECLSPEC_HIDDEN;
|
IDXGIFactory *factory, IDXGIAdapter *adapter,
|
||||||
|
const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* IDXGIOutput */
|
/* IDXGIOutput */
|
||||||
struct dxgi_output
|
struct dxgi_output
|
||||||
@ -174,6 +177,7 @@ struct dxgi_surface
|
|||||||
HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device,
|
HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device,
|
||||||
IUnknown *outer, struct wined3d_resource *wined3d_resource) DECLSPEC_HIDDEN;
|
IUnknown *outer, struct wined3d_resource *wined3d_resource) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT dxgi_check_d3d10_support(struct dxgi_factory *factory, struct dxgi_adapter *adapter) DECLSPEC_HIDDEN;
|
D3D_FEATURE_LEVEL dxgi_check_feature_level_support(struct dxgi_factory *factory, struct dxgi_adapter *adapter,
|
||||||
|
const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
#endif /* __WINE_DXGI_PRIVATE_H */
|
#endif /* __WINE_DXGI_PRIVATE_H */
|
||||||
|
@ -27,6 +27,23 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
|||||||
|
|
||||||
#define WINE_DXGI_TO_STR(x) case x: return #x
|
#define WINE_DXGI_TO_STR(x) case x: return #x
|
||||||
|
|
||||||
|
static const char *debug_feature_level(D3D_FEATURE_LEVEL feature_level)
|
||||||
|
{
|
||||||
|
switch (feature_level)
|
||||||
|
{
|
||||||
|
WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_9_1);
|
||||||
|
WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_9_2);
|
||||||
|
WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_9_3);
|
||||||
|
WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_10_0);
|
||||||
|
WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_10_1);
|
||||||
|
WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_11_0);
|
||||||
|
WINE_DXGI_TO_STR(D3D_FEATURE_LEVEL_11_1);
|
||||||
|
default:
|
||||||
|
FIXME("Unrecognized D3D_FEATURE_LEVEL %#x.\n", feature_level);
|
||||||
|
return "unrecognized";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char *debug_dxgi_format(DXGI_FORMAT format)
|
const char *debug_dxgi_format(DXGI_FORMAT format)
|
||||||
{
|
{
|
||||||
switch(format)
|
switch(format)
|
||||||
@ -455,8 +472,26 @@ HRESULT dxgi_set_private_data_interface(struct wined3d_private_store *store,
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT dxgi_check_d3d10_support(struct dxgi_factory *factory, struct dxgi_adapter *adapter)
|
D3D_FEATURE_LEVEL dxgi_check_feature_level_support(struct dxgi_factory *factory, struct dxgi_adapter *adapter,
|
||||||
|
const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count)
|
||||||
{
|
{
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
D3D_FEATURE_LEVEL feature_level;
|
||||||
|
unsigned int sm;
|
||||||
|
}
|
||||||
|
feature_levels_sm[] =
|
||||||
|
{
|
||||||
|
{D3D_FEATURE_LEVEL_11_1, 5},
|
||||||
|
{D3D_FEATURE_LEVEL_11_0, 5},
|
||||||
|
{D3D_FEATURE_LEVEL_10_1, 4},
|
||||||
|
{D3D_FEATURE_LEVEL_10_0, 4},
|
||||||
|
{D3D_FEATURE_LEVEL_9_3, 3},
|
||||||
|
{D3D_FEATURE_LEVEL_9_2, 2},
|
||||||
|
{D3D_FEATURE_LEVEL_9_1, 2},
|
||||||
|
};
|
||||||
|
D3D_FEATURE_LEVEL selected_feature_level = 0;
|
||||||
|
unsigned int i, j;
|
||||||
WINED3DCAPS caps;
|
WINED3DCAPS caps;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
@ -464,15 +499,39 @@ HRESULT dxgi_check_d3d10_support(struct dxgi_factory *factory, struct dxgi_adapt
|
|||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = wined3d_get_device_caps(factory->wined3d, adapter->ordinal, WINED3D_DEVICE_TYPE_HAL, &caps);
|
hr = wined3d_get_device_caps(factory->wined3d, adapter->ordinal, WINED3D_DEVICE_TYPE_HAL, &caps);
|
||||||
if (FAILED(hr) || caps.VertexShaderVersion < 4 || caps.PixelShaderVersion < 4)
|
|
||||||
{
|
|
||||||
FIXME_(winediag)("Direct3D 10 is not supported on this GPU with the current shader backend.\n");
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
hr = E_FAIL;
|
|
||||||
wined3d_mutex_unlock();
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
return S_OK;
|
if (FAILED(hr))
|
||||||
|
level_count = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < level_count; ++i)
|
||||||
|
{
|
||||||
|
for (j = 0; j < sizeof(feature_levels_sm) / sizeof(feature_levels_sm[0]); ++j)
|
||||||
|
{
|
||||||
|
if (feature_levels[i] == feature_levels_sm[j].feature_level)
|
||||||
|
{
|
||||||
|
if (caps.VertexShaderVersion >= feature_levels_sm[j].sm
|
||||||
|
&& caps.PixelShaderVersion >= feature_levels_sm[j].sm)
|
||||||
|
{
|
||||||
|
selected_feature_level = feature_levels[i];
|
||||||
|
TRACE("Choosing supported feature level %s (SM%u).\n",
|
||||||
|
debug_feature_level(selected_feature_level), feature_levels_sm[j].sm);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (selected_feature_level)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (j == sizeof(feature_levels_sm) / sizeof(feature_levels_sm[0]))
|
||||||
|
FIXME("Unexpected feature level %#x.\n", feature_levels[i]);
|
||||||
|
else
|
||||||
|
TRACE("Feature level %s not supported, trying next fallback if available.\n",
|
||||||
|
debug_feature_level(feature_levels[i]));
|
||||||
|
}
|
||||||
|
if (!selected_feature_level)
|
||||||
|
FIXME_(winediag)("None of the requested D3D feature levels is supported on this GPU "
|
||||||
|
"with the current shader backend.\n");
|
||||||
|
|
||||||
|
return selected_feature_level;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user