[PATCH] d2d1: Only create shader resource views for drawable bitmaps.

Henri Verbeet hverbeet at codeweavers.com
Wed Sep 25 14:05:57 CDT 2019


From: Brendan Shanks <bshanks at codeweavers.com>

The underlying resource for bitmaps created with
D2D1_BITMAP_OPTIONS_CANNOT_DRAW doesn't necessarily have
D3D10_BIND_SHADER_RESOURCE in its bind flags.

Original patch by Robin Kertels <robin.kertels at gmail.com>

Signed-off-by: Brendan Shanks <bshanks at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/d2d1/bitmap.c           | 65 ++++++++++++++++----------------------------
 dlls/d2d1/brush.c            |  2 +-
 dlls/d2d1/d2d1_private.h     |  3 +-
 dlls/d2d1/dc_render_target.c |  5 +---
 4 files changed, 27 insertions(+), 48 deletions(-)

diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c
index 39e81192f77..dc5ed9e6ad7 100644
--- a/dlls/d2d1/bitmap.c
+++ b/dlls/d2d1/bitmap.c
@@ -66,11 +66,13 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_Release(ID2D1Bitmap1 *iface)
 
     if (!refcount)
     {
-        ID3D10ShaderResourceView_Release(bitmap->view);
+        if (bitmap->srv)
+            ID3D10ShaderResourceView_Release(bitmap->srv);
         if (bitmap->rtv)
             ID3D10RenderTargetView_Release(bitmap->rtv);
         if (bitmap->surface)
             IDXGISurface_Release(bitmap->surface);
+        ID3D10Resource_Release(bitmap->resource);
         ID2D1Factory_Release(bitmap->factory);
         heap_free(bitmap);
     }
@@ -149,7 +151,6 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap1 *iface,
 {
     struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap1(iface);
     ID3D10Device *device;
-    ID3D10Resource *dst;
     D3D10_BOX box;
 
     TRACE("iface %p, dst_rect %p, src_data %p, pitch %u.\n", iface, dst_rect, src_data, pitch);
@@ -164,11 +165,9 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap1 *iface,
         box.back = 1;
     }
 
-    ID3D10ShaderResourceView_GetResource(bitmap->view, &dst);
-    ID3D10ShaderResourceView_GetDevice(bitmap->view, &device);
-    ID3D10Device_UpdateSubresource(device, dst, 0, dst_rect ? &box : NULL, src_data, pitch, 0);
+    ID3D10Resource_GetDevice(bitmap->resource, &device);
+    ID3D10Device_UpdateSubresource(device, bitmap->resource, 0, dst_rect ? &box : NULL, src_data, pitch, 0);
     ID3D10Device_Release(device);
-    ID3D10Resource_Release(dst);
 
     return S_OK;
 }
@@ -271,36 +270,37 @@ static BOOL format_supported(const D2D1_PIXEL_FORMAT *format)
 }
 
 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)
+        ID3D10Resource *resource, D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES1 *desc)
 {
-    ID3D10Resource *resource;
     ID3D10Device *d3d_device;
     HRESULT hr;
 
     bitmap->ID2D1Bitmap1_iface.lpVtbl = &d2d_bitmap_vtbl;
     bitmap->refcount = 1;
     ID2D1Factory_AddRef(bitmap->factory = context->factory);
-    ID3D10ShaderResourceView_AddRef(bitmap->view = view);
+    ID3D10Resource_AddRef(bitmap->resource = resource);
     bitmap->pixel_size = size;
     bitmap->format = desc->pixelFormat;
     bitmap->dpi_x = desc->dpiX;
     bitmap->dpi_y = desc->dpiY;
     bitmap->options = desc->bitmapOptions;
 
-    ID3D10ShaderResourceView_GetResource(bitmap->view, &resource);
-
     if (d2d_device_context_is_dxgi_target(context))
         ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface, (void **)&bitmap->surface);
 
+    ID3D10Resource_GetDevice(resource, &d3d_device);
     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);
+            WARN("Failed to create RTV, hr %#x.\n", hr);
     }
 
-    ID3D10Resource_Release(resource);
+    if (!(bitmap->options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW))
+    {
+        if (FAILED(hr = ID3D10Device_CreateShaderResourceView(d3d_device, resource, NULL, &bitmap->srv)))
+            WARN("Failed to create SRV, hr %#x.\n", hr);
+    }
+    ID3D10Device_Release(d3d_device);
 
     if (bitmap->dpi_x == 0.0f && bitmap->dpi_y == 0.0f)
     {
@@ -314,7 +314,6 @@ HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size,
 {
     D3D10_SUBRESOURCE_DATA resource_data;
     D3D10_TEXTURE2D_DESC texture_desc;
-    ID3D10ShaderResourceView *view;
     ID3D10Texture2D *texture;
     HRESULT hr;
 
@@ -355,21 +354,12 @@ HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size,
         return hr;
     }
 
-    hr = ID3D10Device_CreateShaderResourceView(context->d3d_device, (ID3D10Resource *)texture, NULL, &view);
-    ID3D10Texture2D_Release(texture);
-    if (FAILED(hr))
-    {
-        ERR("Failed to create view, hr %#x.\n", hr);
-        return hr;
-    }
-
     if ((*bitmap = heap_alloc_zero(sizeof(**bitmap))))
     {
-        d2d_bitmap_init(*bitmap, context, view, size, desc);
+        d2d_bitmap_init(*bitmap, context, (ID3D10Resource *)texture, size, desc);
         TRACE("Created bitmap %p.\n", *bitmap);
     }
-
-    ID3D10ShaderResourceView_Release(view);
+    ID3D10Texture2D_Release(texture);
 
     return *bitmap ? S_OK : E_OUTOFMEMORY;
 }
@@ -391,7 +381,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
             goto failed;
         }
 
-        ID3D10ShaderResourceView_GetDevice(src_impl->view, &device);
+        ID3D10Resource_GetDevice(src_impl->resource, &device);
         ID3D10Device_Release(device);
         if (device != context->d3d_device)
         {
@@ -423,7 +413,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
             goto failed;
         }
 
-        d2d_bitmap_init(*bitmap, context, src_impl->view, src_impl->pixel_size, desc);
+        d2d_bitmap_init(*bitmap, context, src_impl->resource, src_impl->pixel_size, desc);
         TRACE("Created bitmap %p.\n", *bitmap);
 
     failed:
@@ -432,7 +422,6 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
 
     if (IsEqualGUID(iid, &IID_IDXGISurface) || IsEqualGUID(iid, &IID_IDXGISurface1))
     {
-        ID3D10ShaderResourceView *view;
         DXGI_SURFACE_DESC surface_desc;
         IDXGISurface *surface = data;
         ID3D10Resource *resource;
@@ -454,17 +443,9 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
             return D2DERR_UNSUPPORTED_OPERATION;
         }
 
-        hr = ID3D10Device_CreateShaderResourceView(context->d3d_device, resource, NULL, &view);
-        ID3D10Resource_Release(resource);
-        if (FAILED(hr))
-        {
-            WARN("Failed to create shader resource view, hr %#x.\n", hr);
-            return hr;
-        }
-
         if (!(*bitmap = heap_alloc_zero(sizeof(**bitmap))))
         {
-            ID3D10ShaderResourceView_Release(view);
+            ID3D10Resource_Release(resource);
             return E_OUTOFMEMORY;
         }
 
@@ -472,7 +453,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
         if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc)))
         {
             WARN("Failed to get surface desc, hr %#x.\n", hr);
-            ID3D10ShaderResourceView_Release(view);
+            ID3D10Resource_Release(resource);
             return hr;
         }
 
@@ -499,8 +480,8 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
         pixel_size.width = surface_desc.Width;
         pixel_size.height = surface_desc.Height;
 
-        d2d_bitmap_init(*bitmap, context, view, pixel_size, &d);
-        ID3D10ShaderResourceView_Release(view);
+        d2d_bitmap_init(*bitmap, context, resource, pixel_size, &d);
+        ID3D10Resource_Release(resource);
         TRACE("Created bitmap %p.\n", *bitmap);
 
         return S_OK;
diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c
index 21abf1456ab..80fc0f53317 100644
--- a/dlls/d2d1/brush.c
+++ b/dlls/d2d1/brush.c
@@ -1295,7 +1295,7 @@ static void d2d_brush_bind_bitmap(struct d2d_brush *brush, ID3D10Device *device,
 {
     HRESULT hr;
 
-    ID3D10Device_PSSetShaderResources(device, brush_idx, 1, &brush->u.bitmap.bitmap->view);
+    ID3D10Device_PSSetShaderResources(device, brush_idx, 1, &brush->u.bitmap.bitmap->srv);
     if (!brush->u.bitmap.sampler_state)
     {
         D3D10_SAMPLER_DESC sampler_desc;
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index b07893ae18c..2e42d6d5503 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -346,9 +346,10 @@ struct d2d_bitmap
     LONG refcount;
 
     ID2D1Factory *factory;
-    ID3D10ShaderResourceView *view;
+    ID3D10ShaderResourceView *srv;
     ID3D10RenderTargetView *rtv;
     IDXGISurface *surface;
+    ID3D10Resource *resource;
     D2D1_SIZE_U pixel_size;
     D2D1_PIXEL_FORMAT format;
     float dpi_x;
diff --git a/dlls/d2d1/dc_render_target.c b/dlls/d2d1/dc_render_target.c
index 310c5412967..47aa99697d7 100644
--- a/dlls/d2d1/dc_render_target.c
+++ b/dlls/d2d1/dc_render_target.c
@@ -687,7 +687,6 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget
     struct d2d_bitmap *bitmap_impl;
     IDXGISurface1 *dxgi_surface;
     ID2D1DeviceContext *context;
-    ID3D10Resource *resource;
     D2D1_SIZE_U bitmap_size;
     ID2D1Bitmap *bitmap;
     HRESULT hr;
@@ -716,9 +715,7 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget
     }
 
     bitmap_impl = unsafe_impl_from_ID2D1Bitmap(bitmap);
-    ID3D10ShaderResourceView_GetResource(bitmap_impl->view, &resource);
-    ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface1, (void **)&dxgi_surface);
-    ID3D10Resource_Release(resource);
+    ID3D10Resource_QueryInterface(bitmap_impl->resource, &IID_IDXGISurface1, (void **)&dxgi_surface);
 
     ID2D1DeviceContext_SetTarget(context, (ID2D1Image *)bitmap);
     ID2D1Bitmap_Release(bitmap);
-- 
2.11.0




More information about the wine-devel mailing list