[PATCH 4/5] d2d1: Implement bitmap brush support for d2d_d3d_render_target_FillRectangle().
Henri Verbeet
hverbeet at codeweavers.com
Fri Feb 6 02:57:01 CST 2015
---
dlls/d2d1/bitmap.c | 51 +++++++++++++++++-
dlls/d2d1/brush.c | 45 ++++++++++++++--
dlls/d2d1/d2d1_private.h | 17 ++++--
dlls/d2d1/render_target.c | 128 +++++++++++++++++++++++++++++++++++++++------
4 files changed, 216 insertions(+), 25 deletions(-)
diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c
index e827e46..ccc8d75 100644
--- a/dlls/d2d1/bitmap.c
+++ b/dlls/d2d1/bitmap.c
@@ -65,7 +65,10 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_Release(ID2D1Bitmap *iface)
TRACE("%p increasing refcount to %u.\n", iface, refcount);
if (!refcount)
+ {
+ ID3D10ShaderResourceView_Release(bitmap->view);
HeapFree(GetProcessHeap(), 0, bitmap);
+ }
return refcount;
}
@@ -156,14 +159,48 @@ static const struct ID2D1BitmapVtbl d2d_bitmap_vtbl =
d2d_bitmap_CopyFromMemory,
};
-void d2d_bitmap_init(struct d2d_bitmap *bitmap, D2D1_SIZE_U size, const void *src_data,
- UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc)
+HRESULT d2d_bitmap_init(struct d2d_bitmap *bitmap, struct d2d_d3d_render_target *render_target,
+ D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc)
{
+ D3D10_SUBRESOURCE_DATA resource_data;
+ D3D10_TEXTURE2D_DESC texture_desc;
+ ID3D10Texture2D *texture;
+ HRESULT hr;
+
FIXME("Ignoring bitmap properties.\n");
bitmap->ID2D1Bitmap_iface.lpVtbl = &d2d_bitmap_vtbl;
bitmap->refcount = 1;
+ texture_desc.Width = size.width;
+ texture_desc.Height = size.height;
+ texture_desc.MipLevels = 1;
+ texture_desc.ArraySize = 1;
+ texture_desc.Format = desc->pixelFormat.format;
+ texture_desc.SampleDesc.Count = 1;
+ texture_desc.SampleDesc.Quality = 0;
+ texture_desc.Usage = D3D10_USAGE_DEFAULT;
+ texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
+ texture_desc.CPUAccessFlags = 0;
+ texture_desc.MiscFlags = 0;
+
+ resource_data.pSysMem = src_data;
+ resource_data.SysMemPitch = pitch;
+
+ if (FAILED(hr = ID3D10Device_CreateTexture2D(render_target->device, &texture_desc, &resource_data, &texture)))
+ {
+ ERR("Failed to create texture, hr %#x.\n", hr);
+ return hr;
+ }
+
+ hr = ID3D10Device_CreateShaderResourceView(render_target->device, (ID3D10Resource *)texture, NULL, &bitmap->view);
+ ID3D10Texture2D_Release(texture);
+ if (FAILED(hr))
+ {
+ ERR("Failed to create view, hr %#x.\n", hr);
+ return hr;
+ }
+
bitmap->pixel_size = size;
bitmap->dpi_x = desc->dpiX;
bitmap->dpi_y = desc->dpiY;
@@ -173,4 +210,14 @@ void d2d_bitmap_init(struct d2d_bitmap *bitmap, D2D1_SIZE_U size, const void *sr
bitmap->dpi_x = 96.0f;
bitmap->dpi_y = 96.0f;
}
+
+ return S_OK;
+}
+
+struct d2d_bitmap *unsafe_impl_from_ID2D1Bitmap(ID2D1Bitmap *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &d2d_bitmap_vtbl);
+ return CONTAINING_RECORD(iface, struct d2d_bitmap, ID2D1Bitmap_iface);
}
diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c
index d6d9ef2..f2451e6 100644
--- a/dlls/d2d1/brush.c
+++ b/dlls/d2d1/brush.c
@@ -498,7 +498,10 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_brush_Release(ID2D1BitmapBrush *iface)
TRACE("%p decreasing refcount to %u.\n", iface, refcount);
if (!refcount)
+ {
+ ID3D10SamplerState_Release(brush->u.bitmap.sampler_state);
HeapFree(GetProcessHeap(), 0, brush);
+ }
return refcount;
}
@@ -616,13 +619,40 @@ static const struct ID2D1BitmapBrushVtbl d2d_bitmap_brush_vtbl =
d2d_bitmap_brush_GetBitmap,
};
-void d2d_bitmap_brush_init(struct d2d_brush *brush, ID2D1RenderTarget *render_target, const ID2D1Bitmap *bitmap,
+HRESULT d2d_bitmap_brush_init(struct d2d_brush *brush, struct d2d_d3d_render_target *render_target, ID2D1Bitmap *bitmap,
const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc)
{
+ D3D10_SAMPLER_DESC sampler_desc;
+ HRESULT hr;
+
FIXME("Ignoring brush properties.\n");
- d2d_brush_init(brush, render_target, D2D_BRUSH_TYPE_BITMAP, brush_desc,
- (ID2D1BrushVtbl *)&d2d_bitmap_brush_vtbl);
+ d2d_brush_init(brush, &render_target->ID2D1RenderTarget_iface, D2D_BRUSH_TYPE_BITMAP,
+ brush_desc, (ID2D1BrushVtbl *)&d2d_bitmap_brush_vtbl);
+ brush->u.bitmap.bitmap = unsafe_impl_from_ID2D1Bitmap(bitmap);
+
+ sampler_desc.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT;
+ sampler_desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP;
+ sampler_desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP;
+ sampler_desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP;
+ sampler_desc.MipLODBias = 0.0f;
+ sampler_desc.MaxAnisotropy = 0;
+ sampler_desc.ComparisonFunc = D3D10_COMPARISON_NEVER;
+ sampler_desc.BorderColor[0] = 0.0f;
+ sampler_desc.BorderColor[1] = 0.0f;
+ sampler_desc.BorderColor[2] = 0.0f;
+ sampler_desc.BorderColor[3] = 0.0f;
+ sampler_desc.MinLOD = 0.0f;
+ sampler_desc.MaxLOD = 0.0f;
+
+ if (FAILED(hr = ID3D10Device_CreateSamplerState(render_target->device,
+ &sampler_desc, &brush->u.bitmap.sampler_state)))
+ {
+ ERR("Failed to create sampler state, hr %#x.\n", hr);
+ return hr;
+ }
+
+ return S_OK;
}
struct d2d_brush *unsafe_impl_from_ID2D1Brush(ID2D1Brush *iface)
@@ -634,3 +664,12 @@ struct d2d_brush *unsafe_impl_from_ID2D1Brush(ID2D1Brush *iface)
|| iface->lpVtbl == (const ID2D1BrushVtbl *)&d2d_bitmap_brush_vtbl);
return CONTAINING_RECORD(iface, struct d2d_brush, ID2D1Brush_iface);
}
+
+void d2d_brush_bind_resources(struct d2d_brush *brush, ID3D10Device *device)
+{
+ if (brush->type == D2D_BRUSH_TYPE_BITMAP)
+ {
+ ID3D10Device_PSSetShaderResources(device, 0, 1, &brush->u.bitmap.bitmap->view);
+ ID3D10Device_PSSetSamplers(device, 0, 1, &brush->u.bitmap.sampler_state);
+ }
+}
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index 0402c8d..72c1c57 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -61,6 +61,7 @@ struct d2d_d3d_render_target
ID3D10BlendState *bs;
ID3D10PixelShader *rect_solid_ps;
+ ID3D10PixelShader *rect_bitmap_ps;
D2D1_SIZE_U pixel_size;
D2D1_MATRIX_3X2_F transform;
@@ -118,6 +119,11 @@ struct d2d_brush
{
D2D1_COLOR_F color;
} solid;
+ struct
+ {
+ struct d2d_bitmap *bitmap;
+ ID3D10SamplerState *sampler_state;
+ } bitmap;
} u;
};
@@ -126,9 +132,10 @@ void d2d_solid_color_brush_init(struct d2d_brush *brush, ID2D1RenderTarget *rend
void d2d_linear_gradient_brush_init(struct d2d_brush *brush, ID2D1RenderTarget *render_target,
const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc,
ID2D1GradientStopCollection *gradient) DECLSPEC_HIDDEN;
-void d2d_bitmap_brush_init(struct d2d_brush *brush, ID2D1RenderTarget *render_target,
- const ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc,
+HRESULT d2d_bitmap_brush_init(struct d2d_brush *brush, struct d2d_d3d_render_target *render_target,
+ ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc,
const D2D1_BRUSH_PROPERTIES *brush_desc) DECLSPEC_HIDDEN;
+void d2d_brush_bind_resources(struct d2d_brush *brush, ID3D10Device *device) DECLSPEC_HIDDEN;
struct d2d_brush *unsafe_impl_from_ID2D1Brush(ID2D1Brush *iface) DECLSPEC_HIDDEN;
struct d2d_stroke_style
@@ -153,12 +160,14 @@ struct d2d_bitmap
ID2D1Bitmap ID2D1Bitmap_iface;
LONG refcount;
+ ID3D10ShaderResourceView *view;
D2D1_SIZE_U pixel_size;
float dpi_x;
float dpi_y;
};
-void d2d_bitmap_init(struct d2d_bitmap *bitmap, D2D1_SIZE_U size, const void *src_data,
- UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc) DECLSPEC_HIDDEN;
+HRESULT d2d_bitmap_init(struct d2d_bitmap *bitmap, struct d2d_d3d_render_target *render_target,
+ D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc) DECLSPEC_HIDDEN;
+struct d2d_bitmap *unsafe_impl_from_ID2D1Bitmap(ID2D1Bitmap *iface) DECLSPEC_HIDDEN;
#endif /* __WINE_D2D1_PRIVATE_H */
diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c
index bdefab8..3d9abb8 100644
--- a/dlls/d2d1/render_target.c
+++ b/dlls/d2d1/render_target.c
@@ -122,7 +122,7 @@ static void d2d_clip_stack_pop(struct d2d_clip_stack *stack)
}
static void d2d_draw(struct d2d_d3d_render_target *render_target, ID3D10Buffer *vs_cb,
- ID3D10PixelShader *ps, ID3D10Buffer *ps_cb, BOOL blend)
+ ID3D10PixelShader *ps, ID3D10Buffer *ps_cb, struct d2d_brush *brush)
{
ID3D10Device *device = render_target->device;
unsigned int offset;
@@ -169,8 +169,11 @@ static void d2d_draw(struct d2d_d3d_render_target *render_target, ID3D10Buffer *
ID3D10Device_RSSetState(device, render_target->rs);
}
ID3D10Device_OMSetRenderTargets(device, 1, &render_target->view, NULL);
- if (blend)
+ if (brush)
+ {
ID3D10Device_OMSetBlendState(device, render_target->bs, blend_factor, D3D10_DEFAULT_SAMPLE_MASK);
+ d2d_brush_bind_resources(brush, device);
+ }
ID3D10Device_Draw(device, 4, 0);
@@ -222,6 +225,7 @@ static ULONG STDMETHODCALLTYPE d2d_d3d_render_target_Release(ID2D1RenderTarget *
if (!refcount)
{
d2d_clip_stack_cleanup(&render_target->clip_stack);
+ ID3D10PixelShader_Release(render_target->rect_bitmap_ps);
ID3D10PixelShader_Release(render_target->rect_solid_ps);
ID3D10BlendState_Release(render_target->bs);
ID3D10RasterizerState_Release(render_target->rs);
@@ -247,7 +251,9 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_GetFactory(ID2D1RenderTarget
static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmap(ID2D1RenderTarget *iface,
D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
{
+ struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
struct d2d_bitmap *object;
+ HRESULT hr;
TRACE("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p.\n",
iface, size.width, size.height, src_data, pitch, desc, bitmap);
@@ -255,7 +261,12 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmap(ID2D1RenderT
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
- d2d_bitmap_init(object, size, src_data, pitch, desc);
+ if (FAILED(hr = d2d_bitmap_init(object, render_target, size, src_data, pitch, desc)))
+ {
+ WARN("Failed to initialize bitmap, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
TRACE("Created bitmap %p.\n", object);
*bitmap = &object->ID2D1Bitmap_iface;
@@ -364,7 +375,9 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapBrush(ID2D1Re
ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc,
const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush **brush)
{
+ struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
struct d2d_brush *object;
+ HRESULT hr;
TRACE("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n",
iface, bitmap, bitmap_brush_desc, brush_desc, brush);
@@ -372,7 +385,12 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapBrush(ID2D1Re
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
- d2d_bitmap_brush_init(object, iface, bitmap, bitmap_brush_desc, brush_desc);
+ if (FAILED(hr = d2d_bitmap_brush_init(object, render_target, bitmap, bitmap_brush_desc, brush_desc)))
+ {
+ WARN("Failed to initialize brush, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
TRACE("Created brush %p.\n", object);
*brush = (ID2D1BitmapBrush *)&object->ID2D1Brush_iface;
@@ -511,6 +529,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRectangle(ID2D1RenderTar
D3D10_SUBRESOURCE_DATA buffer_data;
D3D10_BUFFER_DESC buffer_desc;
ID3D10Buffer *vs_cb, *ps_cb;
+ ID3D10PixelShader *ps;
D2D1_COLOR_F color;
float tmp_x, tmp_y;
HRESULT hr;
@@ -518,11 +537,12 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRectangle(ID2D1RenderTar
{
float _11, _21, _31, pad0;
float _12, _22, _32, pad1;
- } transform;
+ } transform, transform_inverse;
TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush);
- if (brush_impl->type != D2D_BRUSH_TYPE_SOLID)
+ if (brush_impl->type != D2D_BRUSH_TYPE_SOLID
+ && brush_impl->type != D2D_BRUSH_TYPE_BITMAP)
{
FIXME("Unhandled brush type %#x.\n", brush_impl->type);
return;
@@ -569,14 +589,55 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRectangle(ID2D1RenderTar
return;
}
- color = brush_impl->u.solid.color;
- color.r *= brush_impl->opacity;
- color.g *= brush_impl->opacity;
- color.b *= brush_impl->opacity;
- color.a *= brush_impl->opacity;
+ if (brush_impl->type == D2D_BRUSH_TYPE_BITMAP)
+ {
+ struct d2d_bitmap *bitmap = brush_impl->u.bitmap.bitmap;
+ float rt_scale, rt_bitmap_scale, d;
+
+ ps = render_target->rect_bitmap_ps;
+
+ /* Scale for bitmap size and dpi. */
+ rt_scale = render_target->dpi_x / 96.0f;
+ rt_bitmap_scale = bitmap->pixel_size.width * (bitmap->dpi_x / 96.0f) * rt_scale;
+ transform._11 = brush_impl->transform._11 * rt_bitmap_scale;
+ transform._21 = brush_impl->transform._21 * rt_bitmap_scale;
+ transform._31 = brush_impl->transform._31 * rt_scale;
+ rt_scale = render_target->dpi_y / 96.0f;
+ rt_bitmap_scale = bitmap->pixel_size.height * (bitmap->dpi_y / 96.0f) * rt_scale;
+ transform._12 = brush_impl->transform._12 * rt_bitmap_scale;
+ transform._22 = brush_impl->transform._22 * rt_bitmap_scale;
+ transform._32 = brush_impl->transform._32 * rt_scale;
+
+ /* Invert the matrix. (Because the matrix is applied to the sampling
+ * coordinates. I.e., to scale the bitmap by 2 we need to divide the
+ * coordinates by 2.) */
+ d = transform._11 * transform._22 - transform._21 * transform._22;
+ if (d != 0.0f)
+ {
+ transform_inverse._11 = transform._22 / d;
+ transform_inverse._21 = -transform._21 / d;
+ transform_inverse._31 = (transform._21 * transform._32 - transform._31 * transform._22) / d;
+ transform_inverse._12 = -transform._12 / d;
+ transform_inverse._22 = transform._11 / d;
+ transform_inverse._32 = -(transform._11 * transform._32 - transform._31 * transform._12) / d;
+ }
- buffer_desc.ByteWidth = sizeof(color);
- buffer_data.pSysMem = &color;
+ buffer_desc.ByteWidth = sizeof(transform_inverse);
+ buffer_data.pSysMem = &transform_inverse;
+ }
+ else
+ {
+ ps = render_target->rect_solid_ps;
+
+ color = brush_impl->u.solid.color;
+ color.r *= brush_impl->opacity;
+ color.g *= brush_impl->opacity;
+ color.b *= brush_impl->opacity;
+ color.a *= brush_impl->opacity;
+
+ buffer_desc.ByteWidth = sizeof(color);
+ buffer_data.pSysMem = &color;
+ }
if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &ps_cb)))
{
@@ -585,7 +646,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRectangle(ID2D1RenderTar
return;
}
- d2d_draw(render_target, vs_cb, render_target->rect_solid_ps, ps_cb, TRUE);
+ d2d_draw(render_target, vs_cb, ps, ps_cb, brush_impl);
ID3D10Buffer_Release(ps_cb);
ID3D10Buffer_Release(vs_cb);
@@ -870,7 +931,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *ifa
return;
}
- d2d_draw(render_target, vs_cb, render_target->rect_solid_ps, ps_cb, FALSE);
+ d2d_draw(render_target, vs_cb, render_target->rect_solid_ps, ps_cb, NULL);
ID3D10Buffer_Release(ps_cb);
ID3D10Buffer_Release(vs_cb);
@@ -1197,6 +1258,32 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target,
0x00000010, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
};
+ static const DWORD rect_bitmap_ps_code[] =
+ {
+#if 0
+ float3x2 transform;
+ SamplerState s;
+ Texture2D t;
+
+ float4 main(float4 position : SV_POSITION) : SV_Target
+ {
+ return t.Sample(s, mul(float3(position.xy, 1.0), transform));
+ }
+#endif
+ 0x43425844, 0x20fce5be, 0x138fa37f, 0x9554f03f, 0x3dbe9c02, 0x00000001, 0x00000184, 0x00000003,
+ 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
+ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
+ 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000e8, 0x00000040,
+ 0x0000003a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0300005a, 0x00106000, 0x00000000,
+ 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001,
+ 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x05000036, 0x00100032, 0x00000000,
+ 0x00101046, 0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0x3f800000, 0x08000010,
+ 0x00100012, 0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000010,
+ 0x00100022, 0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000001, 0x09000045,
+ 0x001020f2, 0x00000000, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, 0x00000000,
+ 0x0100003e,
+ };
static const struct
{
float x, y;
@@ -1320,7 +1407,14 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target,
if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->device,
rect_solid_ps_code, sizeof(rect_solid_ps_code), &render_target->rect_solid_ps)))
{
- WARN("Failed to create clear pixel shader, hr %#x.\n", hr);
+ WARN("Failed to create pixel shader, hr %#x.\n", hr);
+ goto err;
+ }
+
+ if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->device,
+ rect_bitmap_ps_code, sizeof(rect_bitmap_ps_code), &render_target->rect_bitmap_ps)))
+ {
+ WARN("Failed to create pixel shader, hr %#x.\n", hr);
goto err;
}
@@ -1353,6 +1447,8 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target,
return S_OK;
err:
+ if (render_target->rect_bitmap_ps)
+ ID3D10PixelShader_Release(render_target->rect_bitmap_ps);
if (render_target->rect_solid_ps)
ID3D10PixelShader_Release(render_target->rect_solid_ps);
if (render_target->bs)
--
1.7.10.4
More information about the wine-patches
mailing list