diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index e4f4c09f811..3317e9cfce5 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -43,6 +43,7 @@ extern HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLSPEC_HIDDEN; D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN; +BOOL is_gdi_compat_format(D3DFORMAT format) DECLSPEC_HIDDEN; enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN; void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters, const struct wined3d_swapchain_desc *swapchain_desc) DECLSPEC_HIDDEN; @@ -227,7 +228,6 @@ struct d3d9_surface IDirect3DDevice9Ex *parent_device; IUnknown *container; struct d3d9_texture *texture; - BOOL getdc_supported; }; struct wined3d_rendertarget_view *d3d9_surface_get_rendertarget_view(struct d3d9_surface *surface) DECLSPEC_HIDDEN; diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index c3f30072c16..b8c46381316 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -1125,6 +1125,9 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width desc.depth = 1; desc.size = 0; + if (is_gdi_compat_format(format)) + flags |= WINED3D_TEXTURE_CREATE_GET_DC; + wined3d_mutex_lock(); if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc, @@ -1153,6 +1156,22 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width return D3D_OK; } +BOOL is_gdi_compat_format(D3DFORMAT format) +{ + switch (format) + { + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + case D3DFMT_R5G6B5: + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + case D3DFMT_R8G8B8: + return TRUE; + default: + return FALSE; + } +} + static HRESULT WINAPI d3d9_device_CreateRenderTarget(IDirect3DDevice9Ex *iface, UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle) @@ -3722,6 +3741,7 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_texture **texture) { struct d3d9_device *device = device_from_device_parent(device_parent); + DWORD flags = WINED3D_TEXTURE_CREATE_MAPPABLE; struct d3d9_surface *d3d_surface; HRESULT hr; @@ -3731,8 +3751,11 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic if (container_parent == device_parent) container_parent = &device->IDirect3DDevice9Ex_iface; + if (is_gdi_compat_format(d3dformat_from_wined3dformat(desc->format))) + flags |= WINED3D_TEXTURE_CREATE_GET_DC; + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1, - WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, container_parent, &d3d9_null_wined3d_parent_ops, texture))) + flags, NULL, container_parent, &d3d9_null_wined3d_parent_ops, texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c index b007f787df1..be686821167 100644 --- a/dlls/d3d9/surface.c +++ b/dlls/d3d9/surface.c @@ -287,13 +287,6 @@ static HRESULT WINAPI d3d9_surface_GetDC(IDirect3DSurface9 *iface, HDC *dc) TRACE("iface %p, dc %p.\n", iface, dc); - if (!surface->getdc_supported) - { - WARN("Surface does not support GetDC, returning D3DERR_INVALIDCALL\n"); - /* Don't touch the DC */ - return D3DERR_INVALIDCALL; - } - wined3d_mutex_lock(); hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, dc); wined3d_mutex_unlock(); @@ -354,7 +347,6 @@ static const struct wined3d_parent_ops d3d9_surface_wined3d_parent_ops = void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) { - struct wined3d_resource_desc desc; IDirect3DBaseTexture9 *texture; surface->IDirect3DSurface9_iface.lpVtbl = &d3d9_surface_vtbl; @@ -372,23 +364,6 @@ void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_ IDirect3DBaseTexture9_Release(texture); } - wined3d_resource_get_desc(wined3d_texture_get_resource(wined3d_texture), &desc); - switch (d3dformat_from_wined3dformat(desc.format)) - { - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: - case D3DFMT_R5G6B5: - case D3DFMT_X1R5G5B5: - case D3DFMT_A1R5G5B5: - case D3DFMT_R8G8B8: - surface->getdc_supported = TRUE; - break; - - default: - surface->getdc_supported = FALSE; - break; - } - *parent_ops = &d3d9_surface_wined3d_parent_ops; } diff --git a/dlls/d3d9/texture.c b/dlls/d3d9/texture.c index bd93d21249f..46e42180fc3 100644 --- a/dlls/d3d9/texture.c +++ b/dlls/d3d9/texture.c @@ -1257,6 +1257,9 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; + if (is_gdi_compat_format(format)) + flags |= WINED3D_TEXTURE_CREATE_GET_DC; + if (!levels) { if (usage & D3DUSAGE_AUTOGENMIPMAP) @@ -1307,6 +1310,9 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; + if (is_gdi_compat_format(format)) + flags |= WINED3D_TEXTURE_CREATE_GET_DC; + if (!levels) { if (usage & D3DUSAGE_AUTOGENMIPMAP) diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index cf5fc93fa34..a13f2c69c4f 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -324,6 +324,8 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc texture->flags |= WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS; if (flags & WINED3D_TEXTURE_CREATE_GET_DC_LENIENT) texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_GET_DC_LENIENT; + if (flags & (WINED3D_TEXTURE_CREATE_GET_DC | WINED3D_TEXTURE_CREATE_GET_DC_LENIENT)) + texture->flags |= WINED3D_TEXTURE_GET_DC; if (flags & WINED3D_TEXTURE_CREATE_DISCARD) texture->flags |= WINED3D_TEXTURE_DISCARD; @@ -2866,6 +2868,13 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc); + if (!(texture->flags & WINED3D_TEXTURE_GET_DC)) + { + WARN("Texture does not support GetDC\n"); + /* Don't touch the DC */ + return WINED3DERR_INVALIDCALL; + } + if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) return WINED3DERR_INVALIDCALL; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 2dd60ed25cc..447983752f8 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2640,6 +2640,7 @@ struct wined3d_texture_ops #define WINED3D_TEXTURE_GET_DC_LENIENT 0x00000800 #define WINED3D_TEXTURE_DC_IN_USE 0x00001000 #define WINED3D_TEXTURE_DISCARD 0x00002000 +#define WINED3D_TEXTURE_GET_DC 0x00004000 #define WINED3D_TEXTURE_ASYNC_COLOR_KEY 0x00000001 diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index f2900a9a173..e42ef7789ae 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1490,6 +1490,7 @@ enum wined3d_display_rotation #define WINED3D_TEXTURE_CREATE_MAPPABLE 0x00000001 #define WINED3D_TEXTURE_CREATE_DISCARD 0x00000002 #define WINED3D_TEXTURE_CREATE_GET_DC_LENIENT 0x00000004 +#define WINED3D_TEXTURE_CREATE_GET_DC 0x00000008 #define WINED3D_APPEND_ALIGNED_ELEMENT 0xffffffff