[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