mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 03:54:46 +00:00
dxgi: Introduce IWineDXGIDeviceParent::register_swapchain_texture() and use it in IDXGIDevice::CreateSurface().
Instead of having d3d11 create the wined3d texture, create it in dxgi instead, and let d3d11 create a d3d_texture2d object to wrap it. This is a step towards getting rid of the create_swapchain_texture() callback, which is mildly difficult to work with and conceptually complex.
This commit is contained in:
parent
f443b9e042
commit
4413e94908
|
@ -148,7 +148,8 @@ static inline struct d3d_texture2d *impl_from_ID3D11Texture2D(ID3D11Texture2D *i
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DESC *desc,
|
HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DESC *desc,
|
||||||
const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture2d **texture) DECLSPEC_HIDDEN;
|
struct wined3d_texture *wined3d_texture,
|
||||||
|
const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture2d **out) DECLSPEC_HIDDEN;
|
||||||
struct d3d_texture2d *unsafe_impl_from_ID3D11Texture2D(ID3D11Texture2D *iface) DECLSPEC_HIDDEN;
|
struct d3d_texture2d *unsafe_impl_from_ID3D11Texture2D(ID3D11Texture2D *iface) DECLSPEC_HIDDEN;
|
||||||
struct d3d_texture2d *unsafe_impl_from_ID3D10Texture2D(ID3D10Texture2D *iface) DECLSPEC_HIDDEN;
|
struct d3d_texture2d *unsafe_impl_from_ID3D10Texture2D(ID3D10Texture2D *iface) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
|
@ -3335,7 +3335,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateTexture2D(ID3D11Device2 *ifa
|
||||||
|
|
||||||
TRACE("iface %p, desc %p, data %p, texture %p.\n", iface, desc, data, texture);
|
TRACE("iface %p, desc %p, data %p, texture %p.\n", iface, desc, data, texture);
|
||||||
|
|
||||||
if (FAILED(hr = d3d_texture2d_create(device, desc, data, &object)))
|
if (FAILED(hr = d3d_texture2d_create(device, desc, NULL, data, &object)))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
*texture = &object->ID3D11Texture2D_iface;
|
*texture = &object->ID3D11Texture2D_iface;
|
||||||
|
@ -6021,7 +6021,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture2D(ID3D10Device1 *ifa
|
||||||
d3d11_desc.CPUAccessFlags = d3d11_cpu_access_flags_from_d3d10_cpu_access_flags(desc->CPUAccessFlags);
|
d3d11_desc.CPUAccessFlags = d3d11_cpu_access_flags_from_d3d10_cpu_access_flags(desc->CPUAccessFlags);
|
||||||
d3d11_desc.MiscFlags = d3d11_resource_misc_flags_from_d3d10_resource_misc_flags(desc->MiscFlags);
|
d3d11_desc.MiscFlags = d3d11_resource_misc_flags_from_d3d10_resource_misc_flags(desc->MiscFlags);
|
||||||
|
|
||||||
if (FAILED(hr = d3d_texture2d_create(device, &d3d11_desc, (const D3D11_SUBRESOURCE_DATA *)data, &object)))
|
if (FAILED(hr = d3d_texture2d_create(device, &d3d11_desc, NULL, (const D3D11_SUBRESOURCE_DATA *)data, &object)))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
*texture = &object->ID3D10Texture2D_iface;
|
*texture = &object->ID3D10Texture2D_iface;
|
||||||
|
@ -6780,6 +6780,46 @@ static struct wined3d_device_parent * STDMETHODCALLTYPE dxgi_device_parent_get_w
|
||||||
return &device->device_parent;
|
return &device->device_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT STDMETHODCALLTYPE dxgi_device_parent_register_swapchain_texture(IWineDXGIDeviceParent *iface,
|
||||||
|
struct wined3d_texture *wined3d_texture, unsigned int texture_flags, IDXGISurface **ret_surface)
|
||||||
|
{
|
||||||
|
struct d3d_device *device = device_from_dxgi_device_parent(iface);
|
||||||
|
struct wined3d_resource_desc wined3d_desc;
|
||||||
|
struct d3d_texture2d *object;
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
wined3d_resource_get_desc(wined3d_texture_get_resource(wined3d_texture), &wined3d_desc);
|
||||||
|
|
||||||
|
desc.Width = wined3d_desc.width;
|
||||||
|
desc.Height = wined3d_desc.height;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.ArraySize = 1;
|
||||||
|
desc.Format = dxgi_format_from_wined3dformat(wined3d_desc.format);
|
||||||
|
desc.SampleDesc.Count = wined3d_desc.multisample_type ? wined3d_desc.multisample_type : 1;
|
||||||
|
desc.SampleDesc.Quality = wined3d_desc.multisample_quality;
|
||||||
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
desc.BindFlags = d3d11_bind_flags_from_wined3d(wined3d_desc.bind_flags);
|
||||||
|
desc.CPUAccessFlags = 0;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
|
||||||
|
if (texture_flags & WINED3D_TEXTURE_CREATE_GET_DC)
|
||||||
|
{
|
||||||
|
desc.MiscFlags |= D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
|
||||||
|
texture_flags &= ~WINED3D_TEXTURE_CREATE_GET_DC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture_flags)
|
||||||
|
FIXME("Unhandled flags %#x.\n", texture_flags);
|
||||||
|
|
||||||
|
if (FAILED(hr = d3d_texture2d_create(device, &desc, wined3d_texture, NULL, &object)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
hr = IUnknown_QueryInterface(object->dxgi_resource, &IID_IDXGISurface, (void **)ret_surface);
|
||||||
|
ID3D11Texture2D_Release(&object->ID3D11Texture2D_iface);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct IWineDXGIDeviceParentVtbl d3d_dxgi_device_parent_vtbl =
|
static const struct IWineDXGIDeviceParentVtbl d3d_dxgi_device_parent_vtbl =
|
||||||
{
|
{
|
||||||
/* IUnknown methods */
|
/* IUnknown methods */
|
||||||
|
@ -6788,6 +6828,7 @@ static const struct IWineDXGIDeviceParentVtbl d3d_dxgi_device_parent_vtbl =
|
||||||
dxgi_device_parent_Release,
|
dxgi_device_parent_Release,
|
||||||
/* IWineDXGIDeviceParent methods */
|
/* IWineDXGIDeviceParent methods */
|
||||||
dxgi_device_parent_get_wined3d_device_parent,
|
dxgi_device_parent_get_wined3d_device_parent,
|
||||||
|
dxgi_device_parent_register_swapchain_texture,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct d3d_device *device_from_wined3d_device_parent(struct wined3d_device_parent *device_parent)
|
static inline struct d3d_device *device_from_wined3d_device_parent(struct wined3d_device_parent *device_parent)
|
||||||
|
|
|
@ -956,11 +956,9 @@ static BOOL validate_texture2d_desc(const D3D11_TEXTURE2D_DESC *desc, D3D_FEATUR
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DESC *desc,
|
HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DESC *desc,
|
||||||
const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture2d **out)
|
struct wined3d_texture *wined3d_texture, const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture2d **out)
|
||||||
{
|
{
|
||||||
struct wined3d_resource_desc wined3d_desc;
|
|
||||||
struct d3d_texture2d *texture;
|
struct d3d_texture2d *texture;
|
||||||
unsigned int levels;
|
|
||||||
BOOL needs_surface;
|
BOOL needs_surface;
|
||||||
DWORD flags = 0;
|
DWORD flags = 0;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -980,38 +978,51 @@ HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DE
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
texture->desc = *desc;
|
texture->desc = *desc;
|
||||||
|
|
||||||
wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
|
if (wined3d_texture)
|
||||||
wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format);
|
|
||||||
wined3d_desc.multisample_type = desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE;
|
|
||||||
wined3d_desc.multisample_quality = desc->SampleDesc.Quality;
|
|
||||||
wined3d_desc.usage = wined3d_usage_from_d3d11(desc->Usage);
|
|
||||||
wined3d_desc.bind_flags = wined3d_bind_flags_from_d3d11(desc->BindFlags, desc->MiscFlags);
|
|
||||||
wined3d_desc.access = wined3d_access_from_d3d11(desc->Usage,
|
|
||||||
desc->Usage == D3D11_USAGE_DEFAULT ? 0 : desc->CPUAccessFlags);
|
|
||||||
wined3d_desc.width = desc->Width;
|
|
||||||
wined3d_desc.height = desc->Height;
|
|
||||||
wined3d_desc.depth = 1;
|
|
||||||
wined3d_desc.size = 0;
|
|
||||||
|
|
||||||
levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(desc->Width, desc->Height)) + 1;
|
|
||||||
|
|
||||||
if (desc->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE)
|
|
||||||
flags |= WINED3D_TEXTURE_CREATE_GET_DC;
|
|
||||||
if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
|
|
||||||
flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
|
|
||||||
|
|
||||||
if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc,
|
|
||||||
desc->ArraySize, levels, flags, (struct wined3d_sub_resource_data *)data,
|
|
||||||
texture, &d3d_texture2d_wined3d_parent_ops, &texture->wined3d_texture)))
|
|
||||||
{
|
{
|
||||||
WARN("Failed to create wined3d texture, hr %#lx.\n", hr);
|
wined3d_resource_set_parent(wined3d_texture_get_resource(wined3d_texture),
|
||||||
free(texture);
|
texture, &d3d_texture2d_wined3d_parent_ops);
|
||||||
wined3d_mutex_unlock();
|
wined3d_texture_incref(wined3d_texture);
|
||||||
if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DERR_INVALIDCALL)
|
texture->wined3d_texture = wined3d_texture;
|
||||||
hr = E_INVALIDARG;
|
}
|
||||||
return hr;
|
else
|
||||||
|
{
|
||||||
|
struct wined3d_resource_desc wined3d_desc;
|
||||||
|
unsigned int levels;
|
||||||
|
|
||||||
|
wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
|
||||||
|
wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format);
|
||||||
|
wined3d_desc.multisample_type = desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE;
|
||||||
|
wined3d_desc.multisample_quality = desc->SampleDesc.Quality;
|
||||||
|
wined3d_desc.usage = wined3d_usage_from_d3d11(desc->Usage);
|
||||||
|
wined3d_desc.bind_flags = wined3d_bind_flags_from_d3d11(desc->BindFlags, desc->MiscFlags);
|
||||||
|
wined3d_desc.access = wined3d_access_from_d3d11(desc->Usage,
|
||||||
|
desc->Usage == D3D11_USAGE_DEFAULT ? 0 : desc->CPUAccessFlags);
|
||||||
|
wined3d_desc.width = desc->Width;
|
||||||
|
wined3d_desc.height = desc->Height;
|
||||||
|
wined3d_desc.depth = 1;
|
||||||
|
wined3d_desc.size = 0;
|
||||||
|
|
||||||
|
levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(desc->Width, desc->Height)) + 1;
|
||||||
|
|
||||||
|
if (desc->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE)
|
||||||
|
flags |= WINED3D_TEXTURE_CREATE_GET_DC;
|
||||||
|
if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
|
||||||
|
flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS;
|
||||||
|
|
||||||
|
if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc,
|
||||||
|
desc->ArraySize, levels, flags, (struct wined3d_sub_resource_data *)data,
|
||||||
|
texture, &d3d_texture2d_wined3d_parent_ops, &texture->wined3d_texture)))
|
||||||
|
{
|
||||||
|
WARN("Failed to create wined3d texture, hr %#lx.\n", hr);
|
||||||
|
free(texture);
|
||||||
|
wined3d_mutex_unlock();
|
||||||
|
if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DERR_INVALIDCALL)
|
||||||
|
hr = E_INVALIDARG;
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
texture->desc.MipLevels = levels;
|
||||||
}
|
}
|
||||||
texture->desc.MipLevels = levels;
|
|
||||||
|
|
||||||
needs_surface = desc->MipLevels == 1 && desc->ArraySize == 1;
|
needs_surface = desc->MipLevels == 1 && desc->ArraySize == 1;
|
||||||
hr = d3d_device_create_dxgi_resource((IUnknown *)&device->ID3D10Device1_iface,
|
hr = d3d_device_create_dxgi_resource((IUnknown *)&device->ID3D10Device1_iface,
|
||||||
|
|
|
@ -21,6 +21,13 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(dxgi);
|
WINE_DEFAULT_DEBUG_CHANNEL(dxgi);
|
||||||
|
|
||||||
|
static void STDMETHODCALLTYPE dxgi_null_wined3d_object_destroyed(void *parent) {}
|
||||||
|
|
||||||
|
static const struct wined3d_parent_ops dxgi_null_wined3d_parent_ops =
|
||||||
|
{
|
||||||
|
dxgi_null_wined3d_object_destroyed,
|
||||||
|
};
|
||||||
|
|
||||||
static inline struct dxgi_device *impl_from_IWineDXGIDevice(IWineDXGIDevice *iface)
|
static inline struct dxgi_device *impl_from_IWineDXGIDevice(IWineDXGIDevice *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, struct dxgi_device, IWineDXGIDevice_iface);
|
return CONTAINING_RECORD(iface, struct dxgi_device, IWineDXGIDevice_iface);
|
||||||
|
@ -168,7 +175,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *ifac
|
||||||
const DXGI_SURFACE_DESC *desc, UINT surface_count, DXGI_USAGE usage,
|
const DXGI_SURFACE_DESC *desc, UINT surface_count, DXGI_USAGE usage,
|
||||||
const DXGI_SHARED_RESOURCE *shared_resource, IDXGISurface **surface)
|
const DXGI_SHARED_RESOURCE *shared_resource, IDXGISurface **surface)
|
||||||
{
|
{
|
||||||
struct wined3d_device_parent *device_parent;
|
struct dxgi_device *device = impl_from_IWineDXGIDevice(iface);
|
||||||
struct wined3d_resource_desc surface_desc;
|
struct wined3d_resource_desc surface_desc;
|
||||||
IWineDXGIDeviceParent *dxgi_device_parent;
|
IWineDXGIDeviceParent *dxgi_device_parent;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -185,8 +192,6 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *ifac
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_parent = IWineDXGIDeviceParent_get_wined3d_device_parent(dxgi_device_parent);
|
|
||||||
|
|
||||||
surface_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
|
surface_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
|
||||||
surface_desc.format = wined3dformat_from_dxgi_format(desc->Format);
|
surface_desc.format = wined3dformat_from_dxgi_format(desc->Format);
|
||||||
wined3d_sample_desc_from_dxgi(&surface_desc.multisample_type,
|
wined3d_sample_desc_from_dxgi(&surface_desc.multisample_type,
|
||||||
|
@ -204,23 +209,22 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *ifac
|
||||||
for (i = 0; i < surface_count; ++i)
|
for (i = 0; i < surface_count; ++i)
|
||||||
{
|
{
|
||||||
struct wined3d_texture *wined3d_texture;
|
struct wined3d_texture *wined3d_texture;
|
||||||
IUnknown *parent;
|
|
||||||
|
|
||||||
if (FAILED(hr = device_parent->ops->create_swapchain_texture(device_parent,
|
if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &surface_desc,
|
||||||
NULL, &surface_desc, 0, &wined3d_texture)))
|
1, 1, 0, NULL, NULL, &dxgi_null_wined3d_parent_ops, &wined3d_texture)))
|
||||||
{
|
{
|
||||||
ERR("Failed to create surface, hr %#lx.\n", hr);
|
ERR("Failed to create wined3d texture, hr %#lx.\n", hr);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent = wined3d_texture_get_parent(wined3d_texture);
|
if (FAILED(hr = IWineDXGIDeviceParent_register_swapchain_texture(
|
||||||
hr = IUnknown_QueryInterface(parent, &IID_IDXGISurface, (void **)&surface[i]);
|
dxgi_device_parent, wined3d_texture, 0, &surface[i])))
|
||||||
|
{
|
||||||
|
wined3d_texture_decref(wined3d_texture);
|
||||||
|
ERR("Failed to create parent swapchain texture, hr %#lx.\n", hr);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
wined3d_texture_decref(wined3d_texture);
|
wined3d_texture_decref(wined3d_texture);
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
ERR("Surface should implement IDXGISurface.\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("Created IDXGISurface %p (%u/%u).\n", surface[i], i + 1, surface_count);
|
TRACE("Created IDXGISurface %p (%u/%u).\n", surface[i], i + 1, surface_count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ interface IWineDXGIDevice : IDXGIDevice3
|
||||||
interface IWineDXGIDeviceParent : IUnknown
|
interface IWineDXGIDeviceParent : IUnknown
|
||||||
{
|
{
|
||||||
struct wined3d_device_parent *get_wined3d_device_parent();
|
struct wined3d_device_parent *get_wined3d_device_parent();
|
||||||
|
HRESULT register_swapchain_texture(struct wined3d_texture *texture,
|
||||||
|
unsigned int texture_flags, IDXGISurface **ret_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wine_dxgi_adapter_info
|
struct wine_dxgi_adapter_info
|
||||||
|
|
Loading…
Reference in a new issue