Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
September 2018
- 70 participants
- 1549 messages
[PATCH 1/4] comctl32/pager: Support date time picker notification conversion.
by Zhiyi Zhang
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/comctl32/pager.c | 65 +++++++++++++++++++++++++
dlls/comctl32/tests/pager.c | 97 +++++++++++++++++++++++++++++++++++++
2 files changed, 162 insertions(+)
diff --git a/dlls/comctl32/pager.c b/dlls/comctl32/pager.c
index 96a66806ee..605141b9ab 100644
--- a/dlls/comctl32/pager.c
+++ b/dlls/comctl32/pager.c
@@ -1046,6 +1046,11 @@ static UINT PAGER_GetAnsiNtfCode(UINT code)
case CBEN_DRAGBEGINW: return CBEN_DRAGBEGINA;
case CBEN_ENDEDITW: return CBEN_ENDEDITA;
case CBEN_GETDISPINFOW: return CBEN_GETDISPINFOA;
+ /* Date and Time Picker */
+ case DTN_FORMATW: return DTN_FORMATA;
+ case DTN_FORMATQUERYW: return DTN_FORMATQUERYA;
+ case DTN_USERSTRINGW: return DTN_USERSTRINGA;
+ case DTN_WMKEYDOWNW: return DTN_WMKEYDOWNA;
/* Toolbar */
case TBN_GETBUTTONINFOW: return TBN_GETBUTTONINFOA;
case TBN_GETINFOTIPW: return TBN_GETINFOTIPA;
@@ -1068,6 +1073,23 @@ static BOOL PAGER_AdjustBuffer(PAGER_INFO *infoPtr, INT size)
return TRUE;
}
+/* Convert text to Unicode and return the original text address */
+static WCHAR *PAGER_ConvertText(WCHAR **text)
+{
+ WCHAR *oldText = *text;
+ *text = NULL;
+ Str_SetPtrWtoA((CHAR **)text, oldText);
+ return oldText;
+}
+
+static void PAGER_RestoreText(WCHAR **text, WCHAR *oldText)
+{
+ if (!oldText) return;
+
+ Free(*text);
+ *text = oldText;
+}
+
static LRESULT PAGER_SendConvertedNotify(PAGER_INFO *infoPtr, NMHDR *hdr, UINT *mask, UINT requiredMask, WCHAR **text,
INT *textMax, DWORD flags)
{
@@ -1166,6 +1188,49 @@ static LRESULT PAGER_Notify(PAGER_INFO *infoPtr, NMHDR *hdr)
NULL, FALSE);
return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, hdr->idFrom, (LPARAM)&nmedA);
}
+ /* Date and Time Picker */
+ case DTN_FORMATW:
+ {
+ NMDATETIMEFORMATW *nmdtf = (NMDATETIMEFORMATW *)hdr;
+ WCHAR *oldFormat;
+ INT textLength;
+
+ hdr->code = PAGER_GetAnsiNtfCode(hdr->code);
+ oldFormat = PAGER_ConvertText((WCHAR **)&nmdtf->pszFormat);
+ ret = SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, hdr->idFrom, (LPARAM)nmdtf);
+ PAGER_RestoreText((WCHAR **)&nmdtf->pszFormat, oldFormat);
+
+ if (nmdtf->pszDisplay)
+ {
+ textLength = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)nmdtf->pszDisplay, -1, 0, 0);
+ if (!PAGER_AdjustBuffer(infoPtr, textLength * sizeof(WCHAR))) return ret;
+ MultiByteToWideChar(CP_ACP, 0, (LPCSTR)nmdtf->pszDisplay, -1, infoPtr->pwszBuffer, textLength);
+ if (nmdtf->pszDisplay != nmdtf->szDisplay)
+ nmdtf->pszDisplay = infoPtr->pwszBuffer;
+ else
+ {
+ textLength = min(textLength, ARRAY_SIZE(nmdtf->szDisplay));
+ memcpy(nmdtf->szDisplay, infoPtr->pwszBuffer, textLength * sizeof(WCHAR));
+ }
+ }
+
+ return ret;
+ }
+ case DTN_FORMATQUERYW:
+ {
+ NMDATETIMEFORMATQUERYW *nmdtfq = (NMDATETIMEFORMATQUERYW *)hdr;
+ return PAGER_SendConvertedNotify(infoPtr, hdr, NULL, 0, (WCHAR **)&nmdtfq->pszFormat, NULL, CONVERT_SEND);
+ }
+ case DTN_WMKEYDOWNW:
+ {
+ NMDATETIMEWMKEYDOWNW *nmdtkd = (NMDATETIMEWMKEYDOWNW *)hdr;
+ return PAGER_SendConvertedNotify(infoPtr, hdr, NULL, 0, (WCHAR **)&nmdtkd->pszFormat, NULL, CONVERT_SEND);
+ }
+ case DTN_USERSTRINGW:
+ {
+ NMDATETIMESTRINGW *nmdts = (NMDATETIMESTRINGW *)hdr;
+ return PAGER_SendConvertedNotify(infoPtr, hdr, NULL, 0, (WCHAR **)&nmdts->pszUserString, NULL, CONVERT_SEND);
+ }
/* Toolbar */
case TBN_GETBUTTONINFOW:
{
diff --git a/dlls/comctl32/tests/pager.c b/dlls/comctl32/tests/pager.c
index b689549aa5..8993118711 100644
--- a/dlls/comctl32/tests/pager.c
+++ b/dlls/comctl32/tests/pager.c
@@ -32,6 +32,8 @@ static INT notify_format;
static BOOL notify_query_received;
static WCHAR test_w[] = {'t', 'e', 's', 't', 0};
static CHAR test_a[] = {'t', 'e', 's', 't', 0};
+/* Double zero so that it's safe to cast it to WCHAR * */
+static CHAR te_a[] = {'t', 'e', 0, 0};
static WCHAR empty_w[] = {0};
static CHAR empty_a[] = {0};
static CHAR large_a[] = "You should have received a copy of the GNU Lesser General Public License along with this ...";
@@ -180,6 +182,29 @@ static const struct notify_test_tooltip
{NULL, 0, large_a, NULL, large_truncated_80_w, sizeof(large_truncated_80_w), large_w}
};
+static const struct notify_test_datetime_format
+{
+ /* Data send to parent */
+ WCHAR *send_pszformat;
+ /* Data expected by parent */
+ CHAR *expect_pszformat;
+ /* Data for parent to write */
+ CHAR *write_szdisplay;
+ INT write_szdisplay_size;
+ CHAR *write_pszdisplay;
+ /* Data when message returned */
+ WCHAR *return_szdisplay;
+ INT return_szdisplay_size;
+ WCHAR *return_pszdisplay;
+} test_datetime_format_data[] =
+{
+ {test_w, test_a},
+ {NULL, NULL, NULL, 0, test_a, empty_w, -1, test_w},
+ {NULL, NULL, test_a, sizeof(test_a), NULL, test_w, -1, test_w},
+ {NULL, NULL, test_a, 2, test_a, (WCHAR *)te_a, -1, test_w},
+ {NULL, NULL, NULL, 0, large_a, NULL, 0, large_w}
+};
+
#define CHILD1_ID 1
#define CHILD2_ID 2
@@ -639,6 +664,18 @@ static void notify_tooltip_handler(NMTTDISPINFOA *nm)
if (data->write_hinst) nm->hinst = data->write_hinst;
}
+static void notify_datetime_handler(NMDATETIMEFORMATA *nm)
+{
+ const struct notify_test_datetime_format *data = test_datetime_format_data + notify_test_info.sub_test_id;
+ if (data->expect_pszformat)
+ ok(!lstrcmpA(data->expect_pszformat, nm->pszFormat), "Sub test %d expect %s, got %s\n",
+ notify_test_info.sub_test_id, data->expect_pszformat, nm->pszFormat);
+ ok(nm->pszDisplay == nm->szDisplay, "Test %d expect %p, got %p\n", notify_test_info.sub_test_id, nm->szDisplay,
+ nm->pszDisplay);
+ if (data->write_szdisplay) memcpy(nm->szDisplay, data->write_szdisplay, data->write_szdisplay_size);
+ if (data->write_pszdisplay) nm->pszDisplay = data->write_pszdisplay;
+}
+
static LRESULT WINAPI test_notify_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static const WCHAR test[] = {'t', 'e', 's', 't', 0};
@@ -690,6 +727,30 @@ static LRESULT WINAPI test_notify_proc(HWND hwnd, UINT message, WPARAM wParam, L
notify_generic_text_handler(&nmcbe->ceItem.pszText, &nmcbe->ceItem.cchTextMax);
break;
}
+ /* Date and Time Picker */
+ case DTN_FORMATA:
+ {
+ notify_datetime_handler((NMDATETIMEFORMATA *)hdr);
+ break;
+ }
+ case DTN_FORMATQUERYA:
+ {
+ NMDATETIMEFORMATQUERYA *nmdtfq = (NMDATETIMEFORMATQUERYA *)hdr;
+ notify_generic_text_handler((CHAR **)&nmdtfq->pszFormat, NULL);
+ break;
+ }
+ case DTN_WMKEYDOWNA:
+ {
+ NMDATETIMEWMKEYDOWNA *nmdtkd = (NMDATETIMEWMKEYDOWNA *)hdr;
+ notify_generic_text_handler((CHAR **)&nmdtkd->pszFormat, NULL);
+ break;
+ }
+ case DTN_USERSTRINGA:
+ {
+ NMDATETIMESTRINGA *nmdts = (NMDATETIMESTRINGA *)hdr;
+ notify_generic_text_handler((CHAR **)&nmdts->pszUserString, NULL);
+ break;
+ }
/* Toolbar */
case TBN_SAVE:
{
@@ -896,6 +957,30 @@ static void test_wm_notify_comboboxex(HWND pager)
ok(!lstrcmpW(nmcbeed.szText, test_w), "Expect %s, got %s\n", wine_dbgstr_w(test_w), wine_dbgstr_w(nmcbeed.szText));
}
+static void test_wm_notify_datetime(HWND pager)
+{
+ const struct notify_test_datetime_format *data;
+ NMDATETIMEFORMATW nmdtf;
+ INT i;
+
+ for (i = 0; i < ARRAY_SIZE(test_datetime_format_data); i++)
+ {
+ data = test_datetime_format_data + i;
+ notify_test_info.sub_test_id = i;
+
+ memset(&nmdtf, 0, sizeof(nmdtf));
+ if(data->send_pszformat) nmdtf.pszFormat = data->send_pszformat;
+ nmdtf.pszDisplay = nmdtf.szDisplay;
+ send_notify(pager, DTN_FORMATW, DTN_FORMATA, (LPARAM)&nmdtf, TRUE);
+ if (data->return_szdisplay)
+ ok(!lstrcmpW(nmdtf.szDisplay, data->return_szdisplay), "Sub test %d expect %s, got %s\n", i,
+ wine_dbgstr_w(data->return_szdisplay), wine_dbgstr_w(nmdtf.szDisplay));
+ if (data->return_pszdisplay)
+ ok(!lstrcmpW(nmdtf.pszDisplay, data->return_pszdisplay), "Sub test %d expect %s, got %s\n", i,
+ wine_dbgstr_w(data->return_pszdisplay), wine_dbgstr_w(nmdtf.pszDisplay));
+ }
+}
+
static void test_wm_notify_tooltip(HWND pager)
{
NMTTDISPINFOW nmttdi;
@@ -940,6 +1025,10 @@ static void test_wm_notify(void)
HWND parent, pager;
/* Combo Box Ex */
static NMCOMBOBOXEXW nmcbe;
+ /* Date and Time Picker */
+ static NMDATETIMEFORMATQUERYW nmdtfq;
+ static NMDATETIMEWMKEYDOWNW nmdtkd;
+ static NMDATETIMESTRINGW nmdts;
/* Tool Bar */
static NMTBRESTORE nmtbr;
static NMTBSAVE nmtbs;
@@ -955,6 +1044,13 @@ static void test_wm_notify(void)
CBEN_DELETEITEM, CBEN_DELETEITEM, DONT_CONVERT_SEND | DONT_CONVERT_RECEIVE},
{&nmcbe, sizeof(nmcbe), &nmcbe.ceItem.mask, CBEIF_TEXT, &nmcbe.ceItem.pszText, &nmcbe.ceItem.cchTextMax,
CBEN_GETDISPINFOW, CBEN_GETDISPINFOA, ZERO_SEND | SET_NULL_IF_NO_MASK | DONT_CONVERT_SEND | CONVERT_RECEIVE},
+ /* Date and Time Picker */
+ {&nmdtfq, sizeof(nmdtfq), NULL, 0, (WCHAR **)&nmdtfq.pszFormat, NULL, DTN_FORMATQUERYW, DTN_FORMATQUERYA,
+ CONVERT_SEND},
+ {&nmdtkd, sizeof(nmdtkd), NULL, 0, (WCHAR **)&nmdtkd.pszFormat, NULL, DTN_WMKEYDOWNW, DTN_WMKEYDOWNA,
+ CONVERT_SEND},
+ {&nmdts, sizeof(nmdts), NULL, 0, (WCHAR **)&nmdts.pszUserString, NULL, DTN_USERSTRINGW, DTN_USERSTRINGA,
+ CONVERT_SEND},
/* Tool Bar */
{&nmtbs, sizeof(nmtbs), NULL, 0, (WCHAR **)&nmtbs.tbButton.iString, NULL, TBN_SAVE, TBN_SAVE,
DONT_CONVERT_SEND | DONT_CONVERT_RECEIVE},
@@ -984,6 +1080,7 @@ static void test_wm_notify(void)
/* Tests for those that can't be covered by generic text test helper */
test_wm_notify_comboboxex(pager);
+ test_wm_notify_datetime(pager);
test_wm_notify_tooltip(pager);
DestroyWindow(parent);
--
2.18.0
Sept. 24, 2018
[PATCH 3/3] d2d1: Implement GetDevice() for device context.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/d2d1/bitmap.c | 10 ++---
dlls/d2d1/bitmap_render_target.c | 4 +-
dlls/d2d1/brush.c | 2 +-
dlls/d2d1/d2d1_private.h | 17 ++++----
dlls/d2d1/dc_render_target.c | 28 +++++++++---
dlls/d2d1/device.c | 74 ++++++++++++++++++--------------
dlls/d2d1/factory.c | 28 ++++++++++--
dlls/d2d1/hwnd_render_target.c | 33 +++++++++++---
dlls/d2d1/tests/d2d1.c | 8 ++--
dlls/d2d1/wic_render_target.c | 33 +++++++++++---
10 files changed, 161 insertions(+), 76 deletions(-)
diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c
index 01dc829a1c..c8d099c7df 100644
--- a/dlls/d2d1/bitmap.c
+++ b/dlls/d2d1/bitmap.c
@@ -330,14 +330,14 @@ HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size,
resource_data.pSysMem = src_data;
resource_data.SysMemPitch = pitch;
- if (FAILED(hr = ID3D10Device_CreateTexture2D(context->device, &texture_desc,
+ if (FAILED(hr = ID3D10Device_CreateTexture2D(context->d3d_device, &texture_desc,
src_data ? &resource_data : NULL, &texture)))
{
ERR("Failed to create texture, hr %#x.\n", hr);
return hr;
}
- hr = ID3D10Device_CreateShaderResourceView(context->device, (ID3D10Resource *)texture, NULL, &view);
+ hr = ID3D10Device_CreateShaderResourceView(context->d3d_device, (ID3D10Resource *)texture, NULL, &view);
ID3D10Texture2D_Release(texture);
if (FAILED(hr))
{
@@ -375,7 +375,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
ID3D10ShaderResourceView_GetDevice(src_impl->view, &device);
ID3D10Device_Release(device);
- if (device != context->device)
+ if (device != context->d3d_device)
{
hr = D2DERR_UNSUPPORTED_OPERATION;
goto failed;
@@ -430,13 +430,13 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
ID3D10Resource_GetDevice(resource, &device);
ID3D10Device_Release(device);
- if (device != context->device)
+ if (device != context->d3d_device)
{
ID3D10Resource_Release(resource);
return D2DERR_UNSUPPORTED_OPERATION;
}
- hr = ID3D10Device_CreateShaderResourceView(context->device, resource, NULL, &view);
+ hr = ID3D10Device_CreateShaderResourceView(context->d3d_device, resource, NULL, &view);
ID3D10Resource_Release(resource);
if (FAILED(hr))
{
diff --git a/dlls/d2d1/bitmap_render_target.c b/dlls/d2d1/bitmap_render_target.c
index 6cea50972f..7411d48892 100644
--- a/dlls/d2d1/bitmap_render_target.c
+++ b/dlls/d2d1/bitmap_render_target.c
@@ -795,7 +795,7 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta
texture_desc.CPUAccessFlags = 0;
texture_desc.MiscFlags = 0;
- if (FAILED(hr = ID3D10Device_CreateTexture2D(parent_target->device, &texture_desc, NULL, &texture)))
+ if (FAILED(hr = ID3D10Device_CreateTexture2D(parent_target->d3d_device, &texture_desc, NULL, &texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
@@ -809,7 +809,7 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta
return hr;
}
- if (FAILED(hr = d2d_d3d_create_render_target(parent_target->factory, dxgi_surface,
+ if (FAILED(hr = d2d_d3d_create_render_target(parent_target->device, dxgi_surface,
(IUnknown *)&render_target->ID2D1BitmapRenderTarget_iface,
parent_target->ops ? &d2d_bitmap_render_target_ops : NULL,
&dxgi_rt_desc, (void **)&render_target->dxgi_inner)))
diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c
index b03af89211..30a4235cda 100644
--- a/dlls/d2d1/brush.c
+++ b/dlls/d2d1/brush.c
@@ -1288,7 +1288,7 @@ HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_b
buffer_data.SysMemPitch = 0;
buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, ps_cb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, ps_cb)))
ERR("Failed to create constant buffer, hr %#x.\n", hr);
return hr;
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index d7989f93a2..2d3acd5997 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -134,7 +134,8 @@ struct d2d_device_context
const struct d2d_device_context_ops *ops;
ID2D1Factory *factory;
- ID3D10Device *device;
+ ID2D1Device *device;
+ ID3D10Device *d3d_device;
ID3D10RenderTargetView *view;
ID3D10StateBlock *stateblock;
struct d2d_shape_resources shape_resources[D2D_SHAPE_TYPE_COUNT];
@@ -155,7 +156,7 @@ struct d2d_device_context
struct d2d_clip_stack clip_stack;
};
-HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, 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,
void **render_target) DECLSPEC_HIDDEN;
HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN;
@@ -181,8 +182,8 @@ struct d2d_wic_render_target
unsigned int bpp;
};
-HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, ID2D1Factory *factory,
- ID3D10Device1 *device, IWICBitmap *bitmap, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN;
+HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, ID2D1Factory1 *factory,
+ ID3D10Device1 *d3d_device, IWICBitmap *bitmap, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN;
struct d2d_dc_render_target
{
@@ -197,8 +198,8 @@ struct d2d_dc_render_target
HDC hdc;
};
-HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory *factory,
- ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN;
+HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory1 *factory,
+ ID3D10Device1 *d3d_device, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN;
struct d2d_hwnd_render_target
{
@@ -212,8 +213,8 @@ struct d2d_hwnd_render_target
HWND hwnd;
};
-HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target, ID2D1Factory *factory,
- ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc,
+HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target, ID2D1Factory1 *factory,
+ ID3D10Device1 *d3d_device, const D2D1_RENDER_TARGET_PROPERTIES *desc,
const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_desc) DECLSPEC_HIDDEN;
struct d2d_bitmap_render_target
diff --git a/dlls/d2d1/dc_render_target.c b/dlls/d2d1/dc_render_target.c
index 8e43bcc307..050adf6dd6 100644
--- a/dlls/d2d1/dc_render_target.c
+++ b/dlls/d2d1/dc_render_target.c
@@ -813,11 +813,13 @@ static const struct d2d_device_context_ops d2d_dc_render_target_ops =
d2d_dc_render_target_present,
};
-HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory *factory,
- ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc)
+HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory1 *factory,
+ ID3D10Device1 *d3d_device, const D2D1_RENDER_TARGET_PROPERTIES *desc)
{
D3D10_TEXTURE2D_DESC texture_desc;
ID3D10Texture2D *texture;
+ IDXGIDevice *dxgi_device;
+ ID2D1Device *device;
HRESULT hr;
render_target->ID2D1DCRenderTarget_iface.lpVtbl = &d2d_dc_render_target_vtbl;
@@ -852,7 +854,7 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID
texture_desc.CPUAccessFlags = 0;
texture_desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
- if (FAILED(hr = ID3D10Device1_CreateTexture2D(device, &texture_desc, NULL, &texture)))
+ if (FAILED(hr = ID3D10Device1_CreateTexture2D(d3d_device, &texture_desc, NULL, &texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
@@ -866,9 +868,25 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID
return hr;
}
- if (FAILED(hr = d2d_d3d_create_render_target(factory, (IDXGISurface *)render_target->dxgi_surface,
+ if (FAILED(hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device)))
+ {
+ WARN("Failed to get DXGI device interface, hr %#x.\n", hr);
+ return hr;
+ }
+
+ hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, &device);
+ IDXGIDevice_Release(dxgi_device);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create D2D device, hr %#x.\n", hr);
+ return hr;
+ }
+
+ hr = d2d_d3d_create_render_target(device, (IDXGISurface *)render_target->dxgi_surface,
(IUnknown *)&render_target->ID2D1DCRenderTarget_iface, &d2d_dc_render_target_ops,
- desc, (void **)&render_target->dxgi_inner)))
+ desc, (void **)&render_target->dxgi_inner);
+ ID2D1Device_Release(device);
+ if (FAILED(hr))
{
WARN("Failed to create DXGI surface render target, hr %#x.\n", hr);
IDXGISurface1_Release(render_target->dxgi_surface);
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c
index f1d0dad45e..be8b7eab03 100644
--- a/dlls/d2d1/device.c
+++ b/dlls/d2d1/device.c
@@ -123,7 +123,7 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en
ID3D10Buffer *vs_cb, ID3D10Buffer *ps_cb, struct d2d_brush *brush, struct d2d_brush *opacity_brush)
{
struct d2d_shape_resources *shape_resources = &render_target->shape_resources[shape_type];
- ID3D10Device *device = render_target->device;
+ ID3D10Device *device = render_target->d3d_device;
D3D10_RECT scissor_rect;
unsigned int offset;
D3D10_VIEWPORT vp;
@@ -273,8 +273,9 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface)
}
context->stateblock->lpVtbl->Release(context->stateblock);
ID3D10RenderTargetView_Release(context->view);
- ID3D10Device_Release(context->device);
+ ID3D10Device_Release(context->d3d_device);
ID2D1Factory_Release(context->factory);
+ ID2D1Device_Release(context->device);
heap_free(context);
}
@@ -441,7 +442,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateGradientStopCollection
TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n",
iface, stops, stop_count, gamma, extend_mode, gradient);
- if (SUCCEEDED(hr = d2d_gradient_create(render_target->factory, render_target->device,
+ if (SUCCEEDED(hr = d2d_gradient_create(render_target->factory, render_target->d3d_device,
stops, stop_count, gamma, extend_mode, &object)))
*gradient = &object->ID2D1GradientStopCollection_iface;
@@ -746,7 +747,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
buffer_data.SysMemPitch = 0;
buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vs_cb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vs_cb)))
{
WARN("Failed to create constant buffer, hr %#x.\n", hr);
return;
@@ -765,7 +766,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
buffer_data.pSysMem = geometry->outline.faces;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &ib)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib)))
{
WARN("Failed to create index buffer, hr %#x.\n", hr);
goto done;
@@ -775,7 +776,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
buffer_data.pSysMem = geometry->outline.vertices;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
{
ERR("Failed to create vertex buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(ib);
@@ -795,7 +796,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
buffer_data.pSysMem = geometry->outline.bezier_faces;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &ib)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib)))
{
WARN("Failed to create beziers index buffer, hr %#x.\n", hr);
goto done;
@@ -805,7 +806,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
buffer_data.pSysMem = geometry->outline.beziers;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
{
ERR("Failed to create beziers vertex buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(ib);
@@ -894,7 +895,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t
buffer_data.SysMemPitch = 0;
buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vs_cb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vs_cb)))
{
WARN("Failed to create constant buffer, hr %#x.\n", hr);
return;
@@ -913,7 +914,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
buffer_data.pSysMem = geometry->fill.faces;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &ib)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib)))
{
WARN("Failed to create index buffer, hr %#x.\n", hr);
goto done;
@@ -923,7 +924,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
buffer_data.pSysMem = geometry->fill.vertices;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
{
ERR("Failed to create vertex buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(ib);
@@ -942,7 +943,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t
buffer_desc.ByteWidth = geometry->fill.bezier_vertex_count * sizeof(*geometry->fill.bezier_vertices);
buffer_data.pSysMem = geometry->fill.bezier_vertices;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
{
ERR("Failed to create beziers vertex buffer, hr %#x.\n", hr);
goto done;
@@ -1634,7 +1635,7 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface
buffer_data.SysMemPitch = 0;
buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vs_cb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vs_cb)))
{
WARN("Failed to create constant buffer, hr %#x.\n", hr);
return;
@@ -1657,7 +1658,7 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface
buffer_desc.ByteWidth = sizeof(ps_cb_data);
buffer_data.pSysMem = &ps_cb_data;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &ps_cb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ps_cb)))
{
WARN("Failed to create constant buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(vs_cb);
@@ -1952,7 +1953,12 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_GetGlyphRunWorldBounds(ID2D1
static void STDMETHODCALLTYPE d2d_device_context_GetDevice(ID2D1DeviceContext *iface, ID2D1Device **device)
{
- FIXME("iface %p, device %p stub!\n", iface, device);
+ struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = context->device;
+ ID2D1Device_AddRef(*device);
}
static void STDMETHODCALLTYPE d2d_device_context_SetTarget(ID2D1DeviceContext *iface, ID2D1Image *target)
@@ -2574,7 +2580,7 @@ static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_targe
d2d_gdi_interop_render_target_ReleaseDC,
};
-static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, ID2D1Factory *factory,
+static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, ID2D1Device *device,
IDXGISurface *surface, IUnknown *outer_unknown, const struct d2d_device_context_ops *ops,
const D2D1_RENDER_TARGET_PROPERTIES *desc)
{
@@ -3460,13 +3466,14 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
render_target->IDWriteTextRenderer_iface.lpVtbl = &d2d_text_renderer_vtbl;
render_target->IUnknown_iface.lpVtbl = &d2d_device_context_inner_unknown_vtbl;
render_target->refcount = 1;
- render_target->factory = factory;
- ID2D1Factory_AddRef(render_target->factory);
+ ID2D1Device_GetFactory(device, &render_target->factory);
+ render_target->device = device;
+ ID2D1Device_AddRef(render_target->device);
render_target->outer_unknown = outer_unknown ? outer_unknown : &render_target->IUnknown_iface;
render_target->ops = ops;
- if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->device)))
+ if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->d3d_device)))
{
WARN("Failed to get device interface, hr %#x.\n", hr);
ID2D1Factory_Release(render_target->factory);
@@ -3479,7 +3486,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
goto err;
}
- hr = ID3D10Device_CreateRenderTargetView(render_target->device, resource, NULL, &render_target->view);
+ hr = ID3D10Device_CreateRenderTargetView(render_target->d3d_device, resource, NULL, &render_target->view);
ID3D10Resource_Release(resource);
if (FAILED(hr))
{
@@ -3493,7 +3500,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
goto err;
}
- if (FAILED(hr = D3D10CreateStateBlock(render_target->device, &state_mask, &render_target->stateblock)))
+ if (FAILED(hr = D3D10CreateStateBlock(render_target->d3d_device, &state_mask, &render_target->stateblock)))
{
WARN("Failed to create stateblock, hr %#x.\n", hr);
goto err;
@@ -3503,14 +3510,14 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
{
const struct shape_info *si = &shape_info[i];
- if (FAILED(hr = ID3D10Device_CreateInputLayout(render_target->device, si->il_desc, si->il_element_count,
+ if (FAILED(hr = ID3D10Device_CreateInputLayout(render_target->d3d_device, si->il_desc, si->il_element_count,
si->vs_code, si->vs_code_size, &render_target->shape_resources[si->shape_type].il)))
{
WARN("Failed to create input layout for shape type %#x, hr %#x.\n", si->shape_type, hr);
goto err;
}
- if (FAILED(hr = ID3D10Device_CreateVertexShader(render_target->device, si->vs_code,
+ if (FAILED(hr = ID3D10Device_CreateVertexShader(render_target->d3d_device, si->vs_code,
si->vs_code_size, &render_target->shape_resources[si->shape_type].vs)))
{
WARN("Failed to create vertex shader for shape type %#x, hr %#x.\n", si->shape_type, hr);
@@ -3519,7 +3526,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
}
- if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->device,
+ if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->d3d_device,
ps_code, sizeof(ps_code), &render_target->ps)))
{
WARN("Failed to create pixel shader, hr %#x.\n", hr);
@@ -3536,7 +3543,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
buffer_data.SysMemPitch = 0;
buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device,
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device,
&buffer_desc, &buffer_data, &render_target->ib)))
{
WARN("Failed to create clear index buffer, hr %#x.\n", hr);
@@ -3548,7 +3555,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
buffer_data.pSysMem = quad;
render_target->vb_stride = sizeof(*quad);
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device,
+ if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device,
&buffer_desc, &buffer_data, &render_target->vb)))
{
WARN("Failed to create clear vertex buffer, hr %#x.\n", hr);
@@ -3565,7 +3572,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
rs_desc.ScissorEnable = TRUE;
rs_desc.MultisampleEnable = FALSE;
rs_desc.AntialiasedLineEnable = FALSE;
- if (FAILED(hr = ID3D10Device_CreateRasterizerState(render_target->device, &rs_desc, &render_target->rs)))
+ if (FAILED(hr = ID3D10Device_CreateRasterizerState(render_target->d3d_device, &rs_desc, &render_target->rs)))
{
WARN("Failed to create clear rasterizer state, hr %#x.\n", hr);
goto err;
@@ -3588,7 +3595,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
}
blend_desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
blend_desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
- if (FAILED(hr = ID3D10Device_CreateBlendState(render_target->device, &blend_desc, &render_target->bs)))
+ if (FAILED(hr = ID3D10Device_CreateBlendState(render_target->d3d_device, &blend_desc, &render_target->bs)))
{
WARN("Failed to create blend state, hr %#x.\n", hr);
goto err;
@@ -3656,13 +3663,14 @@ err:
render_target->stateblock->lpVtbl->Release(render_target->stateblock);
if (render_target->view)
ID3D10RenderTargetView_Release(render_target->view);
- if (render_target->device)
- ID3D10Device_Release(render_target->device);
+ if (render_target->d3d_device)
+ ID3D10Device_Release(render_target->d3d_device);
+ ID2D1Device_Release(render_target->device);
ID2D1Factory_Release(render_target->factory);
return hr;
}
-HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, 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, void **render_target)
{
struct d2d_device_context *object;
@@ -3671,7 +3679,7 @@ HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surfac
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
- if (FAILED(hr = d2d_device_context_init(object, factory, surface, outer_unknown, ops, desc)))
+ if (FAILED(hr = d2d_device_context_init(object, device, surface, outer_unknown, ops, desc)))
{
WARN("Failed to initialize render target, hr %#x.\n", hr);
heap_free(object);
@@ -3711,7 +3719,7 @@ HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *iface, IDXGISurface1
return hr;
}
- hr = ID3D10Device_CreateRenderTargetView(render_target->device, resource, NULL, &view);
+ hr = ID3D10Device_CreateRenderTargetView(render_target->d3d_device, resource, NULL, &view);
ID3D10Resource_Release(resource);
if (FAILED(hr))
{
diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c
index 5ce21f6f15..29038ec91e 100644
--- a/dlls/d2d1/factory.c
+++ b/dlls/d2d1/factory.c
@@ -300,7 +300,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateWicBitmapRenderTarget(ID2D1Fa
return hr;
}
- if (FAILED(hr = d2d_wic_render_target_init(object, (ID2D1Factory *)iface, device, target, desc)))
+ if (FAILED(hr = d2d_wic_render_target_init(object, iface, device, target, desc)))
{
WARN("Failed to initialize render target, hr %#x.\n", hr);
heap_free(object);
@@ -330,7 +330,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
- if (FAILED(hr = d2d_hwnd_render_target_init(object, (ID2D1Factory *)iface, device, desc, hwnd_rt_desc)))
+ if (FAILED(hr = d2d_hwnd_render_target_init(object, iface, device, desc, hwnd_rt_desc)))
{
WARN("Failed to initialize render target, hr %#x.\n", hr);
heap_free(object);
@@ -346,9 +346,29 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory
static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1Factory1 *iface,
IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target)
{
+ IDXGIDevice *dxgi_device;
+ ID2D1Device *device;
+ HRESULT hr;
+
TRACE("iface %p, surface %p, desc %p, render_target %p.\n", iface, surface, desc, render_target);
- return d2d_d3d_create_render_target((ID2D1Factory *)iface, surface, NULL, NULL, desc, (void **)render_target);
+ if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_IDXGIDevice, (void **)&dxgi_device)))
+ {
+ WARN("Failed to get DXGI device, hr %#x.\n", hr);
+ return hr;
+ }
+
+ hr = ID2D1Factory1_CreateDevice(iface, dxgi_device, &device);
+ IDXGIDevice_Release(dxgi_device);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create D2D device, hr %#x.\n", hr);
+ return hr;
+ }
+
+ hr = d2d_d3d_create_render_target(device, surface, NULL, NULL, desc, (void **)render_target);
+ ID2D1Device_Release(device);
+ return hr;
}
static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory1 *iface,
@@ -367,7 +387,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory1
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
- if (FAILED(hr = d2d_dc_render_target_init(object, (ID2D1Factory *)iface, device, desc)))
+ if (FAILED(hr = d2d_dc_render_target_init(object, iface, device, desc)))
{
WARN("Failed to initialize render target, hr %#x.\n", hr);
heap_free(object);
diff --git a/dlls/d2d1/hwnd_render_target.c b/dlls/d2d1/hwnd_render_target.c
index 1e76326119..2c9481e576 100644
--- a/dlls/d2d1/hwnd_render_target.c
+++ b/dlls/d2d1/hwnd_render_target.c
@@ -776,8 +776,8 @@ static const struct d2d_device_context_ops d2d_hwnd_render_target_ops =
d2d_hwnd_render_target_present,
};
-HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target, ID2D1Factory *factory,
- ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc,
+HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target, ID2D1Factory1 *factory,
+ ID3D10Device1 *d3d_device, const D2D1_RENDER_TARGET_PROPERTIES *desc,
const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_rt_desc)
{
D2D1_RENDER_TARGET_PROPERTIES dxgi_rt_desc;
@@ -786,6 +786,7 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target
IDXGIFactory *dxgi_factory;
IDXGISurface *dxgi_surface;
IDXGIDevice *dxgi_device;
+ ID2D1Device *device;
HRESULT hr;
if (!IsWindow(hwnd_rt_desc->hwnd))
@@ -795,7 +796,7 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target
render_target->hwnd = hwnd_rt_desc->hwnd;
render_target->sync_interval = hwnd_rt_desc->presentOptions & D2D1_PRESENT_OPTIONS_IMMEDIATELY ? 0 : 1;
- if (FAILED(hr = ID3D10Device1_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device)))
+ if (FAILED(hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device)))
{
WARN("Failed to get IDXGIDevice interface, hr %#x.\n", hr);
return hr;
@@ -819,7 +820,7 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target
dxgi_rt_desc = *desc;
if (dxgi_rt_desc.dpiX == 0.0f && dxgi_rt_desc.dpiY == 0.0f)
- ID2D1Factory_GetDesktopDpi(factory, &dxgi_rt_desc.dpiX, &dxgi_rt_desc.dpiY);
+ ID2D1Factory1_GetDesktopDpi(factory, &dxgi_rt_desc.dpiX, &dxgi_rt_desc.dpiY);
if (dxgi_rt_desc.pixelFormat.format == DXGI_FORMAT_UNKNOWN)
{
@@ -844,7 +845,7 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target
DXGI_SWAP_EFFECT_SEQUENTIAL : DXGI_SWAP_EFFECT_DISCARD;
swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;
- hr = IDXGIFactory_CreateSwapChain(dxgi_factory, (IUnknown *)device, &swapchain_desc, &render_target->swapchain);
+ hr = IDXGIFactory_CreateSwapChain(dxgi_factory, (IUnknown *)d3d_device, &swapchain_desc, &render_target->swapchain);
IDXGIFactory_Release(dxgi_factory);
if (FAILED(hr))
{
@@ -860,10 +861,30 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target
}
render_target->ID2D1HwndRenderTarget_iface.lpVtbl = &d2d_hwnd_render_target_vtbl;
- hr = d2d_d3d_create_render_target(factory, dxgi_surface,
+
+ if (FAILED(hr = IDXGISurface_GetDevice(dxgi_surface, &IID_IDXGIDevice, (void **)&dxgi_device)))
+ {
+ WARN("Failed to get DXGI device, hr %#X.\n", hr);
+ IDXGISurface_Release(dxgi_surface);
+ IDXGISwapChain_Release(render_target->swapchain);
+ return hr;
+ }
+
+ hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, &device);
+ IDXGIDevice_Release(dxgi_device);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create D2D device, hr %#X.\n", hr);
+ IDXGISurface_Release(dxgi_surface);
+ IDXGISwapChain_Release(render_target->swapchain);
+ return hr;
+ }
+
+ hr = d2d_d3d_create_render_target(device, dxgi_surface,
(IUnknown *)&render_target->ID2D1HwndRenderTarget_iface, &d2d_hwnd_render_target_ops,
&dxgi_rt_desc, (void **)&render_target->dxgi_inner);
IDXGISurface_Release(dxgi_surface);
+ ID2D1Device_Release(device);
if (FAILED(hr))
{
WARN("Failed to create DXGI surface render target, hr %#x.\n", hr);
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 65ab5c258b..eaa0b64a3d 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -6772,7 +6772,7 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B
/* Pixel format is not defined until target is set, for DC target it's specified on creation. */
if (target || dc_rt)
{
- ID2D1Device *device = NULL, *device2 = NULL;
+ ID2D1Device *device, *device2;
ID2D1DeviceContext *context2;
ID2D1DeviceContext_GetDevice(context, &device);
@@ -6787,10 +6787,8 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B
ID2D1DeviceContext_GetDevice(context2, &device2);
ok_(__FILE__, line)(device == device2, "Unexpected device.\n");
- if (device)
- ID2D1Device_Release(device);
- if (device2)
- ID2D1Device_Release(device2);
+ ID2D1Device_Release(device);
+ ID2D1Device_Release(device2);
ID2D1DeviceContext_Release(context2);
diff --git a/dlls/d2d1/wic_render_target.c b/dlls/d2d1/wic_render_target.c
index 27236e2963..21a1fa170e 100644
--- a/dlls/d2d1/wic_render_target.c
+++ b/dlls/d2d1/wic_render_target.c
@@ -152,11 +152,13 @@ static const struct d2d_device_context_ops d2d_wic_render_target_ops =
d2d_wic_render_target_present,
};
-HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, ID2D1Factory *factory,
- ID3D10Device1 *device, IWICBitmap *bitmap, const D2D1_RENDER_TARGET_PROPERTIES *desc)
+HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, ID2D1Factory1 *factory,
+ ID3D10Device1 *d3d_device, IWICBitmap *bitmap, const D2D1_RENDER_TARGET_PROPERTIES *desc)
{
D3D10_TEXTURE2D_DESC texture_desc;
ID3D10Texture2D *texture;
+ IDXGIDevice *dxgi_device;
+ ID2D1Device *device;
HRESULT hr;
render_target->IUnknown_iface.lpVtbl = &d2d_wic_render_target_vtbl;
@@ -214,7 +216,7 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target,
texture_desc.MiscFlags = desc->usage & D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE ?
D3D10_RESOURCE_MISC_GDI_COMPATIBLE : 0;
- if (FAILED(hr = ID3D10Device1_CreateTexture2D(device, &texture_desc, NULL, &texture)))
+ if (FAILED(hr = ID3D10Device1_CreateTexture2D(d3d_device, &texture_desc, NULL, &texture)))
{
WARN("Failed to create texture, hr %#x.\n", hr);
return hr;
@@ -233,16 +235,33 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target,
texture_desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
texture_desc.MiscFlags = 0;
- if (FAILED(hr = ID3D10Device1_CreateTexture2D(device, &texture_desc, NULL, &render_target->readback_texture)))
+ if (FAILED(hr = ID3D10Device1_CreateTexture2D(d3d_device, &texture_desc, NULL, &render_target->readback_texture)))
{
WARN("Failed to create readback texture, hr %#x.\n", hr);
IDXGISurface_Release(render_target->dxgi_surface);
return hr;
}
- if (FAILED(hr = d2d_d3d_create_render_target(factory, render_target->dxgi_surface,
- &render_target->IUnknown_iface, &d2d_wic_render_target_ops,
- desc, (void **)&render_target->dxgi_inner)))
+ if (FAILED(hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device)))
+ {
+ WARN("Failed to get DXGI device, hr %#x.\n", hr);
+ IDXGISurface_Release(render_target->dxgi_surface);
+ return hr;
+ }
+
+ hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, &device);
+ IDXGIDevice_Release(dxgi_device);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create D2D device, hr %#x.\n", hr);
+ IDXGISurface_Release(render_target->dxgi_surface);
+ return hr;
+ }
+
+ hr = d2d_d3d_create_render_target(device, render_target->dxgi_surface, &render_target->IUnknown_iface,
+ &d2d_wic_render_target_ops, desc, (void **)&render_target->dxgi_inner);
+ ID2D1Device_Release(device);
+ if (FAILED(hr))
{
WARN("Failed to create DXGI surface render target, hr %#x.\n", hr);
ID3D10Texture2D_Release(render_target->readback_texture);
--
2.19.0
Sept. 24, 2018
[PATCH 2/3] d2d1/tests: Test that device is reused for compatible targets.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/d2d1/tests/d2d1.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 9e6ce06543..65ab5c258b 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -6772,14 +6772,26 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B
/* Pixel format is not defined until target is set, for DC target it's specified on creation. */
if (target || dc_rt)
{
+ ID2D1Device *device = NULL, *device2 = NULL;
ID2D1DeviceContext *context2;
+ ID2D1DeviceContext_GetDevice(context, &device);
+
hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, NULL, NULL,
D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, (ID2D1BitmapRenderTarget **)&compatible_rt);
ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create compatible render target, hr %#x.\n", hr);
hr = ID2D1RenderTarget_QueryInterface(compatible_rt, &IID_ID2D1DeviceContext, (void **)&context2);
ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
+
+ ID2D1DeviceContext_GetDevice(context2, &device2);
+ ok_(__FILE__, line)(device == device2, "Unexpected device.\n");
+
+ if (device)
+ ID2D1Device_Release(device);
+ if (device2)
+ ID2D1Device_Release(device2);
+
ID2D1DeviceContext_Release(context2);
hr = ID2D1RenderTarget_CreateBitmap(compatible_rt, size, bitmap_data, sizeof(*bitmap_data), &bitmap_desc, &bitmap);
--
2.19.0
Sept. 24, 2018
[PATCH 1/3] d2d1: Fix compatible target initialization.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/d2d1/bitmap_render_target.c | 8 +++-
dlls/d2d1/device.c | 4 +-
dlls/d2d1/tests/d2d1.c | 67 ++++++++++++++++++++++++++++++--
3 files changed, 73 insertions(+), 6 deletions(-)
diff --git a/dlls/d2d1/bitmap_render_target.c b/dlls/d2d1/bitmap_render_target.c
index 57f5b23b51..6cea50972f 100644
--- a/dlls/d2d1/bitmap_render_target.c
+++ b/dlls/d2d1/bitmap_render_target.c
@@ -722,6 +722,11 @@ static const struct ID2D1BitmapRenderTargetVtbl d2d_bitmap_render_target_vtbl =
d2d_bitmap_render_target_GetBitmap
};
+static const struct d2d_device_context_ops d2d_bitmap_render_target_ops =
+{
+ NULL,
+};
+
HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_target,
const struct d2d_device_context *parent_target, const D2D1_SIZE_F *size,
const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *pixel_format,
@@ -805,7 +810,8 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta
}
if (FAILED(hr = d2d_d3d_create_render_target(parent_target->factory, dxgi_surface,
- (IUnknown *)&render_target->ID2D1BitmapRenderTarget_iface, NULL,
+ (IUnknown *)&render_target->ID2D1BitmapRenderTarget_iface,
+ parent_target->ops ? &d2d_bitmap_render_target_ops : NULL,
&dxgi_rt_desc, (void **)&render_target->dxgi_inner)))
{
WARN("Failed to create DXGI surface render target, hr %#x.\n", hr);
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c
index d20377b5c2..f1d0dad45e 100644
--- a/dlls/d2d1/device.c
+++ b/dlls/d2d1/device.c
@@ -1515,7 +1515,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_Flush(ID2D1DeviceContext *if
FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2);
- if (context->ops)
+ if (context->ops && context->ops->device_context_present)
context->ops->device_context_present(context->outer_unknown);
return E_NOTIMPL;
@@ -1693,7 +1693,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_EndDraw(ID2D1DeviceContext *
if (tag2)
*tag2 = context->error.tag2;
- if (context->ops)
+ if (context->ops && context->ops->device_context_present)
{
if (FAILED(hr = context->ops->device_context_present(context->outer_unknown)))
context->error.code = hr;
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 4136b69885..9e6ce06543 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -6705,8 +6705,10 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B
ID2D1RenderTarget *compatible_rt;
IWICImagingFactory *wic_factory;
ID2D1DeviceContext *context;
+ ID2D1DCRenderTarget *dc_rt;
IWICBitmap *wic_bitmap;
ID2D1Bitmap *bitmap;
+ ID2D1Image *target;
D2D1_SIZE_U size;
HRESULT hr;
@@ -6749,13 +6751,37 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B
CoUninitialize();
- if (FAILED(ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&context)))
+ /* Compatible target follows its parent. */
+ hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&context);
+ ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
+
+ dc_rt = NULL;
+ ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DCRenderTarget, (void **)&dc_rt);
+
+ bitmap = NULL;
+ target = NULL;
+ ID2D1DeviceContext_GetTarget(context, &target);
+ if (target && FAILED(ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap, (void **)&bitmap)))
+ {
+ ID2D1Image_Release(target);
+ target = NULL;
+ }
+ if (bitmap)
+ ID2D1Bitmap_Release(bitmap);
+
+ /* Pixel format is not defined until target is set, for DC target it's specified on creation. */
+ if (target || dc_rt)
{
- /* Compatible target follows its parent. */
+ ID2D1DeviceContext *context2;
+
hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, NULL, NULL,
D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, (ID2D1BitmapRenderTarget **)&compatible_rt);
ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create compatible render target, hr %#x.\n", hr);
+ hr = ID2D1RenderTarget_QueryInterface(compatible_rt, &IID_ID2D1DeviceContext, (void **)&context2);
+ ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
+ ID2D1DeviceContext_Release(context2);
+
hr = ID2D1RenderTarget_CreateBitmap(compatible_rt, size, bitmap_data, sizeof(*bitmap_data), &bitmap_desc, &bitmap);
ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
@@ -6765,7 +6791,18 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B
ID2D1Bitmap_Release(bitmap);
}
else
- ID2D1DeviceContext_Release(context);
+ {
+ hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, NULL, NULL,
+ D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, (ID2D1BitmapRenderTarget **)&compatible_rt);
+ todo_wine
+ ok_(__FILE__, line)(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT, " --- Unexpected hr %#x.\n", hr);
+ }
+
+ ID2D1DeviceContext_Release(context);
+ if (target)
+ ID2D1Image_Release(target);
+ if (dc_rt)
+ ID2D1DCRenderTarget_Release(dc_rt);
}
static void test_bitmap_surface(void)
@@ -6782,6 +6819,7 @@ static void test_bitmap_surface(void)
IDXGISurface *surface;
ID2D1Bitmap1 *bitmap;
ID2D1Device *device;
+ ID2D1Image *target;
HWND window;
HRESULT hr;
@@ -6809,7 +6847,23 @@ static void test_bitmap_surface(void)
rt = create_render_target(surface);
ok(!!rt, "Failed to create render target.\n");
+ hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
+ ok(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
+
+ bitmap = NULL;
+ ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
+todo_wine
+ ok(!!bitmap, "Unexpected target.\n");
+
+if (bitmap)
+{
+ check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
+ ID2D1Bitmap1_Release(bitmap);
+}
check_rt_bitmap_surface(rt, TRUE, D2D1_BITMAP_OPTIONS_NONE);
+
+ ID2D1DeviceContext_Release(device_context);
+
ID2D1RenderTarget_Release(rt);
/* Bitmap created from DXGI surface. */
@@ -6836,7 +6890,14 @@ if (SUCCEEDED(hr))
check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE);
+ ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
+ ID2D1DeviceContext_GetTarget(device_context, &target);
+ ok(target == (ID2D1Image *)bitmap, "Unexpected target.\n");
+
+ check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE);
+
ID2D1DeviceContext_Release(device_context);
+ ID2D1Bitmap1_Release(bitmap);
}
ID2D1Device_Release(device);
IDXGIDevice_Release(dxgi_device);
--
2.19.0
Sept. 24, 2018
[PATCH 6/6] dxgi: Get rid of set_feature_level() from dxgi_device_layer.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/d3d11/d3d11_main.c | 18 +-----------------
dlls/d3d11/d3d11_private.h | 2 --
dlls/d3d11/device.c | 2 ++
dlls/dxgi/device.c | 12 ------------
dlls/dxgi/dxgi_private.h | 2 --
dlls/dxgi/utils.c | 3 ---
6 files changed, 3 insertions(+), 36 deletions(-)
diff --git a/dlls/d3d11/d3d11_main.c b/dlls/d3d11/d3d11_main.c
index 6d981160f245..9c89820f6f53 100644
--- a/dlls/d3d11/d3d11_main.c
+++ b/dlls/d3d11/d3d11_main.c
@@ -95,27 +95,11 @@ static HRESULT WINAPI layer_create(enum dxgi_device_layer_id id, void **layer_ba
return S_OK;
}
-static void WINAPI layer_set_feature_level(enum dxgi_device_layer_id id, void *device,
- D3D_FEATURE_LEVEL feature_level)
-{
- struct d3d_device *d3d_device = device;
-
- TRACE("id %#x, device %p, feature_level %#x.\n", id, device, feature_level);
-
- if (id != DXGI_DEVICE_LAYER_D3D10_DEVICE)
- {
- WARN("Unknown layer id %#x.\n", id);
- return;
- }
-
- d3d_device->feature_level = feature_level;
-}
-
HRESULT WINAPI D3D11CoreRegisterLayers(void)
{
static const struct dxgi_device_layer layers[] =
{
- {DXGI_DEVICE_LAYER_D3D10_DEVICE, layer_init, layer_get_size, layer_create, layer_set_feature_level},
+ {DXGI_DEVICE_LAYER_D3D10_DEVICE, layer_init, layer_get_size, layer_create},
};
DXGID3D10RegisterLayers(layers, ARRAY_SIZE(layers));
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h
index 6ec413139cf6..3049193ce284 100644
--- a/dlls/d3d11/d3d11_private.h
+++ b/dlls/d3d11/d3d11_private.h
@@ -588,8 +588,6 @@ struct dxgi_device_layer
UINT (WINAPI *get_size)(enum dxgi_device_layer_id id, struct layer_get_size_args *args, DWORD unknown0);
HRESULT (WINAPI *create)(enum dxgi_device_layer_id id, void **layer_base, DWORD unknown0,
void *device_object, REFIID riid, void **device_layer);
- void (WINAPI *set_feature_level)(enum dxgi_device_layer_id id, void *device,
- D3D_FEATURE_LEVEL feature_level);
};
HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, IDXGIAdapter *adapter,
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index e6ba31c7c4b7..1edd41f0d404 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -6004,6 +6004,8 @@ static void CDECL device_parent_wined3d_device_created(struct wined3d_device_par
wined3d_device_incref(wined3d_device);
device->wined3d_device = wined3d_device;
+ device->feature_level = wined3d_device_get_feature_level(wined3d_device);
+
set_default_depth_stencil_state(wined3d_device);
}
diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c
index deb07ca0d821..51773e9c0054 100644
--- a/dlls/dxgi/device.c
+++ b/dlls/dxgi/device.c
@@ -411,7 +411,6 @@ HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *l
IWineDXGIDeviceParent *dxgi_device_parent;
struct dxgi_adapter *dxgi_adapter;
struct dxgi_factory *dxgi_factory;
- D3D_FEATURE_LEVEL feature_level;
void *layer_base;
HRESULT hr;
@@ -455,15 +454,6 @@ HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *l
wined3d_device_parent = IWineDXGIDeviceParent_get_wined3d_device_parent(dxgi_device_parent);
IWineDXGIDeviceParent_Release(dxgi_device_parent);
- if (!(feature_level = dxgi_check_feature_level_support(dxgi_factory, dxgi_adapter,
- feature_levels, level_count)))
- {
- IUnknown_Release(device->child_layer);
- wined3d_private_store_cleanup(&device->private_store);
- wined3d_mutex_unlock();
- return E_FAIL;
- }
-
if (FAILED(hr = wined3d_device_create(dxgi_factory->wined3d,
dxgi_adapter->ordinal, WINED3D_DEVICE_TYPE_HAL, NULL, 0, 4,
(const enum wined3d_feature_level *)feature_levels, level_count,
@@ -476,8 +466,6 @@ HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *l
return hr;
}
- layer->set_feature_level(layer->id, device->child_layer, feature_level);
-
memset(&swapchain_desc, 0, sizeof(swapchain_desc));
swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD;
swapchain_desc.device_window = dxgi_factory_get_device_window(dxgi_factory);
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index 3a59196e1abd..8c3e41a390bb 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -75,8 +75,6 @@ struct dxgi_device_layer
UINT (WINAPI *get_size)(enum dxgi_device_layer_id id, struct layer_get_size_args *args, DWORD unknown0);
HRESULT (WINAPI *create)(enum dxgi_device_layer_id id, void **layer_base, DWORD unknown0,
void *device_object, REFIID riid, void **device_layer);
- void (WINAPI *set_feature_level)(enum dxgi_device_layer_id id, void *device,
- D3D_FEATURE_LEVEL feature_level);
};
/* TRACE helper functions */
diff --git a/dlls/dxgi/utils.c b/dlls/dxgi/utils.c
index 009d351f633f..ad8e2a23f2ae 100644
--- a/dlls/dxgi/utils.c
+++ b/dlls/dxgi/utils.c
@@ -23,7 +23,6 @@
#include "dxgi_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dxgi);
-WINE_DECLARE_DEBUG_CHANNEL(winediag);
#define WINE_DXGI_TO_STR(x) case x: return #x
@@ -674,7 +673,5 @@ D3D_FEATURE_LEVEL dxgi_check_feature_level_support(struct dxgi_factory *factory,
debug_feature_level(feature_levels[i]));
}
- FIXME_(winediag)("None of the requested D3D feature levels is supported on this GPU "
- "with the current shader backend.\n");
return 0;
}
--
2.16.4
Sept. 23, 2018
[PATCH 5/6] wined3d: Introduce wined3d_device_get_feature_level().
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/device.c | 7 +++++++
dlls/wined3d/wined3d.spec | 1 +
include/wine/wined3d.h | 1 +
3 files changed, 9 insertions(+)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 38c37d4c536d..922de369c85a 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5026,6 +5026,13 @@ struct wined3d * CDECL wined3d_device_get_wined3d(const struct wined3d_device *d
return device->wined3d;
}
+enum wined3d_feature_level CDECL wined3d_device_get_feature_level(const struct wined3d_device *device)
+{
+ TRACE("device %p.\n", device);
+
+ return device->feature_level;
+}
+
void CDECL wined3d_device_set_gamma_ramp(const struct wined3d_device *device,
UINT swapchain_idx, DWORD flags, const struct wined3d_gamma_ramp *ramp)
{
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index a401e04dcf3b..7944387bcab9 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -72,6 +72,7 @@
@ cdecl wined3d_device_get_domain_shader(ptr)
@ cdecl wined3d_device_get_ds_resource_view(ptr long)
@ cdecl wined3d_device_get_ds_sampler(ptr long)
+@ cdecl wined3d_device_get_feature_level(ptr)
@ cdecl wined3d_device_get_gamma_ramp(ptr long ptr)
@ cdecl wined3d_device_get_geometry_shader(ptr)
@ cdecl wined3d_device_get_gs_resource_view(ptr long)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 6b81b3ab1df1..ef89caf0633f 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2295,6 +2295,7 @@ struct wined3d_shader * __cdecl wined3d_device_get_domain_shader(const struct wi
struct wined3d_shader_resource_view * __cdecl wined3d_device_get_ds_resource_view(const struct wined3d_device *device,
unsigned int idx);
struct wined3d_sampler * __cdecl wined3d_device_get_ds_sampler(const struct wined3d_device *device, unsigned int idx);
+enum wined3d_feature_level __cdecl wined3d_device_get_feature_level(const struct wined3d_device *device);
void __cdecl wined3d_device_get_gamma_ramp(const struct wined3d_device *device,
UINT swapchain_idx, struct wined3d_gamma_ramp *ramp);
struct wined3d_shader * __cdecl wined3d_device_get_geometry_shader(const struct wined3d_device *device);
--
2.16.4
Sept. 23, 2018
[PATCH 4/6] wined3d: Pass feature levels to wined3d_device_create().
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/d3d8/device.c | 14 +++++++++++---
dlls/d3d9/device.c | 14 +++++++++++++-
dlls/ddraw/ddraw.c | 10 +++++++++-
dlls/dxgi/device.c | 7 ++++---
dlls/dxgi/dxgi_private.h | 1 +
dlls/wined3d/device.c | 31 +++++++++++++++++++++++++++++--
dlls/wined3d/directx.c | 20 +++++++++++---------
dlls/wined3d/utils.c | 22 ++++++++++++++++++++++
dlls/wined3d/wined3d.spec | 2 +-
dlls/wined3d/wined3d_private.h | 6 +++++-
include/wine/wined3d.h | 3 ++-
11 files changed, 108 insertions(+), 22 deletions(-)
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index 364798f79b3a..12d025383514 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -3399,6 +3399,14 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
struct wined3d_swapchain *wined3d_swapchain;
HRESULT hr;
+ static const enum wined3d_feature_level feature_levels[] =
+ {
+ WINED3D_FEATURE_LEVEL_8,
+ WINED3D_FEATURE_LEVEL_7,
+ WINED3D_FEATURE_LEVEL_6,
+ WINED3D_FEATURE_LEVEL_5,
+ };
+
device->IDirect3DDevice8_iface.lpVtbl = &d3d8_device_vtbl;
device->device_parent.ops = &d3d8_wined3d_device_parent_ops;
device->ref = 1;
@@ -3413,9 +3421,9 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
wined3d_mutex_lock();
- hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4,
- &device->device_parent, &device->wined3d_device);
- if (FAILED(hr))
+ if (FAILED(hr = wined3d_device_create(wined3d, adapter, device_type,
+ focus_window, flags, 4, feature_levels, ARRAY_SIZE(feature_levels),
+ &device->device_parent, &device->wined3d_device)))
{
WARN("Failed to create wined3d device, hr %#x.\n", hr);
wined3d_mutex_unlock();
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index a8dc7097c487..a31360886b6a 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -4230,6 +4230,17 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
unsigned i, count = 1;
HRESULT hr;
+ static const enum wined3d_feature_level feature_levels[] =
+ {
+ WINED3D_FEATURE_LEVEL_9_SM3,
+ WINED3D_FEATURE_LEVEL_9_SM2,
+ WINED3D_FEATURE_LEVEL_9_1,
+ WINED3D_FEATURE_LEVEL_8,
+ WINED3D_FEATURE_LEVEL_7,
+ WINED3D_FEATURE_LEVEL_6,
+ WINED3D_FEATURE_LEVEL_5,
+ };
+
if (mode)
FIXME("Ignoring display mode.\n");
@@ -4240,7 +4251,8 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
wined3d_mutex_lock();
- if (FAILED(hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4,
+ if (FAILED(hr = wined3d_device_create(wined3d, adapter, device_type,
+ focus_window, flags, 4, feature_levels, ARRAY_SIZE(feature_levels),
&device->device_parent, &device->wined3d_device)))
{
WARN("Failed to create wined3d device, hr %#x.\n", hr);
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index c83d0ca15689..56a74cb3285f 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -4986,6 +4986,13 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de
struct wined3d_caps caps;
HRESULT hr;
+ static const enum wined3d_feature_level feature_levels[] =
+ {
+ WINED3D_FEATURE_LEVEL_7,
+ WINED3D_FEATURE_LEVEL_6,
+ WINED3D_FEATURE_LEVEL_5,
+ };
+
ddraw->IDirectDraw7_iface.lpVtbl = &ddraw7_vtbl;
ddraw->IDirectDraw_iface.lpVtbl = &ddraw1_vtbl;
ddraw->IDirectDraw2_iface.lpVtbl = &ddraw2_vtbl;
@@ -5023,7 +5030,8 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de
}
if (FAILED(hr = wined3d_device_create(ddraw->wined3d, WINED3DADAPTER_DEFAULT, device_type,
- NULL, 0, DDRAW_STRIDE_ALIGNMENT, &ddraw->device_parent, &ddraw->wined3d_device)))
+ NULL, 0, DDRAW_STRIDE_ALIGNMENT, feature_levels, ARRAY_SIZE(feature_levels),
+ &ddraw->device_parent, &ddraw->wined3d_device)))
{
WARN("Failed to create a wined3d device, hr %#x.\n", hr);
wined3d_decref(ddraw->wined3d);
diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c
index 67cadd5a3f89..deb07ca0d821 100644
--- a/dlls/dxgi/device.c
+++ b/dlls/dxgi/device.c
@@ -464,9 +464,10 @@ HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *l
return E_FAIL;
}
- hr = wined3d_device_create(dxgi_factory->wined3d, dxgi_adapter->ordinal, WINED3D_DEVICE_TYPE_HAL,
- NULL, 0, 4, wined3d_device_parent, &device->wined3d_device);
- if (FAILED(hr))
+ if (FAILED(hr = wined3d_device_create(dxgi_factory->wined3d,
+ dxgi_adapter->ordinal, WINED3D_DEVICE_TYPE_HAL, NULL, 0, 4,
+ (const enum wined3d_feature_level *)feature_levels, level_count,
+ wined3d_device_parent, &device->wined3d_device)))
{
WARN("Failed to create a wined3d device, returning %#x.\n", hr);
IUnknown_Release(device->child_layer);
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index f74514f0d326..3a59196e1abd 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -97,6 +97,7 @@ DXGI_USAGE dxgi_usage_from_wined3d_usage(DWORD wined3d_usage) DECLSPEC_HIDDEN;
DWORD wined3d_usage_from_dxgi_usage(DXGI_USAGE usage) DECLSPEC_HIDDEN;
unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags) DECLSPEC_HIDDEN;
unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags) DECLSPEC_HIDDEN;
+
HRESULT dxgi_get_private_data(struct wined3d_private_store *store,
REFGUID guid, UINT *data_size, void *data) DECLSPEC_HIDDEN;
HRESULT dxgi_set_private_data(struct wined3d_private_store *store,
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 3fc3ae557dc6..38c37d4c536d 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5158,16 +5158,43 @@ static int wined3d_sampler_compare(const void *key, const struct wine_rb_entry *
return memcmp(&sampler->desc, key, sizeof(sampler->desc));
}
+static BOOL wined3d_select_feature_level(const struct wined3d_adapter *adapter,
+ const enum wined3d_feature_level *levels, unsigned int level_count,
+ enum wined3d_feature_level *selected_level)
+{
+ const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
+ unsigned int i;
+
+ for (i = 0; i < level_count; ++i)
+ {
+ if (levels[i] && d3d_info->feature_level >= levels[i])
+ {
+ *selected_level = levels[i];
+ return TRUE;
+ }
+ }
+
+ FIXME_(winediag)("None of the requested D3D feature levels is supported on this GPU "
+ "with the current shader backend.\n");
+ return FALSE;
+}
+
HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags,
- BYTE surface_alignment, struct wined3d_device_parent *device_parent)
+ BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count,
+ struct wined3d_device_parent *device_parent)
{
struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
- const struct fragment_pipeline *fragment_pipeline;
const struct wined3d_vertex_pipe_ops *vertex_pipeline;
+ const struct fragment_pipeline *fragment_pipeline;
unsigned int i;
HRESULT hr;
+ if (!wined3d_select_feature_level(adapter, levels, level_count, &device->feature_level))
+ return E_FAIL;
+
+ TRACE("Device feature level %s.\n", wined3d_debug_feature_level(device->feature_level));
+
device->ref = 1;
device->wined3d = wined3d;
wined3d_incref(device->wined3d);
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 4e8afed0a938..b893e0541946 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2448,16 +2448,18 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
return WINED3D_OK;
}
-HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type,
- HWND focus_window, DWORD flags, BYTE surface_alignment, struct wined3d_device_parent *device_parent,
- struct wined3d_device **device)
+HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, unsigned int adapter_idx,
+ enum wined3d_device_type device_type, HWND focus_window, DWORD flags, BYTE surface_alignment,
+ const enum wined3d_feature_level *feature_levels, unsigned int feature_level_count,
+ struct wined3d_device_parent *device_parent, struct wined3d_device **device)
{
struct wined3d_device *object;
HRESULT hr;
- TRACE("wined3d %p, adapter_idx %u, device_type %#x, focus_window %p, "
- "flags %#x, surface_alignment %u, device_parent %p, device %p.\n",
- wined3d, adapter_idx, device_type, focus_window, flags, surface_alignment, device_parent, device);
+ TRACE("wined3d %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x, "
+ "surface_alignment %u, feature_levels %p, feature_level_count %u, device_parent %p, device %p.\n",
+ wined3d, adapter_idx, device_type, focus_window, flags, surface_alignment,
+ feature_levels, feature_level_count, device_parent, device);
if (adapter_idx >= wined3d->adapter_count)
return WINED3DERR_INVALIDCALL;
@@ -2465,9 +2467,9 @@ HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, e
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
- hr = device_init(object, wined3d, adapter_idx, device_type,
- focus_window, flags, surface_alignment, device_parent);
- if (FAILED(hr))
+ if (FAILED(hr = device_init(object, wined3d, adapter_idx,
+ device_type, focus_window, flags, surface_alignment,
+ feature_levels, feature_level_count, device_parent)))
{
WARN("Failed to initialize device, hr %#x.\n", hr);
heap_free(object);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index bf32953032ea..23f5fd70c675 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -6243,6 +6243,28 @@ const char *wined3d_debug_location(DWORD location)
return wine_dbg_sprintf("%s%s%s", prefix, buffer.str, suffix);
}
+const char *wined3d_debug_feature_level(enum wined3d_feature_level level)
+{
+ switch (level)
+ {
+#define LEVEL_TO_STR(level) case level: return #level
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_5);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_6);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_7);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_8);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_1);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_SM2);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_9_SM3);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_10);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_10_1);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_11);
+ LEVEL_TO_STR(WINED3D_FEATURE_LEVEL_11_1);
+#undef LEVEL_TO_STR
+ default:
+ return wine_dbg_sprintf("%#x", level);
+ }
+}
+
/* Print a floating point value with the %.8e format specifier, always using
* '.' as decimal separator. */
void wined3d_ftoa(float value, char *s)
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 93cecf0d3bb4..a401e04dcf3b 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -42,7 +42,7 @@
@ cdecl wined3d_device_copy_resource(ptr ptr ptr)
@ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long ptr long ptr long)
@ cdecl wined3d_device_copy_uav_counter(ptr ptr long ptr)
-@ cdecl wined3d_device_create(ptr long long ptr long long ptr ptr)
+@ cdecl wined3d_device_create(ptr long long ptr long long ptr long ptr ptr)
@ cdecl wined3d_device_decref(ptr)
@ cdecl wined3d_device_dispatch_compute(ptr long long long)
@ cdecl wined3d_device_dispatch_compute_indirect(ptr ptr long)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 637c7218c184..423dda83e731 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2981,6 +2981,8 @@ struct wined3d_device
WORD padding2 : 16;
+ enum wined3d_feature_level feature_level;
+
struct wined3d_state state;
struct wined3d_state *update_state;
struct wined3d_stateblock *recording;
@@ -3036,7 +3038,8 @@ BOOL device_context_add(struct wined3d_device *device, struct wined3d_context *c
void device_context_remove(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags,
- BYTE surface_alignment, struct wined3d_device_parent *device_parent) DECLSPEC_HIDDEN;
+ BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count,
+ struct wined3d_device_parent *device_parent) DECLSPEC_HIDDEN;
LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode,
UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN;
void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
@@ -3913,6 +3916,7 @@ const char *debug_ivec4(const struct wined3d_ivec4 *v) DECLSPEC_HIDDEN;
const char *debug_uvec4(const struct wined3d_uvec4 *v) DECLSPEC_HIDDEN;
const char *debug_shader_type(enum wined3d_shader_type shader_type) DECLSPEC_HIDDEN;
const char *debug_vec4(const struct wined3d_vec4 *v) DECLSPEC_HIDDEN;
+const char *wined3d_debug_feature_level(enum wined3d_feature_level level) DECLSPEC_HIDDEN;
void dump_color_fixup_desc(struct color_fixup_desc fixup) DECLSPEC_HIDDEN;
BOOL is_invalid_op(const struct wined3d_state *state, int stage,
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 17b0fd4c456d..6b81b3ab1df1 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2248,8 +2248,9 @@ HRESULT __cdecl wined3d_device_copy_sub_resource_region(struct wined3d_device *d
unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, unsigned int flags);
void __cdecl wined3d_device_copy_uav_counter(struct wined3d_device *device,
struct wined3d_buffer *dst_buffer, unsigned int offset, struct wined3d_unordered_access_view *uav);
-HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx,
+HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, unsigned int adapter_idx,
enum wined3d_device_type device_type, HWND focus_window, DWORD behaviour_flags, BYTE surface_alignment,
+ const enum wined3d_feature_level *feature_levels, unsigned int feature_level_count,
struct wined3d_device_parent *device_parent, struct wined3d_device **device);
ULONG __cdecl wined3d_device_decref(struct wined3d_device *device);
void __cdecl wined3d_device_dispatch_compute(struct wined3d_device *device,
--
2.16.4
Sept. 23, 2018
[PATCH 3/6] wined3d: Add remaining feature levels.
by Józef Kucia
We still don't have proper and exhaustive checks for feature levels
capabilities.
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/dxgi/utils.c | 6 +++---
dlls/wined3d/adapter_gl.c | 6 +++++-
include/wine/wined3d.h | 3 +++
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/dlls/dxgi/utils.c b/dlls/dxgi/utils.c
index e857a1f090f5..009d351f633f 100644
--- a/dlls/dxgi/utils.c
+++ b/dlls/dxgi/utils.c
@@ -626,11 +626,11 @@ static enum wined3d_feature_level wined3d_feature_level_from_d3d(D3D_FEATURE_LEV
switch (feature_level)
{
case D3D_FEATURE_LEVEL_11_1:
- return WINED3D_FEATURE_LEVEL_11;
+ return WINED3D_FEATURE_LEVEL_11_1;
case D3D_FEATURE_LEVEL_11_0:
return WINED3D_FEATURE_LEVEL_11;
case D3D_FEATURE_LEVEL_10_1:
- return WINED3D_FEATURE_LEVEL_10;
+ return WINED3D_FEATURE_LEVEL_10_1;
case D3D_FEATURE_LEVEL_10_0:
return WINED3D_FEATURE_LEVEL_10;
case D3D_FEATURE_LEVEL_9_3:
@@ -638,7 +638,7 @@ static enum wined3d_feature_level wined3d_feature_level_from_d3d(D3D_FEATURE_LEV
case D3D_FEATURE_LEVEL_9_2:
return WINED3D_FEATURE_LEVEL_9_SM2;
case D3D_FEATURE_LEVEL_9_1:
- return WINED3D_FEATURE_LEVEL_9_SM2;
+ return WINED3D_FEATURE_LEVEL_9_1;
default:
FIXME("Unhandled feature level %#x.\n", feature_level);
return 0;
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 0ee71fd63df5..1d360d104bf8 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -1256,10 +1256,14 @@ static enum wined3d_feature_level feature_level_from_caps(const struct wined3d_g
if (shader_model >= 5
&& gl_info->supported[ARB_DRAW_INDIRECT]
&& gl_info->supported[ARB_TEXTURE_COMPRESSION_BPTC])
- return WINED3D_FEATURE_LEVEL_11;
+ return WINED3D_FEATURE_LEVEL_11_1;
if (shader_model >= 4)
+ {
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY])
+ return WINED3D_FEATURE_LEVEL_10_1;
return WINED3D_FEATURE_LEVEL_10;
+ }
}
if (shader_model >= 3)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 3c01f755d869..17b0fd4c456d 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -95,10 +95,13 @@ enum wined3d_feature_level
WINED3D_FEATURE_LEVEL_6 = 0x6000,
WINED3D_FEATURE_LEVEL_7 = 0x7000,
WINED3D_FEATURE_LEVEL_8 = 0x8000,
+ WINED3D_FEATURE_LEVEL_9_1 = 0x9100,
WINED3D_FEATURE_LEVEL_9_SM2 = 0x9200,
WINED3D_FEATURE_LEVEL_9_SM3 = 0x9300,
WINED3D_FEATURE_LEVEL_10 = 0xa000,
+ WINED3D_FEATURE_LEVEL_10_1 = 0xa100,
WINED3D_FEATURE_LEVEL_11 = 0xb000,
+ WINED3D_FEATURE_LEVEL_11_1 = 0xb100,
};
enum wined3d_degree_type
--
2.16.4
Sept. 23, 2018
[PATCH 2/6] wined3d: Make feature level enum compatible with Direct3D enum.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/directx.c | 89 ++++++++++++++++++++++++++++++--------------------
include/wine/wined3d.h | 18 +++++-----
2 files changed, 62 insertions(+), 45 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 89684477e685..4e8afed0a938 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -617,49 +617,52 @@ void wined3d_driver_info_init(struct wined3d_driver_info *driver_info,
enum wined3d_pci_device wined3d_gpu_from_feature_level(enum wined3d_pci_vendor *vendor,
enum wined3d_feature_level feature_level)
{
- unsigned int i;
-
- static const enum wined3d_pci_device card_fallback_nvidia[] =
- {
- CARD_NVIDIA_RIVA_128, /* D3D5 */
- CARD_NVIDIA_RIVA_TNT, /* D3D6 */
- CARD_NVIDIA_GEFORCE, /* D3D7 */
- CARD_NVIDIA_GEFORCE3, /* D3D8 */
- CARD_NVIDIA_GEFORCEFX_5800, /* D3D9_SM2 */
- CARD_NVIDIA_GEFORCE_6800, /* D3D9_SM3 */
- CARD_NVIDIA_GEFORCE_8800GTX, /* D3D10 */
- CARD_NVIDIA_GEFORCE_GTX470, /* D3D11 */
+ static const struct wined3d_fallback_card
+ {
+ enum wined3d_feature_level feature_level;
+ enum wined3d_pci_device device_id;
+ }
+ card_fallback_nvidia[] =
+ {
+ {WINED3D_FEATURE_LEVEL_5, CARD_NVIDIA_RIVA_128},
+ {WINED3D_FEATURE_LEVEL_6, CARD_NVIDIA_RIVA_TNT},
+ {WINED3D_FEATURE_LEVEL_7, CARD_NVIDIA_GEFORCE},
+ {WINED3D_FEATURE_LEVEL_8, CARD_NVIDIA_GEFORCE3},
+ {WINED3D_FEATURE_LEVEL_9_SM2, CARD_NVIDIA_GEFORCEFX_5800},
+ {WINED3D_FEATURE_LEVEL_9_SM3, CARD_NVIDIA_GEFORCE_6800},
+ {WINED3D_FEATURE_LEVEL_10, CARD_NVIDIA_GEFORCE_8800GTX},
+ {WINED3D_FEATURE_LEVEL_11, CARD_NVIDIA_GEFORCE_GTX470},
+ {WINED3D_FEATURE_LEVEL_NONE},
},
card_fallback_amd[] =
{
- CARD_AMD_RAGE_128PRO, /* D3D5 */
- CARD_AMD_RAGE_128PRO, /* D3D6 */
- CARD_AMD_RADEON_7200, /* D3D7 */
- CARD_AMD_RADEON_8500, /* D3D8 */
- CARD_AMD_RADEON_9500, /* D3D9_SM2 */
- CARD_AMD_RADEON_X1600, /* D3D9_SM3 */
- CARD_AMD_RADEON_HD2900, /* D3D10 */
- CARD_AMD_RADEON_HD5600, /* D3D11 */
+ {WINED3D_FEATURE_LEVEL_5, CARD_AMD_RAGE_128PRO},
+ {WINED3D_FEATURE_LEVEL_6, CARD_AMD_RAGE_128PRO},
+ {WINED3D_FEATURE_LEVEL_7, CARD_AMD_RADEON_7200},
+ {WINED3D_FEATURE_LEVEL_8, CARD_AMD_RADEON_8500},
+ {WINED3D_FEATURE_LEVEL_9_SM2, CARD_AMD_RADEON_9500},
+ {WINED3D_FEATURE_LEVEL_9_SM3, CARD_AMD_RADEON_X1600},
+ {WINED3D_FEATURE_LEVEL_10, CARD_AMD_RADEON_HD2900},
+ {WINED3D_FEATURE_LEVEL_11, CARD_AMD_RADEON_HD5600},
+ {WINED3D_FEATURE_LEVEL_NONE},
},
card_fallback_intel[] =
{
- CARD_INTEL_845G, /* D3D5 */
- CARD_INTEL_845G, /* D3D6 */
- CARD_INTEL_845G, /* D3D7 */
- CARD_INTEL_915G, /* D3D8 */
- CARD_INTEL_915G, /* D3D9_SM2 */
- CARD_INTEL_945G, /* D3D9_SM3 */
- CARD_INTEL_G45, /* D3D10 */
- CARD_INTEL_IVBD, /* D3D11 */
+ {WINED3D_FEATURE_LEVEL_5, CARD_INTEL_845G},
+ {WINED3D_FEATURE_LEVEL_6, CARD_INTEL_845G},
+ {WINED3D_FEATURE_LEVEL_7, CARD_INTEL_845G},
+ {WINED3D_FEATURE_LEVEL_8, CARD_INTEL_915G},
+ {WINED3D_FEATURE_LEVEL_9_SM2, CARD_INTEL_915G},
+ {WINED3D_FEATURE_LEVEL_9_SM3, CARD_INTEL_945G},
+ {WINED3D_FEATURE_LEVEL_10, CARD_INTEL_G45},
+ {WINED3D_FEATURE_LEVEL_11, CARD_INTEL_IVBD},
+ {WINED3D_FEATURE_LEVEL_NONE},
};
- C_ASSERT(ARRAY_SIZE(card_fallback_nvidia) == WINED3D_FEATURE_LEVEL_COUNT);
- C_ASSERT(ARRAY_SIZE(card_fallback_amd) == WINED3D_FEATURE_LEVEL_COUNT);
- C_ASSERT(ARRAY_SIZE(card_fallback_intel) == WINED3D_FEATURE_LEVEL_COUNT);
static const struct
{
enum wined3d_pci_vendor vendor;
- const enum wined3d_pci_device *device;
+ const struct wined3d_fallback_card *cards;
}
fallbacks[] =
{
@@ -669,15 +672,29 @@ enum wined3d_pci_device wined3d_gpu_from_feature_level(enum wined3d_pci_vendor *
{HW_VENDOR_INTEL, card_fallback_intel},
};
+ const struct wined3d_fallback_card *cards;
+ enum wined3d_pci_device device_id;
+ unsigned int i;
+
+ cards = NULL;
for (i = 0; i < ARRAY_SIZE(fallbacks); ++i)
{
if (*vendor == fallbacks[i].vendor)
- return fallbacks[i].device[feature_level];
+ cards = fallbacks[i].cards;
+ }
+ if (!cards)
+ {
+ *vendor = HW_VENDOR_NVIDIA;
+ cards = card_fallback_nvidia;
}
- *vendor = HW_VENDOR_NVIDIA;
-
- return card_fallback_nvidia[feature_level];
+ device_id = cards->device_id;
+ for (i = 0; cards[i].feature_level; ++i)
+ {
+ if (feature_level >= cards[i].feature_level)
+ device_id = cards[i].device_id;
+ }
+ return device_id;
}
UINT CDECL wined3d_get_adapter_count(const struct wined3d *wined3d)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index ac7e3dd85cb4..3c01f755d869 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -90,15 +90,15 @@ enum wined3d_device_type
enum wined3d_feature_level
{
- WINED3D_FEATURE_LEVEL_5,
- WINED3D_FEATURE_LEVEL_6,
- WINED3D_FEATURE_LEVEL_7,
- WINED3D_FEATURE_LEVEL_8,
- WINED3D_FEATURE_LEVEL_9_SM2,
- WINED3D_FEATURE_LEVEL_9_SM3,
- WINED3D_FEATURE_LEVEL_10,
- WINED3D_FEATURE_LEVEL_11,
- WINED3D_FEATURE_LEVEL_COUNT
+ WINED3D_FEATURE_LEVEL_NONE = 0x0000,
+ WINED3D_FEATURE_LEVEL_5 = 0x5000,
+ WINED3D_FEATURE_LEVEL_6 = 0x6000,
+ WINED3D_FEATURE_LEVEL_7 = 0x7000,
+ WINED3D_FEATURE_LEVEL_8 = 0x8000,
+ WINED3D_FEATURE_LEVEL_9_SM2 = 0x9200,
+ WINED3D_FEATURE_LEVEL_9_SM3 = 0x9300,
+ WINED3D_FEATURE_LEVEL_10 = 0xa000,
+ WINED3D_FEATURE_LEVEL_11 = 0xb000,
};
enum wined3d_degree_type
--
2.16.4
Sept. 23, 2018
[PATCH 1/6] dxgi: Introduce wined3d_feature_level_from_d3d() helper function.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/dxgi/utils.c | 75 ++++++++++++++++++++++++++-----------------------------
1 file changed, 36 insertions(+), 39 deletions(-)
diff --git a/dlls/dxgi/utils.c b/dlls/dxgi/utils.c
index aed62a4a3b36..e857a1f090f5 100644
--- a/dlls/dxgi/utils.c
+++ b/dlls/dxgi/utils.c
@@ -621,27 +621,36 @@ HRESULT dxgi_set_private_data_interface(struct wined3d_private_store *store,
return hr;
}
-D3D_FEATURE_LEVEL dxgi_check_feature_level_support(struct dxgi_factory *factory, struct dxgi_adapter *adapter,
- const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count)
+static enum wined3d_feature_level wined3d_feature_level_from_d3d(D3D_FEATURE_LEVEL feature_level)
{
- static const struct
+ switch (feature_level)
{
- D3D_FEATURE_LEVEL d3d;
- enum wined3d_feature_level wined3d;
+ case D3D_FEATURE_LEVEL_11_1:
+ return WINED3D_FEATURE_LEVEL_11;
+ case D3D_FEATURE_LEVEL_11_0:
+ return WINED3D_FEATURE_LEVEL_11;
+ case D3D_FEATURE_LEVEL_10_1:
+ return WINED3D_FEATURE_LEVEL_10;
+ case D3D_FEATURE_LEVEL_10_0:
+ return WINED3D_FEATURE_LEVEL_10;
+ case D3D_FEATURE_LEVEL_9_3:
+ return WINED3D_FEATURE_LEVEL_9_SM3;
+ case D3D_FEATURE_LEVEL_9_2:
+ return WINED3D_FEATURE_LEVEL_9_SM2;
+ case D3D_FEATURE_LEVEL_9_1:
+ return WINED3D_FEATURE_LEVEL_9_SM2;
+ default:
+ FIXME("Unhandled feature level %#x.\n", feature_level);
+ return 0;
}
- wined3d_feature_levels[] =
- {
- {D3D_FEATURE_LEVEL_11_1, WINED3D_FEATURE_LEVEL_11},
- {D3D_FEATURE_LEVEL_11_0, WINED3D_FEATURE_LEVEL_11},
- {D3D_FEATURE_LEVEL_10_1, WINED3D_FEATURE_LEVEL_10},
- {D3D_FEATURE_LEVEL_10_0, WINED3D_FEATURE_LEVEL_10},
- {D3D_FEATURE_LEVEL_9_3, WINED3D_FEATURE_LEVEL_9_SM3},
- {D3D_FEATURE_LEVEL_9_2, WINED3D_FEATURE_LEVEL_9_SM2},
- {D3D_FEATURE_LEVEL_9_1, WINED3D_FEATURE_LEVEL_9_SM2},
- };
- D3D_FEATURE_LEVEL selected_feature_level = 0;
+}
+
+D3D_FEATURE_LEVEL dxgi_check_feature_level_support(struct dxgi_factory *factory, struct dxgi_adapter *adapter,
+ const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count)
+{
+ enum wined3d_feature_level wined3d_feature_level;
struct wined3d_caps caps;
- unsigned int i, j;
+ unsigned int i;
HRESULT hr;
wined3d_mutex_lock();
@@ -653,31 +662,19 @@ D3D_FEATURE_LEVEL dxgi_check_feature_level_support(struct dxgi_factory *factory,
for (i = 0; i < level_count; ++i)
{
- for (j = 0; j < ARRAY_SIZE(wined3d_feature_levels); ++j)
+ wined3d_feature_level = wined3d_feature_level_from_d3d(feature_levels[i]);
+ if (wined3d_feature_level && caps.max_feature_level >= wined3d_feature_level)
{
- if (feature_levels[i] == wined3d_feature_levels[j].d3d)
- {
- if (caps.max_feature_level >= wined3d_feature_levels[j].wined3d)
- {
- selected_feature_level = feature_levels[i];
- TRACE("Choosing supported feature level %s.\n",
- debug_feature_level(selected_feature_level));
- }
- break;
- }
+ TRACE("Choosing supported feature level %s.\n",
+ debug_feature_level(feature_levels[i]));
+ return feature_levels[i];
}
- if (selected_feature_level)
- break;
- if (j == ARRAY_SIZE(wined3d_feature_levels))
- FIXME("Unexpected feature level %#x.\n", feature_levels[i]);
- else
- TRACE("Feature level %s not supported, trying next fallback if available.\n",
- debug_feature_level(feature_levels[i]));
+ TRACE("Feature level %s not supported, trying next fallback if available.\n",
+ debug_feature_level(feature_levels[i]));
}
- if (!selected_feature_level)
- FIXME_(winediag)("None of the requested D3D feature levels is supported on this GPU "
- "with the current shader backend.\n");
- return selected_feature_level;
+ FIXME_(winediag)("None of the requested D3D feature levels is supported on this GPU "
+ "with the current shader backend.\n");
+ return 0;
}
--
2.16.4
Sept. 23, 2018