This should reflect what we actually support, while still being a superset of what native drivers actually support.
Native driver support varies, but, as the comments document, native drivers (at least as of windows 10) support only RGB -> RGB, YUV -> RGB, and BC -> RGB conversions. The actual formats supported are a more limited subset than exposed (despite that the video cards should be perfectly capable of supporting more conversions) but erring on the side of overreporting seems safer.
From: Elizabeth Figura zfigura@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44888 --- dlls/d3d9/directx.c | 3 + dlls/d3d9/tests/visual.c | 135 +++++++++++++++++++++++++++++++++++++++ dlls/wined3d/directx.c | 43 +++++++++++-- 3 files changed, 176 insertions(+), 5 deletions(-)
diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c index d5b8e276075..13d32b00680 100644 --- a/dlls/d3d9/directx.c +++ b/dlls/d3d9/directx.c @@ -414,6 +414,9 @@ static HRESULT WINAPI d3d9_CheckDeviceFormatConversion(IDirect3D9Ex *iface, UINT if (output_idx >= d3d9->wined3d_output_count) return D3DERR_INVALIDCALL;
+ if (src_format == dst_format) + return S_OK; + wined3d_mutex_lock(); hr = wined3d_check_device_format_conversion(d3d9->wined3d_outputs[output_idx], wined3d_device_type_from_d3d(device_type), wined3dformat_from_d3dformat(src_format), diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index e924588630e..da298d1e605 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -28682,6 +28682,140 @@ static void test_default_attribute_components(void) release_test_context(&context); }
+static void test_format_conversion(void) +{ + D3DADAPTER_IDENTIFIER9 identifier; + struct d3d9_test_context context; + HRESULT hr; + + static const struct + { + D3DFORMAT src_format; + D3DFORMAT dst_format; + HRESULT expect_hr; + bool broken_warp; + } + tests[] = + { + {D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, S_OK}, + {D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, S_OK}, + {D3DFMT_R5G6B5, D3DFMT_X8R8G8B8, S_OK}, + {D3DFMT_YUY2, D3DFMT_X8R8G8B8, S_OK, .broken_warp = true}, + {D3DFMT_YUY2, D3DFMT_R5G6B5, S_OK, .broken_warp = true}, + {D3DFMT_R32F, D3DFMT_R16F, D3DERR_NOTAVAILABLE}, + + {D3DFMT_L8, D3DFMT_L8, S_OK}, + {D3DFMT_X8R8G8B8, D3DFMT_L8, D3DERR_NOTAVAILABLE}, + {D3DFMT_A8, D3DFMT_L8, D3DERR_NOTAVAILABLE}, + {D3DFMT_A8L8, D3DFMT_L8, D3DERR_NOTAVAILABLE}, + {D3DFMT_L16, D3DFMT_L8, D3DERR_NOTAVAILABLE}, + {D3DFMT_L8, D3DFMT_A8, D3DERR_NOTAVAILABLE}, + {D3DFMT_L8, D3DFMT_L16, D3DERR_NOTAVAILABLE}, + {D3DFMT_L8, D3DFMT_A8L8, D3DERR_NOTAVAILABLE}, + }; + + static const D3DFORMAT all_formats[] = + { + D3DFMT_R8G8B8, + D3DFMT_A8R8G8B8, + D3DFMT_X8R8G8B8, + D3DFMT_R5G6B5, + D3DFMT_X1R5G5B5, + D3DFMT_A1R5G5B5, + D3DFMT_A4R4G4B4, + D3DFMT_R3G3B2, + D3DFMT_A8, + D3DFMT_A8R3G3B2, + D3DFMT_X4R4G4B4, + D3DFMT_A2B10G10R10, + D3DFMT_A8B8G8R8, + D3DFMT_X8B8G8R8, + D3DFMT_G16R16, + D3DFMT_A2R10G10B10, + D3DFMT_A16B16G16R16, + D3DFMT_A8P8, + D3DFMT_P8, + D3DFMT_L8, + D3DFMT_A8L8, + D3DFMT_A4L4, + D3DFMT_V8U8, + D3DFMT_L6V5U5, + D3DFMT_X8L8V8U8, + D3DFMT_Q8W8V8U8, + D3DFMT_V16U16, + D3DFMT_A2W10V10U10, + D3DFMT_UYVY, + D3DFMT_YUY2, + D3DFMT_DXT1, + D3DFMT_DXT2, + D3DFMT_DXT3, + D3DFMT_DXT4, + D3DFMT_DXT5, + D3DFMT_MULTI2_ARGB8, + D3DFMT_G8R8_G8B8, + D3DFMT_R8G8_B8G8, + D3DFMT_D16_LOCKABLE, + D3DFMT_D32, + D3DFMT_D15S1, + D3DFMT_D24S8, + D3DFMT_D24X8, + D3DFMT_D24X4S4, + D3DFMT_D16, + D3DFMT_L16, + D3DFMT_D32F_LOCKABLE, + D3DFMT_D24FS8, + D3DFMT_D32_LOCKABLE, + D3DFMT_S8_LOCKABLE, + D3DFMT_VERTEXDATA, + D3DFMT_INDEX16, + D3DFMT_INDEX32, + D3DFMT_Q16W16V16U16, + D3DFMT_R16F, + D3DFMT_G16R16F, + D3DFMT_A16B16G16R16F, + D3DFMT_R32F, + D3DFMT_G32R32F, + D3DFMT_A32B32G32R32F, + D3DFMT_CxV8U8, + D3DFMT_A1, + D3DFMT_A2B10G10R10_XR_BIAS, + D3DFMT_BINARYBUFFER, + 200, + }; + + if (!init_test_context(&context)) + return; + + hr = IDirect3D9_GetAdapterIdentifier(context.d3d, D3DADAPTER_DEFAULT, 0, &identifier); + ok(hr == S_OK, "Failed to get adapter identifier, hr %#lx.\n", hr); + + for (unsigned int i = 0; i < ARRAY_SIZE(tests); ++i) + { + hr = IDirect3D9_CheckDeviceFormatConversion(context.d3d, D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, tests[i].src_format, tests[i].dst_format); + ok(hr == tests[i].expect_hr + || broken(adapter_is_warp(&identifier) && hr == D3DERR_NOTAVAILABLE), + "Got hr %#lx for %u to %u.\n", hr, tests[i].src_format, tests[i].dst_format); + } + + for (D3DFORMAT src_format = 0; src_format < ARRAY_SIZE(all_formats); ++src_format) + { + for (D3DFORMAT dst_format = 0; dst_format < ARRAY_SIZE(all_formats); ++dst_format) + { + hr = IDirect3D9_CheckDeviceFormatConversion(context.d3d, D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, all_formats[src_format], all_formats[dst_format]); + if (src_format == dst_format) + ok(hr == S_OK, "Got hr %#lx for %u to %u.\n", + hr, all_formats[src_format], all_formats[dst_format]); + else + ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE, "Got hr %#lx for %u to %u.\n", + hr, all_formats[src_format], all_formats[dst_format]); + } + } + + release_test_context(&context); +} + START_TEST(visual) { D3DADAPTER_IDENTIFIER9 identifier; @@ -28838,4 +28972,5 @@ START_TEST(visual) test_mipmap_upload(); test_default_diffuse(); test_default_attribute_components(); + test_format_conversion(); } diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 9df95bdea55..f236a59f963 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2184,12 +2184,45 @@ unsigned int CDECL wined3d_calculate_format_pitch(const struct wined3d_adapter * }
HRESULT CDECL wined3d_check_device_format_conversion(const struct wined3d_output *output, - enum wined3d_device_type device_type, enum wined3d_format_id src_format, - enum wined3d_format_id dst_format) + enum wined3d_device_type device_type, enum wined3d_format_id src_format_id, + enum wined3d_format_id dst_format_id) { - FIXME("output %p, device_type %s, src_format %s, dst_format %s stub!\n", - output, debug_d3ddevicetype(device_type), debug_d3dformat(src_format), - debug_d3dformat(dst_format)); + const struct wined3d_format *src_format = wined3d_get_format(output->adapter, src_format_id, 0); + const struct wined3d_format *dst_format = wined3d_get_format(output->adapter, dst_format_id, 0); + + TRACE("output %p, device_type %s, src_format %s, dst_format %s.\n", + output, debug_d3ddevicetype(device_type), debug_d3dformat(src_format_id), + debug_d3dformat(dst_format_id)); + + if (!(src_format->caps[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3D_FORMAT_CAP_BLIT)) + { + TRACE("Source format does not support blitting.\n"); + return WINED3DERR_NOTAVAILABLE; + } + + if (!(dst_format->caps[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3D_FORMAT_CAP_BLIT)) + { + TRACE("Destination format does not support blitting.\n"); + return WINED3DERR_NOTAVAILABLE; + } + + /* Source cannot be depth/stencil (although it can be YUV or compressed, + * and AMD also allows blitting from luminance formats). */ + if (src_format->depth_size || src_format->stencil_size) + { + TRACE("Source format is depth/stencil.\n"); + return WINED3DERR_NOTAVAILABLE; + } + + /* The destination format must be a simple RGB format (no luminance, YUV, + * compression, etc.) All such formats have a nonzero red_size; the only + * exceptions are X24G8 (not supported in d3d9) and A8 (which, it turns out, + * no vendor reports support for converting to). */ + if (!dst_format->red_size) + { + TRACE("Destination format is not a simple RGB format.\n"); + return WINED3DERR_NOTAVAILABLE; + }
return WINED3D_OK; }
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=146188
Your paranoid android.
=== debian11 (32 bit report) ===
d3d9: visual.c:28796: Test failed: Got hr 0 for 114 to 111.
=== debian11 (32 bit ar:MA report) ===
d3d9: visual.c:28796: Test failed: Got hr 0 for 114 to 111.
=== debian11 (32 bit de report) ===
d3d9: visual.c:28796: Test failed: Got hr 0 for 114 to 111.
=== debian11 (32 bit fr report) ===
d3d9: visual.c:28796: Test failed: Got hr 0 for 114 to 111.
=== debian11 (32 bit he:IL report) ===
d3d9: visual.c:28796: Test failed: Got hr 0 for 114 to 111.
=== debian11 (32 bit hi:IN report) ===
d3d9: visual.c:28796: Test failed: Got hr 0 for 114 to 111.
=== debian11 (32 bit ja:JP report) ===
d3d9: visual.c:28796: Test failed: Got hr 0 for 114 to 111.
=== debian11 (32 bit zh:CN report) ===
d3d9: visual.c:28796: Test failed: Got hr 0 for 114 to 111.
=== debian11b (32 bit WoW report) ===
d3d9: visual.c:28796: Test failed: Got hr 0 for 114 to 111.
=== debian11b (64 bit WoW report) ===
d3d9: visual.c:28796: Test failed: Got hr 0 for 114 to 111.