[PATCH 1/2] d2d1: Implement ID2D1Bitmap1::Map().

Dmitry Timoshkov dmitry at baikal.ru
Thu May 12 08:23:17 CDT 2022


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/d2d1/bitmap.c       | 65 ++++++++++++++++++++++++++++++++++++++--
 dlls/d2d1/d2d1_private.h |  1 +
 2 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c
index 971e3c7ff6b..bab3575c431 100644
--- a/dlls/d2d1/bitmap.c
+++ b/dlls/d2d1/bitmap.c
@@ -226,12 +226,73 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_GetSurface(ID2D1Bitmap1 *iface, IDXG
     return *surface ? S_OK : D2DERR_INVALID_CALL;
 }
 
+static unsigned int d3d11_cpu_access_from_d2d1_map_options(map_options)
+{
+    unsigned int cpu_access = 0;
+
+    if (map_options & D2D1_MAP_OPTIONS_READ)
+        cpu_access |= D3D11_CPU_ACCESS_READ;
+    if (map_options & D2D1_MAP_OPTIONS_WRITE)
+        cpu_access |= D3D11_CPU_ACCESS_WRITE;
+    if (map_options &= ~(D2D1_MAP_OPTIONS_READ | D2D1_MAP_OPTIONS_WRITE))
+        FIXME("Unhandled map options flags %#x.\n", map_options);
+
+    return cpu_access;
+}
+
+static unsigned int d3d11_map_from_d2d1_map_options(map_options)
+{
+    unsigned int map = 0;
+
+    if (map_options & D2D1_MAP_OPTIONS_READ)
+        map |= D3D11_MAP_READ;
+    if (map_options & D2D1_MAP_OPTIONS_WRITE)
+        map |= D3D11_MAP_WRITE;
+    if (map_options &= ~(D2D1_MAP_OPTIONS_READ | D2D1_MAP_OPTIONS_WRITE))
+        FIXME("Unhandled map options flags %#x.\n", map_options);
+
+    return map;
+}
+
 static HRESULT STDMETHODCALLTYPE d2d_bitmap_Map(ID2D1Bitmap1 *iface, D2D1_MAP_OPTIONS options,
         D2D1_MAPPED_RECT *mapped_rect)
 {
-    FIXME("iface %p, options %#x, mapped_rect %p stub!\n", iface, options, mapped_rect);
+    struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap1(iface);
+    ID3D11Device *device;
+    ID3D11DeviceContext *context;
+    D3D11_TEXTURE2D_DESC texture_desc;
+    ID3D11Texture2D *staging_texture;
+    D3D11_MAPPED_SUBRESOURCE mapped_subresource;
+    HRESULT hr;
 
-    return E_NOTIMPL;
+    TRACE("iface %p, options %#x, mapped_rect %p.\n", iface, options, mapped_rect);
+
+    ID3D11Resource_GetDevice(bitmap->resource, &device);
+    ID3D11Device_GetImmediateContext(device, &context);
+    ID3D11Texture2D_GetDesc((ID3D11Texture2D *)bitmap->resource, &texture_desc);
+
+    texture_desc.Usage = D3D11_USAGE_STAGING;
+    texture_desc.BindFlags = 0;
+    texture_desc.CPUAccessFlags = d3d11_cpu_access_from_d2d1_map_options(options);
+    ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &staging_texture);
+    ID3D11DeviceContext_CopyResource(context, (ID3D11Resource *)staging_texture, bitmap->resource);
+    if (SUCCEEDED(hr = ID3D11DeviceContext_Map(context, (ID3D11Resource *)staging_texture, 0,
+            d3d11_map_from_d2d1_map_options(options), 0, &mapped_subresource)))
+    {
+        mapped_rect->pitch = mapped_subresource.RowPitch;
+        mapped_rect->bits = mapped_subresource.pData;
+        bitmap->staging_resource = (ID3D11Resource *)staging_texture;
+    }
+    else
+    {
+        WARN("Failed to map resource, hr %#lx.\n", hr);
+        ID3D11Texture2D_Release(staging_texture);
+    }
+
+    ID3D11DeviceContext_Release(context);
+    ID3D11Device_Release(device);
+
+    return hr;
 }
 
 static HRESULT STDMETHODCALLTYPE d2d_bitmap_Unmap(ID2D1Bitmap1 *iface)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index aa8e8569455..da5f9b5a90a 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -382,6 +382,7 @@ struct d2d_bitmap
     ID3D11RenderTargetView *rtv;
     IDXGISurface *surface;
     ID3D11Resource *resource;
+    ID3D11Resource *staging_resource;
     D2D1_SIZE_U pixel_size;
     D2D1_PIXEL_FORMAT format;
     float dpi_x;
-- 
2.35.3




More information about the wine-devel mailing list