1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-01 07:14:31 +00:00

wined3d: Implement wined3d_check_device_format_conversion().

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44888
This commit is contained in:
Elizabeth Figura 2024-06-08 19:13:14 -05:00 committed by Alexandre Julliard
parent fe3a33baec
commit d8379aa2cc
3 changed files with 177 additions and 5 deletions

View File

@ -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),

View File

@ -28682,6 +28682,141 @@ 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);
todo_wine_if (i == 5)
ok(hr == tests[i].expect_hr
|| broken(tests[i].broken_warp && 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 (unsigned int src_format = 0; src_format < ARRAY_SIZE(all_formats); ++src_format)
{
for (unsigned int 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 +28973,5 @@ START_TEST(visual)
test_mipmap_upload();
test_default_diffuse();
test_default_attribute_components();
test_format_conversion();
}

View File

@ -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;
}