Commit 86f1ab36 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

d2d1: Implement d2d_device_context_SetTarget() for bitmap targets.

parent f60455be
...@@ -70,6 +70,8 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_Release(ID2D1Bitmap1 *iface) ...@@ -70,6 +70,8 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_Release(ID2D1Bitmap1 *iface)
if (!refcount) if (!refcount)
{ {
ID3D10ShaderResourceView_Release(bitmap->view); ID3D10ShaderResourceView_Release(bitmap->view);
if (bitmap->rtv)
ID3D10RenderTargetView_Release(bitmap->rtv);
if (bitmap->surface) if (bitmap->surface)
IDXGISurface_Release(bitmap->surface); IDXGISurface_Release(bitmap->surface);
ID2D1Factory_Release(bitmap->factory); ID2D1Factory_Release(bitmap->factory);
...@@ -274,6 +276,10 @@ static BOOL format_supported(const D2D1_PIXEL_FORMAT *format) ...@@ -274,6 +276,10 @@ static BOOL format_supported(const D2D1_PIXEL_FORMAT *format)
static void d2d_bitmap_init(struct d2d_bitmap *bitmap, struct d2d_device_context *context, static void d2d_bitmap_init(struct d2d_bitmap *bitmap, struct d2d_device_context *context,
ID3D10ShaderResourceView *view, D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES1 *desc) ID3D10ShaderResourceView *view, D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES1 *desc)
{ {
ID3D10Resource *resource;
ID3D10Device *d3d_device;
HRESULT hr;
bitmap->ID2D1Bitmap1_iface.lpVtbl = &d2d_bitmap_vtbl; bitmap->ID2D1Bitmap1_iface.lpVtbl = &d2d_bitmap_vtbl;
bitmap->refcount = 1; bitmap->refcount = 1;
ID2D1Factory_AddRef(bitmap->factory = context->factory); ID2D1Factory_AddRef(bitmap->factory = context->factory);
...@@ -283,15 +289,22 @@ static void d2d_bitmap_init(struct d2d_bitmap *bitmap, struct d2d_device_context ...@@ -283,15 +289,22 @@ static void d2d_bitmap_init(struct d2d_bitmap *bitmap, struct d2d_device_context
bitmap->dpi_x = desc->dpiX; bitmap->dpi_x = desc->dpiX;
bitmap->dpi_y = desc->dpiY; bitmap->dpi_y = desc->dpiY;
bitmap->options = desc->bitmapOptions; bitmap->options = desc->bitmapOptions;
if (d2d_device_context_is_dxgi_target(context))
{
ID3D10Resource *resource;
ID3D10ShaderResourceView_GetResource(bitmap->view, &resource); ID3D10ShaderResourceView_GetResource(bitmap->view, &resource);
if (d2d_device_context_is_dxgi_target(context))
ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface, (void **)&bitmap->surface); ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface, (void **)&bitmap->surface);
ID3D10Resource_Release(resource);
if (bitmap->options & D2D1_BITMAP_OPTIONS_TARGET)
{
ID3D10Resource_GetDevice(resource, &d3d_device);
if (FAILED(hr = ID3D10Device_CreateRenderTargetView(d3d_device, resource, NULL, &bitmap->rtv)))
WARN("Failed to create rtv, hr %#x.\n", hr);
ID3D10Device_Release(d3d_device);
} }
ID3D10Resource_Release(resource);
if (bitmap->dpi_x == 0.0f && bitmap->dpi_y == 0.0f) if (bitmap->dpi_x == 0.0f && bitmap->dpi_y == 0.0f)
{ {
bitmap->dpi_x = 96.0f; bitmap->dpi_x = 96.0f;
......
...@@ -69,7 +69,8 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_render_target_Release(ID2D1BitmapRende ...@@ -69,7 +69,8 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_render_target_Release(ID2D1BitmapRende
if (!refcount) if (!refcount)
{ {
IUnknown_Release(render_target->dxgi_inner); IUnknown_Release(render_target->dxgi_inner);
ID2D1Bitmap_Release(render_target->bitmap); if (render_target->bitmap)
ID2D1Bitmap_Release(render_target->bitmap);
heap_free(render_target); heap_free(render_target);
} }
...@@ -733,10 +734,9 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta ...@@ -733,10 +734,9 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta
D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options) D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options)
{ {
D2D1_RENDER_TARGET_PROPERTIES dxgi_rt_desc; D2D1_RENDER_TARGET_PROPERTIES dxgi_rt_desc;
D2D1_BITMAP_PROPERTIES bitmap_desc; D2D1_BITMAP_PROPERTIES1 bitmap_desc;
D3D10_TEXTURE2D_DESC texture_desc; ID2D1DeviceContext *context;
IDXGISurface *dxgi_surface; D2D1_SIZE_U bitmap_size;
ID3D10Texture2D *texture;
HRESULT hr; HRESULT hr;
if (options) if (options)
...@@ -750,24 +750,24 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta ...@@ -750,24 +750,24 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta
if (pixel_size) if (pixel_size)
{ {
texture_desc.Width = pixel_size->width; bitmap_size.width = pixel_size->width;
texture_desc.Height = pixel_size->height; bitmap_size.height = pixel_size->height;
} }
else if (size) else if (size)
{ {
texture_desc.Width = ceilf((size->width * parent_target->desc.dpiX) / 96.0f); bitmap_size.width = ceilf((size->width * parent_target->desc.dpiX) / 96.0f);
texture_desc.Height = ceilf((size->height * parent_target->desc.dpiY) / 96.0f); bitmap_size.height = ceilf((size->height * parent_target->desc.dpiY) / 96.0f);
} }
else else
{ {
texture_desc.Width = parent_target->pixel_size.width; bitmap_size.width = parent_target->pixel_size.width;
texture_desc.Height = parent_target->pixel_size.height; bitmap_size.height = parent_target->pixel_size.height;
} }
if (size) if (size && size->width != 0.0f && size->height != 0.0f)
{ {
dxgi_rt_desc.dpiX = (texture_desc.Width * 96.0f) / size->width; dxgi_rt_desc.dpiX = (bitmap_size.width * 96.0f) / size->width;
dxgi_rt_desc.dpiY = (texture_desc.Height * 96.0f) / size->height; dxgi_rt_desc.dpiY = (bitmap_size.height * 96.0f) / size->height;
} }
else else
{ {
...@@ -776,46 +776,21 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta ...@@ -776,46 +776,21 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta
} }
if (!pixel_format || pixel_format->format == DXGI_FORMAT_UNKNOWN) if (!pixel_format || pixel_format->format == DXGI_FORMAT_UNKNOWN)
texture_desc.Format = parent_target->desc.pixelFormat.format; dxgi_rt_desc.pixelFormat.format = parent_target->desc.pixelFormat.format;
else else
texture_desc.Format = pixel_format->format; dxgi_rt_desc.pixelFormat.format = pixel_format->format;
dxgi_rt_desc.pixelFormat.format = texture_desc.Format;
if (!pixel_format || pixel_format->alphaMode == D2D1_ALPHA_MODE_UNKNOWN) if (!pixel_format || pixel_format->alphaMode == D2D1_ALPHA_MODE_UNKNOWN)
dxgi_rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; dxgi_rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
else else
dxgi_rt_desc.pixelFormat.alphaMode = pixel_format->alphaMode; dxgi_rt_desc.pixelFormat.alphaMode = pixel_format->alphaMode;
texture_desc.MipLevels = 1; if (FAILED(hr = d2d_d3d_create_render_target(parent_target->device, NULL,
texture_desc.ArraySize = 1;
texture_desc.SampleDesc.Count = 1;
texture_desc.SampleDesc.Quality = 0;
texture_desc.Usage = D3D10_USAGE_DEFAULT;
texture_desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
texture_desc.CPUAccessFlags = 0;
texture_desc.MiscFlags = 0;
if (FAILED(hr = ID3D10Device_CreateTexture2D(parent_target->d3d_device, &texture_desc, NULL, &texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
}
hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&dxgi_surface);
ID3D10Texture2D_Release(texture);
if (FAILED(hr))
{
WARN("Failed to get DXGI surface interface, hr %#x.\n", hr);
return hr;
}
if (FAILED(hr = d2d_d3d_create_render_target(parent_target->device, dxgi_surface,
(IUnknown *)&render_target->ID2D1BitmapRenderTarget_iface, (IUnknown *)&render_target->ID2D1BitmapRenderTarget_iface,
parent_target->ops ? &d2d_bitmap_render_target_ops : NULL, parent_target->ops ? &d2d_bitmap_render_target_ops : NULL,
&dxgi_rt_desc, (void **)&render_target->dxgi_inner))) &dxgi_rt_desc, (void **)&render_target->dxgi_inner)))
{ {
WARN("Failed to create DXGI surface render target, hr %#x.\n", hr); WARN("Failed to create DXGI surface render target, hr %#x.\n", hr);
IDXGISurface_Release(dxgi_surface);
return hr; return hr;
} }
...@@ -824,20 +799,23 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta ...@@ -824,20 +799,23 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta
{ {
WARN("Failed to retrieve ID2D1RenderTarget interface, hr %#x.\n", hr); WARN("Failed to retrieve ID2D1RenderTarget interface, hr %#x.\n", hr);
IUnknown_Release(render_target->dxgi_inner); IUnknown_Release(render_target->dxgi_inner);
IDXGISurface_Release(dxgi_surface);
return hr; return hr;
} }
bitmap_desc.pixelFormat = dxgi_rt_desc.pixelFormat; bitmap_desc.pixelFormat = dxgi_rt_desc.pixelFormat;
bitmap_desc.dpiX = dxgi_rt_desc.dpiX; bitmap_desc.dpiX = dxgi_rt_desc.dpiX;
bitmap_desc.dpiY = dxgi_rt_desc.dpiY; bitmap_desc.dpiY = dxgi_rt_desc.dpiY;
bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
hr = ID2D1RenderTarget_CreateSharedBitmap(render_target->dxgi_target, &IID_IDXGISurface, dxgi_surface, bitmap_desc.colorContext = NULL;
&bitmap_desc, &render_target->bitmap);
IDXGISurface_Release(dxgi_surface); ID2D1RenderTarget_QueryInterface(render_target->dxgi_target, &IID_ID2D1DeviceContext, (void **)&context);
hr = ID2D1DeviceContext_CreateBitmap(context, bitmap_size, NULL, 0, &bitmap_desc,
(ID2D1Bitmap1 **)&render_target->bitmap);
ID2D1DeviceContext_SetTarget(context, (ID2D1Image *)render_target->bitmap);
ID2D1DeviceContext_Release(context);
if (FAILED(hr)) if (FAILED(hr))
{ {
WARN("Failed to create shared bitmap, hr %#x.\n", hr); WARN("Failed to create target bitmap, hr %#x.\n", hr);
ID2D1RenderTarget_Release(render_target->dxgi_target); ID2D1RenderTarget_Release(render_target->dxgi_target);
IUnknown_Release(render_target->dxgi_inner); IUnknown_Release(render_target->dxgi_inner);
return hr; return hr;
......
...@@ -136,7 +136,7 @@ struct d2d_device_context ...@@ -136,7 +136,7 @@ struct d2d_device_context
ID2D1Factory *factory; ID2D1Factory *factory;
ID2D1Device *device; ID2D1Device *device;
ID3D10Device *d3d_device; ID3D10Device *d3d_device;
ID3D10RenderTargetView *view; struct d2d_bitmap *target;
ID3D10StateBlock *stateblock; ID3D10StateBlock *stateblock;
struct d2d_shape_resources shape_resources[D2D_SHAPE_TYPE_COUNT]; struct d2d_shape_resources shape_resources[D2D_SHAPE_TYPE_COUNT];
ID3D10PixelShader *ps; ID3D10PixelShader *ps;
...@@ -159,7 +159,6 @@ struct d2d_device_context ...@@ -159,7 +159,6 @@ struct d2d_device_context
HRESULT d2d_d3d_create_render_target(ID2D1Device *device, IDXGISurface *surface, IUnknown *outer_unknown, HRESULT d2d_d3d_create_render_target(ID2D1Device *device, IDXGISurface *surface, IUnknown *outer_unknown,
const struct d2d_device_context_ops *ops, const D2D1_RENDER_TARGET_PROPERTIES *desc, const struct d2d_device_context_ops *ops, const D2D1_RENDER_TARGET_PROPERTIES *desc,
void **render_target) DECLSPEC_HIDDEN; void **render_target) DECLSPEC_HIDDEN;
HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN;
static inline BOOL d2d_device_context_is_dxgi_target(const struct d2d_device_context *context) static inline BOOL d2d_device_context_is_dxgi_target(const struct d2d_device_context *context)
{ {
...@@ -191,6 +190,8 @@ struct d2d_dc_render_target ...@@ -191,6 +190,8 @@ struct d2d_dc_render_target
LONG refcount; LONG refcount;
IDXGISurface1 *dxgi_surface; IDXGISurface1 *dxgi_surface;
D2D1_PIXEL_FORMAT pixel_format;
ID3D10Device1 *d3d_device;
ID2D1RenderTarget *dxgi_target; ID2D1RenderTarget *dxgi_target;
IUnknown *dxgi_inner; IUnknown *dxgi_inner;
...@@ -345,6 +346,7 @@ struct d2d_bitmap ...@@ -345,6 +346,7 @@ struct d2d_bitmap
ID2D1Factory *factory; ID2D1Factory *factory;
ID3D10ShaderResourceView *view; ID3D10ShaderResourceView *view;
ID3D10RenderTargetView *rtv;
IDXGISurface *surface; IDXGISurface *surface;
D2D1_SIZE_U pixel_size; D2D1_SIZE_U pixel_size;
D2D1_PIXEL_FORMAT format; D2D1_PIXEL_FORMAT format;
......
...@@ -99,7 +99,9 @@ static ULONG STDMETHODCALLTYPE d2d_dc_render_target_Release(ID2D1DCRenderTarget ...@@ -99,7 +99,9 @@ static ULONG STDMETHODCALLTYPE d2d_dc_render_target_Release(ID2D1DCRenderTarget
if (!refcount) if (!refcount)
{ {
IUnknown_Release(render_target->dxgi_inner); IUnknown_Release(render_target->dxgi_inner);
IDXGISurface1_Release(render_target->dxgi_surface); if (render_target->dxgi_surface)
IDXGISurface1_Release(render_target->dxgi_surface);
ID3D10Device1_Release(render_target->d3d_device);
heap_free(render_target); heap_free(render_target);
} }
...@@ -686,8 +688,9 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget ...@@ -686,8 +688,9 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget
struct d2d_dc_render_target *render_target = impl_from_ID2D1DCRenderTarget(iface); struct d2d_dc_render_target *render_target = impl_from_ID2D1DCRenderTarget(iface);
D3D10_TEXTURE2D_DESC texture_desc; D3D10_TEXTURE2D_DESC texture_desc;
IDXGISurface1 *dxgi_surface; IDXGISurface1 *dxgi_surface;
ID2D1DeviceContext *context;
ID3D10Texture2D *texture; ID3D10Texture2D *texture;
ID3D10Device *device; ID2D1Bitmap1 *bitmap;
HRESULT hr; HRESULT hr;
TRACE("iface %p, hdc %p, rect %s.\n", iface, hdc, wine_dbgstr_rect(rect)); TRACE("iface %p, hdc %p, rect %s.\n", iface, hdc, wine_dbgstr_rect(rect));
...@@ -695,27 +698,19 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget ...@@ -695,27 +698,19 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget
if (!hdc) if (!hdc)
return E_INVALIDARG; return E_INVALIDARG;
/* Recreate surface using specified size and original texture description. */
if (FAILED(hr = IDXGISurface1_QueryInterface(render_target->dxgi_surface, &IID_ID3D10Texture2D, (void **)&texture)))
{
WARN("Failed to get texture interface, hr %#x.\n", hr);
return hr;
}
ID3D10Texture2D_GetDesc(texture, &texture_desc);
ID3D10Texture2D_Release(texture);
texture_desc.Width = rect->right - rect->left; texture_desc.Width = rect->right - rect->left;
texture_desc.Height = rect->bottom - rect->top; texture_desc.Height = rect->bottom - rect->top;
texture_desc.MipLevels = 1;
texture_desc.ArraySize = 1;
texture_desc.Format = render_target->pixel_format.format;
texture_desc.SampleDesc.Count = 1;
texture_desc.SampleDesc.Quality = 0;
texture_desc.Usage = D3D10_USAGE_DEFAULT;
texture_desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
texture_desc.CPUAccessFlags = 0;
texture_desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
if (FAILED(hr = IDXGISurface1_GetDevice(render_target->dxgi_surface, &IID_ID3D10Device, (void **)&device))) if (FAILED(hr = ID3D10Device1_CreateTexture2D(render_target->d3d_device, &texture_desc, NULL, &texture)))
{
WARN("Failed to get device from dxgi surface, hr %#x.\n", hr);
return hr;
}
hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &texture);
ID3D10Device_Release(device);
if (FAILED(hr))
{ {
WARN("Failed to create texture, hr %#x.\n", hr); WARN("Failed to create texture, hr %#x.\n", hr);
return hr; return hr;
...@@ -730,14 +725,24 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget ...@@ -730,14 +725,24 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget
} }
/* Switch dxgi target to new surface. */ /* Switch dxgi target to new surface. */
if (FAILED(hr = d2d_d3d_render_target_create_rtv(render_target->dxgi_target, dxgi_surface))) ID2D1RenderTarget_QueryInterface(render_target->dxgi_target, &IID_ID2D1DeviceContext, (void **)&context);
hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(context, (IDXGISurface *)dxgi_surface, NULL, &bitmap);
if (SUCCEEDED(hr))
{ {
WARN("Failed to set new surface, hr %#x.\n", hr); ID2D1DeviceContext_SetTarget(context, (ID2D1Image *)bitmap);
ID2D1Bitmap1_Release(bitmap);
}
ID2D1DeviceContext_Release(context);
if (FAILED(hr))
{
WARN("Failed to create new target bitmap, hr %#x.\n", hr);
IDXGISurface1_Release(dxgi_surface); IDXGISurface1_Release(dxgi_surface);
return hr; return hr;
} }
IDXGISurface1_Release(render_target->dxgi_surface); if (render_target->dxgi_surface)
IDXGISurface1_Release(render_target->dxgi_surface);
render_target->dxgi_surface = dxgi_surface; render_target->dxgi_surface = dxgi_surface;
render_target->hdc = hdc; render_target->hdc = hdc;
...@@ -816,8 +821,6 @@ static const struct d2d_device_context_ops d2d_dc_render_target_ops = ...@@ -816,8 +821,6 @@ static const struct d2d_device_context_ops d2d_dc_render_target_ops =
HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory1 *factory, HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory1 *factory,
ID3D10Device1 *d3d_device, const D2D1_RENDER_TARGET_PROPERTIES *desc) ID3D10Device1 *d3d_device, const D2D1_RENDER_TARGET_PROPERTIES *desc)
{ {
D3D10_TEXTURE2D_DESC texture_desc;
ID3D10Texture2D *texture;
IDXGIDevice *dxgi_device; IDXGIDevice *dxgi_device;
ID2D1Device *device; ID2D1Device *device;
HRESULT hr; HRESULT hr;
...@@ -828,14 +831,8 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID ...@@ -828,14 +831,8 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID
SetRectEmpty(&render_target->dst_rect); SetRectEmpty(&render_target->dst_rect);
render_target->hdc = NULL; render_target->hdc = NULL;
/* Dummy 1x1 texture, recreated on BindDC(). */ render_target->pixel_format = desc->pixelFormat;
texture_desc.Width = 1; switch (desc->pixelFormat.format)
texture_desc.Height = 1;
texture_desc.MipLevels = 1;
texture_desc.ArraySize = 1;
texture_desc.Format = desc->pixelFormat.format;
switch (texture_desc.Format)
{ {
case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM:
if (desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED if (desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED
...@@ -843,31 +840,10 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID ...@@ -843,31 +840,10 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID
break; break;
default: default:
FIXME("Unhandled format %#x, alpha mode %u.\n", texture_desc.Format, desc->pixelFormat.alphaMode); FIXME("Unhandled format %#x, alpha mode %u.\n", desc->pixelFormat.format, desc->pixelFormat.alphaMode);
return D2DERR_UNSUPPORTED_PIXEL_FORMAT; return D2DERR_UNSUPPORTED_PIXEL_FORMAT;
} }
texture_desc.SampleDesc.Count = 1;
texture_desc.SampleDesc.Quality = 0;
texture_desc.Usage = D3D10_USAGE_DEFAULT;
texture_desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
texture_desc.CPUAccessFlags = 0;
texture_desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
if (FAILED(hr = ID3D10Device1_CreateTexture2D(d3d_device, &texture_desc, NULL, &texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
}
hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface1, (void **)&render_target->dxgi_surface);
ID3D10Texture2D_Release(texture);
if (FAILED(hr))
{
WARN("Failed to get DXGI surface interface, hr %#x.\n", hr);
return hr;
}
if (FAILED(hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device))) if (FAILED(hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device)))
{ {
WARN("Failed to get DXGI device interface, hr %#x.\n", hr); WARN("Failed to get DXGI device interface, hr %#x.\n", hr);
...@@ -882,14 +858,12 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID ...@@ -882,14 +858,12 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID
return hr; return hr;
} }
hr = d2d_d3d_create_render_target(device, (IDXGISurface *)render_target->dxgi_surface, hr = d2d_d3d_create_render_target(device, NULL, (IUnknown *)&render_target->ID2D1DCRenderTarget_iface,
(IUnknown *)&render_target->ID2D1DCRenderTarget_iface, &d2d_dc_render_target_ops, &d2d_dc_render_target_ops, desc, (void **)&render_target->dxgi_inner);
desc, (void **)&render_target->dxgi_inner);
ID2D1Device_Release(device); ID2D1Device_Release(device);
if (FAILED(hr)) if (FAILED(hr))
{ {
WARN("Failed to create DXGI surface render target, hr %#x.\n", hr); WARN("Failed to create DXGI surface render target, hr %#x.\n", hr);
IDXGISurface1_Release(render_target->dxgi_surface);
return hr; return hr;
} }
...@@ -898,9 +872,11 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID ...@@ -898,9 +872,11 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID
{ {
WARN("Failed to retrieve ID2D1RenderTarget interface, hr %#x.\n", hr); WARN("Failed to retrieve ID2D1RenderTarget interface, hr %#x.\n", hr);
IUnknown_Release(render_target->dxgi_inner); IUnknown_Release(render_target->dxgi_inner);
IDXGISurface1_Release(render_target->dxgi_surface);
return hr; return hr;
} }
render_target->d3d_device = d3d_device;
ID3D10Device1_AddRef(render_target->d3d_device);
return S_OK; return S_OK;
} }
...@@ -675,11 +675,14 @@ static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Resize(ID2D1HwndRenderTa ...@@ -675,11 +675,14 @@ static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Resize(ID2D1HwndRenderTa
{ {
struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface);
IDXGISurface1 *dxgi_surface; IDXGISurface1 *dxgi_surface;
ID2D1DeviceContext *context;
ID2D1Bitmap1 *bitmap;
HRESULT hr; HRESULT hr;
TRACE("iface %p, width %u, height %u.\n", iface, size->width, size->height); TRACE("iface %p, width %u, height %u.\n", iface, size->width, size->height);
d2d_d3d_render_target_create_rtv(render_target->dxgi_target, NULL); ID2D1RenderTarget_QueryInterface(render_target->dxgi_target, &IID_ID2D1DeviceContext, (void **)&context);
ID2D1DeviceContext_SetTarget(context, NULL);
if (SUCCEEDED(hr = IDXGISwapChain_ResizeBuffers(render_target->swapchain, 1, size->width, size->height, if (SUCCEEDED(hr = IDXGISwapChain_ResizeBuffers(render_target->swapchain, 1, size->width, size->height,
DXGI_FORMAT_UNKNOWN, 0))) DXGI_FORMAT_UNKNOWN, 0)))
...@@ -688,13 +691,25 @@ static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Resize(ID2D1HwndRenderTa ...@@ -688,13 +691,25 @@ static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Resize(ID2D1HwndRenderTa
(void **)&dxgi_surface))) (void **)&dxgi_surface)))
{ {
WARN("Failed to get buffer, hr %#x.\n", hr); WARN("Failed to get buffer, hr %#x.\n", hr);
ID2D1DeviceContext_Release(context);
return hr; return hr;
} }
hr = d2d_d3d_render_target_create_rtv(render_target->dxgi_target, dxgi_surface); hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(context, (IDXGISurface *)dxgi_surface, NULL, &bitmap);
IDXGISurface1_Release(dxgi_surface); IDXGISurface1_Release(dxgi_surface);
if (FAILED(hr))
{
WARN("Failed to create target bitmap, hr %#x.\n", hr);
ID2D1DeviceContext_Release(context);
return hr;
}
ID2D1DeviceContext_SetTarget(context, (ID2D1Image *)bitmap);
ID2D1Bitmap1_Release(bitmap);
} }
ID2D1DeviceContext_Release(context);
return hr; return hr;
} }
......
...@@ -813,8 +813,9 @@ static void check_bitmap_surface_(unsigned int line, ID2D1Bitmap *bitmap, BOOL h ...@@ -813,8 +813,9 @@ static void check_bitmap_surface_(unsigned int line, ID2D1Bitmap *bitmap, BOOL h
if (!(options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW)) if (!(options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW))
bind_flags |= D3D10_BIND_SHADER_RESOURCE; bind_flags |= D3D10_BIND_SHADER_RESOURCE;
ok_(__FILE__, line)(desc.BindFlags == bind_flags, "Unexpected bind flags %#x for bitmap options %#x.\n", todo_wine_if (options == D2D1_BITMAP_OPTIONS_TARGET)
desc.BindFlags, options); ok_(__FILE__, line)(desc.BindFlags == bind_flags, "Unexpected bind flags %#x for bitmap options %#x.\n",
desc.BindFlags, options);
ok_(__FILE__, line)(!desc.CPUAccessFlags, "Unexpected cpu access flags %#x.\n", desc.CPUAccessFlags); ok_(__FILE__, line)(!desc.CPUAccessFlags, "Unexpected cpu access flags %#x.\n", desc.CPUAccessFlags);
ok_(__FILE__, line)(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags); ok_(__FILE__, line)(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
...@@ -5283,9 +5284,7 @@ static void test_compatible_target_size_(unsigned int line, ID2D1RenderTarget *r ...@@ -5283,9 +5284,7 @@ static void test_compatible_target_size_(unsigned int line, ID2D1RenderTarget *r
{ {
hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, size_tests[i].size, size_tests[i].pixel_size, hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, size_tests[i].size, size_tests[i].pixel_size,
NULL, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt); NULL, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt);
todo_wine ok_(__FILE__, line)(SUCCEEDED(hr), "%u: Failed to create render target, hr %#x.\n", i, hr); ok_(__FILE__, line)(SUCCEEDED(hr), "%u: Failed to create render target, hr %#x.\n", i, hr);
if (FAILED(hr))
return;
if (size_tests[i].pixel_size) if (size_tests[i].pixel_size)
{ {
...@@ -5519,13 +5518,11 @@ static void test_bitmap_target(void) ...@@ -5519,13 +5518,11 @@ static void test_bitmap_target(void)
ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt); pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt);
todo_wine
ok(pixel_size.width == 0 && pixel_size.height == 0, "Got wrong size\n"); ok(pixel_size.width == 0 && pixel_size.height == 0, "Got wrong size\n");
hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap); hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap);
ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr); ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
pixel_size = ID2D1Bitmap_GetPixelSize(bitmap); pixel_size = ID2D1Bitmap_GetPixelSize(bitmap);
todo_wine
ok(pixel_size.width == 0 && pixel_size.height == 0, "Got wrong size\n"); ok(pixel_size.width == 0 && pixel_size.height == 0, "Got wrong size\n");
ID2D1Bitmap_Release(bitmap); ID2D1Bitmap_Release(bitmap);
...@@ -6989,14 +6986,10 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B ...@@ -6989,14 +6986,10 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B
bitmap2 = NULL; bitmap2 = NULL;
ID2D1DeviceContext_GetTarget(context2, (ID2D1Image **)&bitmap2); ID2D1DeviceContext_GetTarget(context2, (ID2D1Image **)&bitmap2);
todo_wine ok_(__FILE__, line)(bitmap2 == bitmap, "Unexpected bitmap.\n"); ok_(__FILE__, line)(bitmap2 == bitmap, "Unexpected bitmap.\n");
if (bitmap2)
{
check_bitmap_surface_(line, bitmap, has_surface, D2D1_BITMAP_OPTIONS_TARGET);
ID2D1Bitmap_Release(bitmap2); check_bitmap_surface_(line, bitmap, has_surface, D2D1_BITMAP_OPTIONS_TARGET);
} ID2D1Bitmap_Release(bitmap2);
ID2D1Bitmap_Release(bitmap); ID2D1Bitmap_Release(bitmap);
ID2D1BitmapRenderTarget_Release(compatible_rt); ID2D1BitmapRenderTarget_Release(compatible_rt);
...@@ -7093,6 +7086,8 @@ static void test_bitmap_surface(void) ...@@ -7093,6 +7086,8 @@ static void test_bitmap_surface(void)
ID2D1Bitmap1 *bitmap; ID2D1Bitmap1 *bitmap;
ID2D1Device *device; ID2D1Device *device;
ID2D1Image *target; ID2D1Image *target;
D2D1_SIZE_U size;
D2D1_TAG t1, t2;
unsigned int i; unsigned int i;
HWND window; HWND window;
HRESULT hr; HRESULT hr;
...@@ -7126,14 +7121,10 @@ static void test_bitmap_surface(void) ...@@ -7126,14 +7121,10 @@ static void test_bitmap_surface(void)
bitmap = NULL; bitmap = NULL;
ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap); ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
todo_wine
ok(!!bitmap, "Unexpected target.\n"); ok(!!bitmap, "Unexpected target.\n");
if (bitmap)
{
check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW); check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
ID2D1Bitmap1_Release(bitmap); ID2D1Bitmap1_Release(bitmap);
}
check_rt_bitmap_surface(rt, TRUE, D2D1_BITMAP_OPTIONS_NONE); check_rt_bitmap_surface(rt, TRUE, D2D1_BITMAP_OPTIONS_NONE);
ID2D1DeviceContext_Release(device_context); ID2D1DeviceContext_Release(device_context);
...@@ -7213,8 +7204,45 @@ if (SUCCEEDED(hr)) ...@@ -7213,8 +7204,45 @@ if (SUCCEEDED(hr))
check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE); check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE);
ID2D1DeviceContext_Release(device_context);
ID2D1Bitmap1_Release(bitmap); ID2D1Bitmap1_Release(bitmap);
/* Without D2D1_BITMAP_OPTIONS_TARGET. */
memset(&bitmap_desc, 0, sizeof(bitmap_desc));
bitmap_desc.pixelFormat = ID2D1DeviceContext_GetPixelFormat(device_context);
size.width = size.height = 4;
hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap);
ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_NONE);
ID2D1DeviceContext_SetTags(device_context, 1, 2);
ID2D1DeviceContext_BeginDraw(device_context);
ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
hr = ID2D1DeviceContext_EndDraw(device_context, &t1, &t2);
ok(hr == D2DERR_INVALID_TARGET, "Unexpected hr %#x.\n", hr);
ok(t1 == 1 && t2 == 2, "Unexpected tags %s:%s.\n", wine_dbgstr_longlong(t1), wine_dbgstr_longlong(t2));
ID2D1Bitmap1_Release(bitmap);
ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
ok(!!bitmap, "Expected target bitmap.\n");
ID2D1Bitmap1_Release(bitmap);
bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap);
ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET);
ID2D1DeviceContext_SetTarget(device_context, NULL);
ID2D1DeviceContext_SetTags(device_context, 3, 4);
ID2D1DeviceContext_BeginDraw(device_context);
ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
hr = ID2D1DeviceContext_EndDraw(device_context, &t1, &t2);
ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
ok(!t1 && !t2, "Unexpected tags %s:%s.\n", wine_dbgstr_longlong(t1), wine_dbgstr_longlong(t2));
ID2D1Bitmap1_Release(bitmap);
ID2D1DeviceContext_Release(device_context);
} }
ID2D1Device_Release(device); ID2D1Device_Release(device);
IDXGIDevice_Release(dxgi_device); IDXGIDevice_Release(dxgi_device);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment