-- v3: d2d1/tests: Test IsSupported() for bitmap render targets. d2d1: Implement d2d_bitmap_render_target_IsSupported(). d2d1/tests: Test IsSupported() for DC render targets. d2d1: Implement d2d_dc_render_target_IsSupported(). d2d1/tests: Test IsSupported() for hwnd render targets. d2d1: Implement d2d_hwnd_render_target_IsSupported().
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/d2d1/d2d1_private.h | 1 + dlls/d2d1/hwnd_render_target.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 5dab3fbb2a8..4ccb311a234 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -257,6 +257,7 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID struct d2d_hwnd_render_target { ID2D1HwndRenderTarget ID2D1HwndRenderTarget_iface; + D2D1_RENDER_TARGET_PROPERTIES desc; LONG refcount;
ID2D1RenderTarget *dxgi_target; diff --git a/dlls/d2d1/hwnd_render_target.c b/dlls/d2d1/hwnd_render_target.c index 4d3fe43a1b3..05010b3ce3a 100644 --- a/dlls/d2d1/hwnd_render_target.c +++ b/dlls/d2d1/hwnd_render_target.c @@ -652,10 +652,40 @@ static BOOL STDMETHODCALLTYPE d2d_hwnd_render_target_IsSupported(ID2D1HwndRender const D2D1_RENDER_TARGET_PROPERTIES *desc) { struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + const D2D1_RENDER_TARGET_PROPERTIES *target_desc = &render_target->desc; + D2D1_PIXEL_FORMAT pixel_format;
TRACE("iface %p, desc %p.\n", iface, desc);
- return ID2D1RenderTarget_IsSupported(render_target->dxgi_target, desc); + if (!(target_desc->type == desc->type + || (target_desc->type == D2D1_RENDER_TARGET_TYPE_DEFAULT + && desc->type == D2D1_RENDER_TARGET_TYPE_HARDWARE) + || (target_desc->type == D2D1_RENDER_TARGET_TYPE_HARDWARE + && desc->type == D2D1_RENDER_TARGET_TYPE_DEFAULT) + || (target_desc->type == D2D1_RENDER_TARGET_TYPE_SOFTWARE + && desc->type == D2D1_RENDER_TARGET_TYPE_DEFAULT))) + return FALSE; + + pixel_format = ID2D1RenderTarget_GetPixelFormat(render_target->dxgi_target); + if (!(pixel_format.format == desc->pixelFormat.format + || (pixel_format.format == DXGI_FORMAT_UNKNOWN + && desc->pixelFormat.format == DXGI_FORMAT_B8G8R8A8_UNORM) + || (pixel_format.format == DXGI_FORMAT_B8G8R8A8_UNORM + && desc->pixelFormat.format == DXGI_FORMAT_UNKNOWN) + || (pixel_format.format == DXGI_FORMAT_R8G8B8A8_UNORM + && desc->pixelFormat.format == DXGI_FORMAT_UNKNOWN))) + return FALSE; + + if (!(pixel_format.alphaMode == desc->pixelFormat.alphaMode + || desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_UNKNOWN + || (pixel_format.alphaMode == D2D1_ALPHA_MODE_UNKNOWN + && desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE))) + return FALSE; + + if (!(target_desc->usage == desc->usage || desc->usage == D2D1_RENDER_TARGET_USAGE_NONE)) + return FALSE; + + return TRUE; }
static D2D1_WINDOW_STATE STDMETHODCALLTYPE d2d_hwnd_render_target_CheckWindowState(ID2D1HwndRenderTarget *iface) @@ -830,6 +860,7 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target return hr; }
+ render_target->desc = *desc; dxgi_rt_desc = *desc; if (dxgi_rt_desc.dpiX == 0.0f && dxgi_rt_desc.dpiY == 0.0f) ID2D1Factory1_GetDesktopDpi(factory, &dxgi_rt_desc.dpiX, &dxgi_rt_desc.dpiY);
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/d2d1/tests/d2d1.c | 278 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index a065c8ddfb5..ba0e678ef16 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -13280,6 +13280,283 @@ static void test_bitmap_create(BOOL d3d11) release_test_context(&ctx); }
+static void test_hwnd_target_is_supported(void) +{ + static const DWORD levels[] = {D2D1_FEATURE_LEVEL_DEFAULT, D2D1_FEATURE_LEVEL_9, D2D1_FEATURE_LEVEL_10}; + D2D1_RENDER_TARGET_PROPERTIES desc, template_desc, test_desc; + D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc; + D2D1_BITMAP_PROPERTIES1 bitmap_desc; + ID2D1DeviceContext *device_context; + D2D1_PIXEL_FORMAT pixel_format; + ID2D1HwndRenderTarget *rt; + ID2D1Factory *factory; + ID2D1Bitmap1 *bitmap; + unsigned int i, j; + D2D1_SIZE_U size; + BOOL supported; + HWND window; + HRESULT hr; + + window = create_window(); + ok(!!window, "Failed to create test window.\n"); + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + template_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + template_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN; + template_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; + template_desc.dpiX = 96.0f; + template_desc.dpiY = 96.0f; + template_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + template_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + hwnd_rt_desc.hwnd = window; + hwnd_rt_desc.pixelSize.width = 64; + hwnd_rt_desc.pixelSize.height = 64; + hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE; + + /* Make sure the template render target description is valid */ + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &template_desc, &hwnd_rt_desc, &rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + supported = ID2D1HwndRenderTarget_IsSupported(rt, &template_desc); + ok(supported, "Expected supported.\n"); + ID2D1HwndRenderTarget_Release(rt); + + /* Test that SetTarget() with a bitmap of a different usage doesn't change the render target usage */ + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &template_desc, &hwnd_rt_desc, &rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1HwndRenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + test_desc = template_desc; + test_desc.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; + supported = ID2D1HwndRenderTarget_IsSupported(rt, &test_desc); + ok(!supported, "Expected unsupported.\n"); + + memset(&bitmap_desc, 0, sizeof(bitmap_desc)); + bitmap_desc.pixelFormat = ID2D1DeviceContext_GetPixelFormat(device_context); + bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE; + size.width = 4; + size.height = 4; + hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap); + supported = ID2D1HwndRenderTarget_IsSupported(rt, &test_desc); + ok(!supported, "Expected unsupported.\n"); + ID2D1Bitmap1_Release(bitmap); + + /* Test that SetTarget() with a bitmap of a different format changes the render target format */ + test_desc = template_desc; + test_desc.pixelFormat.format = DXGI_FORMAT_R8G8B8A8_UNORM; + test_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + supported = ID2D1HwndRenderTarget_IsSupported(rt, &test_desc); + ok(!supported, "Expected unsupported.\n"); + + memset(&bitmap_desc, 0, sizeof(bitmap_desc)); + bitmap_desc.pixelFormat.format = DXGI_FORMAT_R8G8B8A8_UNORM; + bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET; + size.width = 4; + size.height = 4; + hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap); + pixel_format = ID2D1DeviceContext_GetPixelFormat(device_context); + ok(pixel_format.format == DXGI_FORMAT_R8G8B8A8_UNORM, "Got unexpected format %#x.\n", pixel_format.format); + ok(pixel_format.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED, "Got unexpected alpha %u.\n", pixel_format.alphaMode); + supported = ID2D1HwndRenderTarget_IsSupported(rt, &test_desc); + ok(supported, "Expected supported.\n"); + ID2D1Bitmap1_Release(bitmap); + + ID2D1DeviceContext_Release(device_context); + ID2D1HwndRenderTarget_Release(rt); + + /* Type */ + for (i = D2D1_RENDER_TARGET_TYPE_DEFAULT; i <= D2D1_RENDER_TARGET_TYPE_HARDWARE; ++i) + { + desc = template_desc; + desc.type = i; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + if (FAILED(hr)) + continue; + + for (j = D2D1_RENDER_TARGET_TYPE_DEFAULT; j <= D2D1_RENDER_TARGET_TYPE_HARDWARE; ++j) + { + winetest_push_context("type %u test %u", i, j); + + test_desc = template_desc; + test_desc.type = j; + supported = ID2D1HwndRenderTarget_IsSupported(rt, &test_desc); + if (i == j || (i == D2D1_RENDER_TARGET_TYPE_DEFAULT && j == D2D1_RENDER_TARGET_TYPE_HARDWARE) + || (i == D2D1_RENDER_TARGET_TYPE_HARDWARE && j == D2D1_RENDER_TARGET_TYPE_DEFAULT) + || (i == D2D1_RENDER_TARGET_TYPE_SOFTWARE && j == D2D1_RENDER_TARGET_TYPE_DEFAULT)) + ok(supported || broken(i == D2D1_RENDER_TARGET_TYPE_DEFAULT + && j == D2D1_RENDER_TARGET_TYPE_HARDWARE) /* Win7 */, "Expected supported.\n"); + else + ok(!supported || broken(i == D2D1_RENDER_TARGET_TYPE_DEFAULT + && j == D2D1_RENDER_TARGET_TYPE_SOFTWARE) /* Win7 */, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1HwndRenderTarget_Release(rt); + } + + /* Pixel DXGI format */ + for (i = DXGI_FORMAT_UNKNOWN; i <= DXGI_FORMAT_V408; ++i) + { + if (i > DXGI_FORMAT_B4G4R4A4_UNORM && i < DXGI_FORMAT_P208) + continue; + + desc = template_desc; + desc.pixelFormat.format = i; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + if (FAILED(hr)) + continue; + + for (j = DXGI_FORMAT_UNKNOWN; j <= DXGI_FORMAT_V408; ++j) + { + if (j > DXGI_FORMAT_B4G4R4A4_UNORM && j < DXGI_FORMAT_P208) + continue; + + winetest_push_context("format %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.pixelFormat.format = j; + supported = ID2D1HwndRenderTarget_IsSupported(rt, &test_desc); + if (i == j || (i == DXGI_FORMAT_UNKNOWN && j == DXGI_FORMAT_B8G8R8A8_UNORM) + || (i == DXGI_FORMAT_B8G8R8A8_UNORM && j == DXGI_FORMAT_UNKNOWN) + || (i == DXGI_FORMAT_R8G8B8A8_UNORM && j == DXGI_FORMAT_UNKNOWN)) + ok(supported, "Expected supported.\n"); + else + ok(!supported, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1HwndRenderTarget_Release(rt); + } + + /* Pixel alpha mode */ + for (i = D2D1_ALPHA_MODE_UNKNOWN; i <= D2D1_ALPHA_MODE_IGNORE; ++i) + { + desc = template_desc; + desc.pixelFormat.alphaMode = i; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + if (FAILED(hr)) + continue; + + for (j = D2D1_ALPHA_MODE_UNKNOWN; j <= D2D1_ALPHA_MODE_IGNORE; ++j) + { + winetest_push_context("alpha %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.pixelFormat.alphaMode = j; + supported = ID2D1HwndRenderTarget_IsSupported(rt, &test_desc); + if (i == j || j == D2D1_ALPHA_MODE_UNKNOWN + || (i == D2D1_ALPHA_MODE_UNKNOWN && j == D2D1_ALPHA_MODE_IGNORE)) + ok(supported, "Expected supported.\n"); + else + ok(!supported, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1HwndRenderTarget_Release(rt); + } + + /* DPI */ + for (i = 0; i <= 192; i += 96) + { + desc = template_desc; + desc.dpiX = i; + desc.dpiY = i; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + if (FAILED(hr)) + continue; + + for (j = 0; j <= 192; j += 96) + { + winetest_push_context("dpi %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.dpiX = j; + test_desc.dpiY = j; + supported = ID2D1HwndRenderTarget_IsSupported(rt, &test_desc); + ok(supported, "Expected supported.\n"); + + winetest_pop_context(); + } + + ID2D1HwndRenderTarget_Release(rt); + } + + /* Usage */ + for (i = D2D1_RENDER_TARGET_USAGE_NONE; i <= D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; ++i) + { + desc = template_desc; + desc.usage = i; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + if (FAILED(hr)) + continue; + + for (j = D2D1_RENDER_TARGET_USAGE_NONE; j <= D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; ++j) + { + winetest_push_context("usage %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.usage = j; + supported = ID2D1HwndRenderTarget_IsSupported(rt, &test_desc); + if (i == j || j == D2D1_RENDER_TARGET_USAGE_NONE) + ok(supported, "Expected supported.\n"); + else + ok(!supported, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1HwndRenderTarget_Release(rt); + } + + /* Min level */ + for (i = 0; i < ARRAY_SIZE(levels); ++i) + { + desc = template_desc; + desc.minLevel = levels[i]; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + if (FAILED(hr)) + continue; + + for (j = 0; j < ARRAY_SIZE(levels); ++j) + { + winetest_push_context("level %#lx test %#lx", levels[i], levels[j]); + + test_desc = template_desc; + test_desc.minLevel = levels[j]; + supported = ID2D1HwndRenderTarget_IsSupported(rt, &test_desc); + ok(supported || broken(j != D2D1_FEATURE_LEVEL_DEFAULT) /* Win7 */, "Expected supported.\n"); + + winetest_pop_context(); + } + + ID2D1HwndRenderTarget_Release(rt); + } + + ID2D1Factory_Release(factory); + DestroyWindow(window); +} + +static void test_is_supported(BOOL d3d11) +{ + struct d2d1_test_context ctx; + + if (!init_test_context(&ctx, d3d11)) + return; + release_test_context(&ctx); + + test_hwnd_target_is_supported(); +} + START_TEST(d2d1) { HMODULE d2d1_dll = GetModuleHandleA("d2d1.dll"); @@ -13364,6 +13641,7 @@ START_TEST(d2d1) queue_test(test_image_bounds); queue_test(test_bitmap_map); queue_test(test_bitmap_create); + queue_test(test_is_supported);
run_queued_tests(); }
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/d2d1/d2d1_private.h | 1 + dlls/d2d1/dc_render_target.c | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 4ccb311a234..0206f474dbe 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -239,6 +239,7 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, struct d2d_dc_render_target { ID2D1DCRenderTarget ID2D1DCRenderTarget_iface; + D2D1_RENDER_TARGET_PROPERTIES desc; LONG refcount;
IDXGISurface1 *dxgi_surface; diff --git a/dlls/d2d1/dc_render_target.c b/dlls/d2d1/dc_render_target.c index 30eafe361d1..f9697332e25 100644 --- a/dlls/d2d1/dc_render_target.c +++ b/dlls/d2d1/dc_render_target.c @@ -673,10 +673,43 @@ static BOOL STDMETHODCALLTYPE d2d_dc_render_target_IsSupported(ID2D1DCRenderTarg const D2D1_RENDER_TARGET_PROPERTIES *desc) { struct d2d_dc_render_target *render_target = impl_from_ID2D1DCRenderTarget(iface); + const D2D1_RENDER_TARGET_PROPERTIES *target_desc = &render_target->desc; + D2D1_PIXEL_FORMAT pixel_format;
TRACE("iface %p, desc %p.\n", iface, desc);
- return ID2D1RenderTarget_IsSupported(render_target->dxgi_target, desc); + if (!(target_desc->type == desc->type + || (target_desc->type == D2D1_RENDER_TARGET_TYPE_DEFAULT + && desc->type == D2D1_RENDER_TARGET_TYPE_HARDWARE) + || (target_desc->type == D2D1_RENDER_TARGET_TYPE_HARDWARE + && desc->type == D2D1_RENDER_TARGET_TYPE_DEFAULT) + || (target_desc->type == D2D1_RENDER_TARGET_TYPE_SOFTWARE + && desc->type == D2D1_RENDER_TARGET_TYPE_DEFAULT))) + return FALSE; + + pixel_format = ID2D1RenderTarget_GetPixelFormat(render_target->dxgi_target); + if (!(pixel_format.format == desc->pixelFormat.format + || (pixel_format.format == DXGI_FORMAT_UNKNOWN + && desc->pixelFormat.format == DXGI_FORMAT_B8G8R8A8_UNORM) + || (pixel_format.format == DXGI_FORMAT_B8G8R8A8_UNORM + && desc->pixelFormat.format == DXGI_FORMAT_UNKNOWN) + || (pixel_format.format == DXGI_FORMAT_R8G8B8A8_UNORM + && desc->pixelFormat.format == DXGI_FORMAT_UNKNOWN))) + return FALSE; + + if (!((pixel_format.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED + && (desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_UNKNOWN + || desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED)) + || (pixel_format.alphaMode == D2D1_ALPHA_MODE_IGNORE + && (desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_UNKNOWN + || desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE)))) + return FALSE; + + if (!(target_desc->usage == desc->usage || desc->usage == D2D1_RENDER_TARGET_USAGE_NONE + || desc->usage == D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE)) + return FALSE; + + return TRUE; }
static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget *iface, @@ -808,6 +841,7 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID HRESULT hr;
render_target->ID2D1DCRenderTarget_iface.lpVtbl = &d2d_dc_render_target_vtbl; + render_target->desc = *desc;
/* Set with BindDC(). */ SetRectEmpty(&render_target->dst_rect);
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/d2d1/tests/d2d1.c | 261 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index ba0e678ef16..6441f239af9 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -13546,6 +13546,266 @@ static void test_hwnd_target_is_supported(void) DestroyWindow(window); }
+static void test_dc_target_is_supported(void) +{ + static const DWORD levels[] = {D2D1_FEATURE_LEVEL_DEFAULT, D2D1_FEATURE_LEVEL_9, D2D1_FEATURE_LEVEL_10}; + D2D1_RENDER_TARGET_PROPERTIES desc, template_desc, test_desc; + D2D1_BITMAP_PROPERTIES1 bitmap_desc; + ID2D1DeviceContext *device_context; + D2D1_PIXEL_FORMAT pixel_format; + ID2D1DCRenderTarget *dc_rt; + ID2D1Factory *factory; + ID2D1Bitmap1 *bitmap; + unsigned int i, j; + D2D1_SIZE_U size; + BOOL supported; + HWND window; + HRESULT hr; + + window = create_window(); + ok(!!window, "Failed to create test window.\n"); + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + template_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + template_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + template_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + template_desc.dpiX = 96.0f; + template_desc.dpiY = 96.0f; + template_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + template_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + /* Make sure the render target description template is valid */ + hr = ID2D1Factory_CreateDCRenderTarget(factory, &template_desc, &dc_rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + supported = ID2D1DCRenderTarget_IsSupported(dc_rt, &template_desc); + ok(supported, "Expected supported.\n"); + ID2D1DCRenderTarget_Release(dc_rt); + + /* Test that SetTarget() with a bitmap of a different usage doesn't change the render target usage */ + hr = ID2D1Factory_CreateDCRenderTarget(factory, &template_desc, &dc_rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1DCRenderTarget_QueryInterface(dc_rt, &IID_ID2D1DeviceContext, (void **)&device_context); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + test_desc = template_desc; + test_desc.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; + supported = ID2D1DCRenderTarget_IsSupported(dc_rt, &test_desc); + ok(supported, "Expected unsupported.\n"); + + memset(&bitmap_desc, 0, sizeof(bitmap_desc)); + bitmap_desc.pixelFormat = ID2D1DeviceContext_GetPixelFormat(device_context); + bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET; + size.width = 4; + size.height = 4; + hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap); + supported = ID2D1DCRenderTarget_IsSupported(dc_rt, &test_desc); + ok(supported, "Expected unsupported.\n"); + ID2D1Bitmap1_Release(bitmap); + + /* Test that SetTarget() with a bitmap of a different format changes the render target format */ + test_desc = template_desc; + test_desc.pixelFormat.format = DXGI_FORMAT_R8G8B8A8_UNORM; + test_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + supported = ID2D1DCRenderTarget_IsSupported(dc_rt, &test_desc); + ok(!supported, "Expected unsupported.\n"); + + memset(&bitmap_desc, 0, sizeof(bitmap_desc)); + bitmap_desc.pixelFormat.format = DXGI_FORMAT_R8G8B8A8_UNORM; + bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET; + size.width = 4; + size.height = 4; + hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap); + pixel_format = ID2D1DeviceContext_GetPixelFormat(device_context); + ok(pixel_format.format == DXGI_FORMAT_R8G8B8A8_UNORM, "Got unexpected format %#x.\n", pixel_format.format); + ok(pixel_format.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED, "Got unexpected alpha %u.\n", pixel_format.alphaMode); + supported = ID2D1DCRenderTarget_IsSupported(dc_rt, &test_desc); + ok(supported, "Expected supported.\n"); + ID2D1Bitmap1_Release(bitmap); + + ID2D1DeviceContext_Release(device_context); + ID2D1DCRenderTarget_Release(dc_rt); + + /* Type */ + for (i = D2D1_RENDER_TARGET_TYPE_DEFAULT; i <= D2D1_RENDER_TARGET_TYPE_HARDWARE; ++i) + { + desc = template_desc; + desc.type = i; + hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &dc_rt); + if (FAILED(hr)) + continue; + + for (j = D2D1_RENDER_TARGET_TYPE_DEFAULT; j <= D2D1_RENDER_TARGET_TYPE_HARDWARE; ++j) + { + winetest_push_context("type %u test %u", i, j); + + test_desc = template_desc; + test_desc.type = j; + supported = ID2D1DCRenderTarget_IsSupported(dc_rt, &test_desc); + if (i == j || (i == D2D1_RENDER_TARGET_TYPE_DEFAULT && j == D2D1_RENDER_TARGET_TYPE_HARDWARE) + || (i == D2D1_RENDER_TARGET_TYPE_HARDWARE && j == D2D1_RENDER_TARGET_TYPE_DEFAULT) + || (i == D2D1_RENDER_TARGET_TYPE_SOFTWARE && j == D2D1_RENDER_TARGET_TYPE_DEFAULT)) + ok(supported || broken(i == D2D1_RENDER_TARGET_TYPE_DEFAULT + && j == D2D1_RENDER_TARGET_TYPE_HARDWARE) /* Win7 */, "Expected supported.\n"); + else + ok(!supported || broken(i == D2D1_RENDER_TARGET_TYPE_DEFAULT + && j == D2D1_RENDER_TARGET_TYPE_SOFTWARE) /* Win7 */, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1DCRenderTarget_Release(dc_rt); + } + + /* Pixel DXGI format */ + for (i = DXGI_FORMAT_UNKNOWN; i <= DXGI_FORMAT_V408; ++i) + { + if (i > DXGI_FORMAT_B4G4R4A4_UNORM && i < DXGI_FORMAT_P208) + continue; + + desc = template_desc; + desc.pixelFormat.format = i; + hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &dc_rt); + if (FAILED(hr)) + continue; + + for (j = DXGI_FORMAT_UNKNOWN; j <= DXGI_FORMAT_V408; ++j) + { + if (j > DXGI_FORMAT_B4G4R4A4_UNORM && j < DXGI_FORMAT_P208) + continue; + + winetest_push_context("format %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.pixelFormat.format = j; + supported = ID2D1DCRenderTarget_IsSupported(dc_rt, &test_desc); + if (i == j || (i == DXGI_FORMAT_UNKNOWN && j == DXGI_FORMAT_B8G8R8A8_UNORM) + || (i == DXGI_FORMAT_B8G8R8A8_UNORM && j == DXGI_FORMAT_UNKNOWN) + || (i == DXGI_FORMAT_R8G8B8A8_UNORM && j == DXGI_FORMAT_UNKNOWN)) + ok(supported, "Expected supported.\n"); + else + ok(!supported, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1DCRenderTarget_Release(dc_rt); + } + + /* Pixel alpha mode */ + for (i = D2D1_ALPHA_MODE_UNKNOWN; i <= D2D1_ALPHA_MODE_IGNORE; ++i) + { + desc = template_desc; + desc.pixelFormat.alphaMode = i; + hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &dc_rt); + if (FAILED(hr)) + continue; + + for (j = D2D1_ALPHA_MODE_UNKNOWN; j <= D2D1_ALPHA_MODE_IGNORE; ++j) + { + winetest_push_context("alpha %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.pixelFormat.alphaMode = j; + supported = ID2D1DCRenderTarget_IsSupported(dc_rt, &test_desc); + if ((i == D2D1_ALPHA_MODE_PREMULTIPLIED && (j == D2D1_ALPHA_MODE_UNKNOWN || j == D2D1_ALPHA_MODE_PREMULTIPLIED)) + || (i == D2D1_ALPHA_MODE_IGNORE && (j == D2D1_ALPHA_MODE_UNKNOWN || j == D2D1_ALPHA_MODE_IGNORE))) + ok(supported, "Expected supported.\n"); + else + ok(!supported, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1DCRenderTarget_Release(dc_rt); + } + + /* DPI */ + for (i = 0; i <= 192; i += 96) + { + desc = template_desc; + desc.dpiX = i; + desc.dpiY = i; + hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &dc_rt); + if (FAILED(hr)) + continue; + + for (j = 0; j <= 192; j += 96) + { + winetest_push_context("dpi %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.dpiX = j; + test_desc.dpiY = j; + supported = ID2D1DCRenderTarget_IsSupported(dc_rt, &test_desc); + ok(supported, "Expected supported.\n"); + + winetest_pop_context(); + } + + ID2D1DCRenderTarget_Release(dc_rt); + } + + /* Usage */ + for (i = D2D1_RENDER_TARGET_USAGE_NONE; i <= D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; ++i) + { + desc = template_desc; + desc.usage = i; + hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &dc_rt); + if (FAILED(hr)) + continue; + + for (j = D2D1_RENDER_TARGET_USAGE_NONE; j <= D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; ++j) + { + winetest_push_context("usage %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.usage = j; + supported = ID2D1DCRenderTarget_IsSupported(dc_rt, &test_desc); + if (i == j || j == D2D1_RENDER_TARGET_USAGE_NONE || j == D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE) + ok(supported, "Expected supported.\n"); + else + ok(!supported, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1DCRenderTarget_Release(dc_rt); + } + + /* Min level */ + for (i = 0; i < ARRAY_SIZE(levels); ++i) + { + desc = template_desc; + desc.minLevel = levels[i]; + hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &dc_rt); + if (FAILED(hr)) + continue; + + for (j = 0; j < ARRAY_SIZE(levels); ++j) + { + winetest_push_context("level %#lx test %#lx", levels[i], levels[j]); + + test_desc = template_desc; + test_desc.minLevel = levels[j]; + supported = ID2D1DCRenderTarget_IsSupported(dc_rt, &test_desc); + ok(supported || broken(j != D2D1_FEATURE_LEVEL_DEFAULT) /* Win7 */, "Expected supported.\n"); + + winetest_pop_context(); + } + + ID2D1DCRenderTarget_Release(dc_rt); + } + + ID2D1Factory_Release(factory); + DestroyWindow(window); +} + static void test_is_supported(BOOL d3d11) { struct d2d1_test_context ctx; @@ -13555,6 +13815,7 @@ static void test_is_supported(BOOL d3d11) release_test_context(&ctx);
test_hwnd_target_is_supported(); + test_dc_target_is_supported(); }
START_TEST(d2d1)
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/d2d1/bitmap_render_target.c | 70 ++++++++++++++++++++++++-------- dlls/d2d1/d2d1_private.h | 2 + dlls/d2d1/device.c | 2 + 3 files changed, 56 insertions(+), 18 deletions(-)
diff --git a/dlls/d2d1/bitmap_render_target.c b/dlls/d2d1/bitmap_render_target.c index ce8b8965d39..442acbad5c7 100644 --- a/dlls/d2d1/bitmap_render_target.c +++ b/dlls/d2d1/bitmap_render_target.c @@ -641,10 +641,47 @@ static BOOL STDMETHODCALLTYPE d2d_bitmap_render_target_IsSupported(ID2D1BitmapRe const D2D1_RENDER_TARGET_PROPERTIES *desc) { struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + const D2D1_RENDER_TARGET_PROPERTIES *target_desc = &render_target->desc; + D2D1_PIXEL_FORMAT pixel_format;
TRACE("iface %p, desc %p.\n", iface, desc);
- return ID2D1RenderTarget_IsSupported(render_target->dxgi_target, desc); + if (!(target_desc->type == desc->type + || (target_desc->type == D2D1_RENDER_TARGET_TYPE_DEFAULT + && desc->type == D2D1_RENDER_TARGET_TYPE_HARDWARE) + || (target_desc->type == D2D1_RENDER_TARGET_TYPE_HARDWARE + && desc->type == D2D1_RENDER_TARGET_TYPE_DEFAULT) + || (target_desc->type == D2D1_RENDER_TARGET_TYPE_SOFTWARE + && desc->type == D2D1_RENDER_TARGET_TYPE_DEFAULT))) + return FALSE; + + pixel_format = ID2D1RenderTarget_GetPixelFormat(render_target->dxgi_target); + if (!(pixel_format.format == desc->pixelFormat.format + || (pixel_format.format == DXGI_FORMAT_UNKNOWN + && desc->pixelFormat.format == DXGI_FORMAT_B8G8R8A8_UNORM) + || (pixel_format.format == DXGI_FORMAT_B8G8R8A8_UNORM + && desc->pixelFormat.format == DXGI_FORMAT_UNKNOWN) + || (pixel_format.format == DXGI_FORMAT_R8G8B8A8_UNORM + && desc->pixelFormat.format == DXGI_FORMAT_UNKNOWN))) + return FALSE; + + if (!(((pixel_format.alphaMode == D2D1_ALPHA_MODE_UNKNOWN + || pixel_format.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED) + && (desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_UNKNOWN + || desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED)) + || (pixel_format.alphaMode == D2D1_ALPHA_MODE_IGNORE + && (desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE + || desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_UNKNOWN)))) + return FALSE; + + if (!(desc->usage == D2D1_RENDER_TARGET_USAGE_NONE + || (render_target->options == D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE + && desc->usage == D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE) + || (target_desc->usage == D2D1_RENDER_TARGET_USAGE_FORCE_BITMAP_REMOTING + && desc->usage == D2D1_RENDER_TARGET_USAGE_FORCE_BITMAP_REMOTING))) + return FALSE; + + return TRUE; }
static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_GetBitmap(ID2D1BitmapRenderTarget *iface, @@ -730,7 +767,6 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *pixel_format, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options) { - D2D1_RENDER_TARGET_PROPERTIES dxgi_rt_desc; D2D1_BITMAP_PROPERTIES1 bitmap_desc; ID2D1DeviceContext *context; D2D1_SIZE_U bitmap_size; @@ -740,10 +776,8 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta FIXME("Compatible target options are ignored, %#x.\n", options);
render_target->ID2D1BitmapRenderTarget_iface.lpVtbl = &d2d_bitmap_render_target_vtbl; - - dxgi_rt_desc.type = parent_target->desc.type; - dxgi_rt_desc.usage = parent_target->desc.usage; - dxgi_rt_desc.minLevel = parent_target->desc.minLevel; + render_target->options = options; + render_target->desc = parent_target->desc;
if (pixel_size) { @@ -763,29 +797,29 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta
if (size && size->width != 0.0f && size->height != 0.0f) { - dxgi_rt_desc.dpiX = (bitmap_size.width * 96.0f) / size->width; - dxgi_rt_desc.dpiY = (bitmap_size.height * 96.0f) / size->height; + render_target->desc.dpiX = (bitmap_size.width * 96.0f) / size->width; + render_target->desc.dpiY = (bitmap_size.height * 96.0f) / size->height; } else { - dxgi_rt_desc.dpiX = parent_target->desc.dpiX; - dxgi_rt_desc.dpiY = parent_target->desc.dpiY; + render_target->desc.dpiX = parent_target->desc.dpiX; + render_target->desc.dpiY = parent_target->desc.dpiY; }
if (!pixel_format || pixel_format->format == DXGI_FORMAT_UNKNOWN) - dxgi_rt_desc.pixelFormat.format = parent_target->desc.pixelFormat.format; + render_target->desc.pixelFormat.format = parent_target->desc.pixelFormat.format; else - dxgi_rt_desc.pixelFormat.format = pixel_format->format; + render_target->desc.pixelFormat.format = pixel_format->format;
if (!pixel_format || pixel_format->alphaMode == D2D1_ALPHA_MODE_UNKNOWN) - dxgi_rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + render_target->desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; else - dxgi_rt_desc.pixelFormat.alphaMode = pixel_format->alphaMode; + render_target->desc.pixelFormat.alphaMode = pixel_format->alphaMode;
if (FAILED(hr = d2d_d3d_create_render_target(parent_target->device, NULL, (IUnknown *)&render_target->ID2D1BitmapRenderTarget_iface, parent_target->ops ? &d2d_bitmap_render_target_ops : NULL, - &dxgi_rt_desc, (void **)&render_target->dxgi_inner))) + &render_target->desc, (void **)&render_target->dxgi_inner))) { WARN("Failed to create DXGI surface render target, hr %#lx.\n", hr); return hr; @@ -803,9 +837,9 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta return hr; }
- bitmap_desc.pixelFormat = dxgi_rt_desc.pixelFormat; - bitmap_desc.dpiX = dxgi_rt_desc.dpiX; - bitmap_desc.dpiY = dxgi_rt_desc.dpiY; + bitmap_desc.pixelFormat = render_target->desc.pixelFormat; + bitmap_desc.dpiX = render_target->desc.dpiX; + bitmap_desc.dpiY = render_target->desc.dpiY; bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET; bitmap_desc.colorContext = NULL;
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 0206f474dbe..f5d939126e3 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -275,6 +275,8 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target struct d2d_bitmap_render_target { ID2D1BitmapRenderTarget ID2D1BitmapRenderTarget_iface; + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options; + D2D1_RENDER_TARGET_PROPERTIES desc; LONG refcount;
ID2D1RenderTarget *dxgi_target; diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 72781a48d10..eeb5f92962a 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -4448,6 +4448,8 @@ HRESULT d2d_d3d_create_render_target(ID2D1Device *device, IDXGISurface *surface, return hr; }
+ object->desc.type = desc->type; + object->desc.usage = desc->usage; ID2D1DeviceContext1_SetDpi(&object->ID2D1DeviceContext1_iface, bitmap_desc.dpiX, bitmap_desc.dpiY);
if (surface)
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/d2d1/tests/d2d1.c | 355 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 6441f239af9..4ee8fc3c426 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -13806,6 +13806,360 @@ static void test_dc_target_is_supported(void) DestroyWindow(window); }
+static void test_bitmap_target_is_supported(void) +{ + static const DWORD levels[] = {D2D1_FEATURE_LEVEL_DEFAULT, D2D1_FEATURE_LEVEL_9, D2D1_FEATURE_LEVEL_10}; + D2D1_RENDER_TARGET_PROPERTIES desc, template_desc, test_desc; + D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc; + D2D1_BITMAP_PROPERTIES1 bitmap_desc; + ID2D1BitmapRenderTarget *bitmap_rt; + ID2D1DeviceContext *device_context; + D2D1_PIXEL_FORMAT pixel_format; + ID2D1HwndRenderTarget *hwnd_rt; + ID2D1Factory *factory; + ID2D1Bitmap1 *bitmap; + unsigned int i, j; + D2D1_SIZE_U size; + BOOL supported; + HWND window; + HRESULT hr; + + window = create_window(); + ok(!!window, "Failed to create test window.\n"); + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + template_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + template_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN; + template_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN; + template_desc.dpiX = 96.0f; + template_desc.dpiY = 96.0f; + template_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + template_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + hwnd_rt_desc.hwnd = window; + hwnd_rt_desc.pixelSize.width = 64; + hwnd_rt_desc.pixelSize.height = 64; + hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE; + + /* Make sure the render target description template is valid */ + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &template_desc, &hwnd_rt_desc, &hwnd_rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &template_desc); + ok(supported, "Expected supported.\n"); + ID2D1BitmapRenderTarget_Release(bitmap_rt); + ID2D1HwndRenderTarget_Release(hwnd_rt); + + /* Test that SetTarget() with a bitmap of a different usage doesn't change the render target usage */ + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &template_desc, &hwnd_rt_desc, &hwnd_rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1BitmapRenderTarget_QueryInterface(bitmap_rt, &IID_ID2D1DeviceContext, (void **)&device_context); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + test_desc = template_desc; + test_desc.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &test_desc); + ok(!supported, "Expected unsupported.\n"); + + memset(&bitmap_desc, 0, sizeof(bitmap_desc)); + bitmap_desc.pixelFormat = ID2D1DeviceContext_GetPixelFormat(device_context); + bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE; + size.width = 4; + size.height = 4; + hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap); + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &test_desc); + ok(!supported, "Expected unsupported.\n"); + ID2D1Bitmap1_Release(bitmap); + + /* Test that SetTarget() with a bitmap of a different format changes the render target format */ + test_desc = template_desc; + test_desc.pixelFormat.format = DXGI_FORMAT_R8G8B8A8_UNORM; + test_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &test_desc); + ok(!supported, "Expected unsupported.\n"); + + memset(&bitmap_desc, 0, sizeof(bitmap_desc)); + bitmap_desc.pixelFormat.format = DXGI_FORMAT_R8G8B8A8_UNORM; + bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET; + size.width = 4; + size.height = 4; + hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap); + pixel_format = ID2D1DeviceContext_GetPixelFormat(device_context); + ok(pixel_format.format == DXGI_FORMAT_R8G8B8A8_UNORM, "Got unexpected format %#x.\n", pixel_format.format); + ok(pixel_format.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED, "Got unexpected alpha %u.\n", pixel_format.alphaMode); + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &test_desc); + ok(supported, "Expected supported.\n"); + ID2D1Bitmap1_Release(bitmap); + + ID2D1DeviceContext_Release(device_context); + ID2D1BitmapRenderTarget_Release(bitmap_rt); + ID2D1HwndRenderTarget_Release(hwnd_rt); + + /* Type */ + for (i = D2D1_RENDER_TARGET_TYPE_DEFAULT; i <= D2D1_RENDER_TARGET_TYPE_HARDWARE; ++i) + { + desc = template_desc; + desc.type = i; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &hwnd_rt); + if (FAILED(hr)) + continue; + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + for (j = D2D1_RENDER_TARGET_TYPE_DEFAULT; j <= D2D1_RENDER_TARGET_TYPE_HARDWARE; ++j) + { + winetest_push_context("type %u test %u", i, j); + + test_desc = template_desc; + test_desc.type = j; + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &test_desc); + if (i == j || (i == D2D1_RENDER_TARGET_TYPE_DEFAULT && j == D2D1_RENDER_TARGET_TYPE_HARDWARE) + || (i == D2D1_RENDER_TARGET_TYPE_HARDWARE && j == D2D1_RENDER_TARGET_TYPE_DEFAULT) + || (i == D2D1_RENDER_TARGET_TYPE_SOFTWARE && j == D2D1_RENDER_TARGET_TYPE_DEFAULT)) + ok(supported || broken(i == D2D1_RENDER_TARGET_TYPE_DEFAULT + && j == D2D1_RENDER_TARGET_TYPE_HARDWARE) /* Win7 */, "Expected supported.\n"); + else + ok(!supported || broken(i == D2D1_RENDER_TARGET_TYPE_DEFAULT + && j == D2D1_RENDER_TARGET_TYPE_SOFTWARE) /* Win7 */, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1BitmapRenderTarget_Release(bitmap_rt); + ID2D1HwndRenderTarget_Release(hwnd_rt); + } + + /* Pixel DXGI format */ + for (i = DXGI_FORMAT_UNKNOWN; i <= DXGI_FORMAT_V408; ++i) + { + if (i > DXGI_FORMAT_B4G4R4A4_UNORM && i < DXGI_FORMAT_P208) + continue; + + desc = template_desc; + desc.pixelFormat.format = i; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &hwnd_rt); + if (FAILED(hr)) + continue; + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt); + todo_wine_if(hr == D2DERR_UNSUPPORTED_PIXEL_FORMAT) + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + continue; + + for (j = DXGI_FORMAT_UNKNOWN; j <= DXGI_FORMAT_V408; ++j) + { + if (j > DXGI_FORMAT_B4G4R4A4_UNORM && j < DXGI_FORMAT_P208) + continue; + + winetest_push_context("format %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.pixelFormat.format = j; + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &test_desc); + if (i == j || (i == DXGI_FORMAT_UNKNOWN && j == DXGI_FORMAT_B8G8R8A8_UNORM) + || (i == DXGI_FORMAT_B8G8R8A8_UNORM && j == DXGI_FORMAT_UNKNOWN) + || (i == DXGI_FORMAT_R8G8B8A8_UNORM && j == DXGI_FORMAT_UNKNOWN)) + ok(supported, "Expected supported.\n"); + else + ok(!supported, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1BitmapRenderTarget_Release(bitmap_rt); + ID2D1HwndRenderTarget_Release(hwnd_rt); + } + + /* Pixel alpha mode */ + for (i = D2D1_ALPHA_MODE_UNKNOWN; i <= D2D1_ALPHA_MODE_IGNORE; ++i) + { + desc = template_desc; + desc.pixelFormat.alphaMode = i; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &hwnd_rt); + if (FAILED(hr)) + continue; + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + for (j = D2D1_ALPHA_MODE_UNKNOWN; j <= D2D1_ALPHA_MODE_IGNORE; ++j) + { + winetest_push_context("alpha %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.pixelFormat.alphaMode = j; + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &test_desc); + if (j == D2D1_ALPHA_MODE_UNKNOWN || j == D2D1_ALPHA_MODE_PREMULTIPLIED) + ok(supported, "Expected supported.\n"); + else + ok(!supported, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1BitmapRenderTarget_Release(bitmap_rt); + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, + &desc.pixelFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt); + todo_wine_if(hr == D2DERR_UNSUPPORTED_PIXEL_FORMAT) + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + { + ID2D1HwndRenderTarget_Release(hwnd_rt); + continue; + } + + for (j = D2D1_ALPHA_MODE_UNKNOWN; j <= D2D1_ALPHA_MODE_IGNORE; ++j) + { + winetest_push_context("alpha %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.pixelFormat.alphaMode = j; + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &test_desc); + if (((i == D2D1_ALPHA_MODE_UNKNOWN || i == D2D1_ALPHA_MODE_PREMULTIPLIED) + && (j == D2D1_ALPHA_MODE_UNKNOWN || j == D2D1_ALPHA_MODE_PREMULTIPLIED)) + || (i == D2D1_ALPHA_MODE_IGNORE && (j == D2D1_ALPHA_MODE_IGNORE || j == D2D1_ALPHA_MODE_UNKNOWN))) + ok(supported, "Expected supported.\n"); + else + ok(!supported, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1BitmapRenderTarget_Release(bitmap_rt); + ID2D1HwndRenderTarget_Release(hwnd_rt); + } + + /* DPI */ + for (i = 0; i <= 192; i += 96) + { + desc = template_desc; + desc.dpiX = i; + desc.dpiY = i; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &hwnd_rt); + if (FAILED(hr)) + continue; + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + for (j = 0; j <= 192; j += 96) + { + winetest_push_context("dpi %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.dpiX = j; + test_desc.dpiY = j; + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &test_desc); + ok(supported, "Expected supported.\n"); + + winetest_pop_context(); + } + + ID2D1BitmapRenderTarget_Release(bitmap_rt); + ID2D1HwndRenderTarget_Release(hwnd_rt); + } + + /* Usage */ + for (i = D2D1_RENDER_TARGET_USAGE_NONE; i <= D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; ++i) + { + desc = template_desc; + desc.usage = i; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &hwnd_rt); + if (FAILED(hr)) + continue; + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + for (j = D2D1_RENDER_TARGET_USAGE_NONE; j <= D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; ++j) + { + winetest_push_context("usage %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.usage = j; + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &test_desc); + if (j == D2D1_RENDER_TARGET_USAGE_NONE + || (i == D2D1_RENDER_TARGET_USAGE_FORCE_BITMAP_REMOTING + && j == D2D1_RENDER_TARGET_USAGE_FORCE_BITMAP_REMOTING)) + ok(supported, "Expected supported.\n"); + else + ok(!supported, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1BitmapRenderTarget_Release(bitmap_rt); + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, &bitmap_rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + for (j = D2D1_RENDER_TARGET_USAGE_NONE; j <= D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; ++j) + { + winetest_push_context("usage %#x test %#x", i, j); + + test_desc = template_desc; + test_desc.usage = j; + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &test_desc); + if (j == D2D1_RENDER_TARGET_USAGE_NONE + || j == D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE + || (i == D2D1_RENDER_TARGET_USAGE_FORCE_BITMAP_REMOTING + && j == D2D1_RENDER_TARGET_USAGE_FORCE_BITMAP_REMOTING)) + ok(supported, "Expected supported.\n"); + else + ok(!supported, "Expected unsupported.\n"); + + winetest_pop_context(); + } + + ID2D1BitmapRenderTarget_Release(bitmap_rt); + ID2D1HwndRenderTarget_Release(hwnd_rt); + } + + /* Min level */ + for (i = 0; i < ARRAY_SIZE(levels); ++i) + { + desc = template_desc; + desc.minLevel = levels[i]; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &hwnd_rt); + if (FAILED(hr)) + continue; + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + for (j = 0; j < ARRAY_SIZE(levels); ++j) + { + winetest_push_context("level %#lx test %#lx", levels[i], levels[j]); + + test_desc = template_desc; + test_desc.minLevel = levels[j]; + supported = ID2D1BitmapRenderTarget_IsSupported(bitmap_rt, &test_desc); + ok(supported || broken(j != D2D1_FEATURE_LEVEL_DEFAULT) /* Win7 */, "Expected supported.\n"); + + winetest_pop_context(); + } + + ID2D1BitmapRenderTarget_Release(bitmap_rt); + ID2D1HwndRenderTarget_Release(hwnd_rt); + } + + ID2D1Factory_Release(factory); + DestroyWindow(window); +} + static void test_is_supported(BOOL d3d11) { struct d2d1_test_context ctx; @@ -13816,6 +14170,7 @@ static void test_is_supported(BOOL d3d11)
test_hwnd_target_is_supported(); test_dc_target_is_supported(); + test_bitmap_target_is_supported(); }
START_TEST(d2d1)
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=125890
Your paranoid android.
=== debian11b (32 bit WoW report) ===
d2d1: Unhandled exception: page fault on write access to 0x00000000 in 32-bit code (0x6ab30f94).
Nikolay Sivov (@nsivov) commented about dlls/d2d1/hwnd_render_target.c:
- pixel_format = ID2D1RenderTarget_GetPixelFormat(render_target->dxgi_target);
- if (!(pixel_format.format == desc->pixelFormat.format
|| (pixel_format.format == DXGI_FORMAT_UNKNOWN
&& desc->pixelFormat.format == DXGI_FORMAT_B8G8R8A8_UNORM)
|| (pixel_format.format == DXGI_FORMAT_B8G8R8A8_UNORM
&& desc->pixelFormat.format == DXGI_FORMAT_UNKNOWN)
|| (pixel_format.format == DXGI_FORMAT_R8G8B8A8_UNORM
&& desc->pixelFormat.format == DXGI_FORMAT_UNKNOWN)))
return FALSE;
- if (!(pixel_format.alphaMode == desc->pixelFormat.alphaMode
|| desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_UNKNOWN
|| (pixel_format.alphaMode == D2D1_ALPHA_MODE_UNKNOWN
&& desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE)))
return FALSE;
This does not look good. Are original description fields important after target is created? I think we should store modified values, after _UNKNOWN values are resolved. Then pass input desc argument of IsSupported() through same resolution process, and then compare with a simple equality.
Regarding target type, I think HW/SW are treated as hard requirements on Windows, is that right? E.g. if there is no hardware device, asking for TYPE_HARDWARE will fail. Default type means try hw, then sw if failed. So does it make a difference if target was created with DEFAULT that resolved to HW, or if it was created with HW type directly?
I finally had spent some time on this, and I do think it should be greatly simplified. See attached diff, on top of this MR. With it I get some failures running on Wine, and that's because of how we handle DEFAULT target type - it should be resolved to either HW or SW. The thing is that on Windows without physical GPU you still get two adapters, one marked software. Another failure I get is for supported formats, and for that on Windows, I get only two formats working - DXGI_FORMAT_R8G8B8A8_UNORM and DXGI_FORMAT_B8G8R8A8_UNORM, anything else fails.
I'll take a look at other target types next, @zhiyi let me know what you think. Tests should be also reduced, for example we don't need to iterate over large number of possible formats, I don't think it's useful.
[0001-d2d-hwnd_target-Simplify-IsSupported.txt](/uploads/db2d7523f532ebe577e42e7a23625d43/0001-d2d-hwnd_target-Simplify-IsSupported.txt)
Attaching updated variant that handles usages being a mask. [0001-d2d-Simplify-IsSupported.txt](/uploads/a9266c6feead1395ad5dc4ae97b5f2b2/0001-d2d-Simplify-IsSupported.txt)
This is much better. Thanks for looking into this.
There is also the WIC render target. Can it be simplified as well? Please see https://gitlab.winehq.org/zhiyi/wine/-/commit/ca736a573b9d6b55b5483cb4dff028... at https://gitlab.winehq.org/zhiyi/wine/-/commits/dev
On Tue May 16 11:07:14 2023 +0000, Zhiyi Zhang wrote:
There is also the WIC render target. Can it be simplified as well? Please see https://gitlab.winehq.org/zhiyi/wine/-/commit/ca736a573b9d6b55b5483cb4dff028... at https://gitlab.winehq.org/zhiyi/wine/-/commits/dev
For WIC one, dealing with WIC format directly looks suspicious. I think what needs to happen is we need to store same description as for other targets, after resolving WIC format to corresponding pixel format. That will handle alpha mode as well. I don't know what's going on with feature levels, but we are not handling this correctly right now anyway.
First part submitted as !2836.
This merge request was closed by Zhiyi Zhang.