Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=35194 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=25486 Signed-off-by: Paul Gofman gofmanp@gmail.com --- v2: - perform alpha fixup in wined3d_texture_gl_upload_data().
dlls/ddraw/tests/ddraw7.c | 6 +-- dlls/wined3d/texture.c | 83 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 83 insertions(+), 6 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 1592d2e081..7f2c3e9751 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -16621,11 +16621,11 @@ static void test_surface_format_conversion_alpha(void) {FMT_R5G5B5X1, r5g5b5x1_data, FMT_R5G5B5A1, r5g5b5x1_data, TRUE}, {FMT_R5G5B5A1, r5g5b5a1_data, FMT_R5G6B5, r5g6b5_data}, {FMT_RGBA, rgba_data, FMT_DXT1, dxt1_data}, - {FMT_RGBX, rgbx_data, FMT_DXT1, dxt1_data, TRUE}, + {FMT_RGBX, rgbx_data, FMT_DXT1, dxt1_data}, {FMT_RGBA, rgba_data, FMT_DXT2, dxt2_data}, - {FMT_RGBX, rgbx_data, FMT_DXT2, dxt2_data, TRUE}, + {FMT_RGBX, rgbx_data, FMT_DXT2, dxt2_data}, {FMT_RGBA, rgba_data, FMT_DXT3, dxt2_data}, - {FMT_RGBX, rgbx_data, FMT_DXT3, dxt2_data, TRUE}, + {FMT_RGBX, rgbx_data, FMT_DXT3, dxt2_data}, {FMT_DXT1, dxt1_data, FMT_DXT2, dxt2_data}, {FMT_DXT1, dxt1_data, FMT_RGBA, rgba_data}, {FMT_DXT1, dxt1_data, FMT_RGBX, rgba_data}, diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 8d3c25cf15..a7b835e503 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1963,6 +1963,73 @@ static void wined3d_texture_gl_upload_bo(const struct wined3d_format *src_format } }
+static const struct d3dfmt_alpha_fixup +{ + enum wined3d_format_id format_id, conv_format_id; +} +formats_src_alpha_fixup[] = +{ + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_B8G8R8A8_UNORM}, + {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_B5G5R5A1_UNORM}, + {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_B4G4R4A4_UNORM}, +}; + +static enum wined3d_format_id wined3d_get_alpha_fixup_format(enum wined3d_format_id format_id, + const struct wined3d_format *dst_format) +{ + unsigned int i; + + if (!(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED) + && !dst_format->alpha_size) + return WINED3DFMT_UNKNOWN; + + for (i = 0; i < ARRAY_SIZE(formats_src_alpha_fixup); ++i) + if (formats_src_alpha_fixup[i].format_id == format_id) + return formats_src_alpha_fixup[i].conv_format_id; + + return WINED3DFMT_UNKNOWN; +} + +static void wined3d_fixup_alpha(const struct wined3d_format *format, const BYTE *src_addr, + unsigned int src_row_pitch, BYTE *dst_addr, unsigned int dst_row_pitch, + unsigned int width, unsigned int height) +{ + unsigned int byte_count, alpha_mask; + unsigned int x, y; + + byte_count = format->byte_count; + alpha_mask = ((1u << format->alpha_size) - 1) << format->alpha_offset; + + for (y = 0; y < height; ++y) + { + switch(byte_count) + { + case 2: + { + unsigned short *dst = (unsigned short *)(dst_addr + y * dst_row_pitch); + unsigned short *src = (unsigned short *)(src_addr + y * src_row_pitch); + + for (x = 0; x < width; ++x) + dst[x] = src[x] | alpha_mask; + + break; + } + case 4: + { + unsigned int *dst = (unsigned int *)(dst_addr + y * dst_row_pitch); + unsigned int *src = (unsigned int *)(src_addr + y * src_row_pitch); + + for (x = 0; x < width; ++x) + dst[x] = src[x] | alpha_mask; + + break; + } + default: + ERR("Unsupported byte count %u.\n", byte_count); + } + } +} + static void wined3d_texture_gl_upload_data(struct wined3d_context *context, const struct wined3d_const_bo_address *src_bo_addr, const struct wined3d_format *src_format, const struct wined3d_box *src_box, unsigned int src_row_pitch, unsigned int src_slice_pitch, @@ -1970,17 +2037,17 @@ static void wined3d_texture_gl_upload_data(struct wined3d_context *context, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z) { struct wined3d_context_gl *context_gl = wined3d_context_gl(context); + enum wined3d_format_id alpha_fixup_format_id = WINED3DFMT_UNKNOWN; const struct wined3d_gl_info *gl_info = context_gl->gl_info; unsigned int update_w = src_box->right - src_box->left; unsigned int update_h = src_box->bottom - src_box->top; unsigned int update_d = src_box->back - src_box->front; struct wined3d_bo_address bo; unsigned int level; + BOOL srgb = FALSE; BOOL decompress; GLenum target;
- BOOL srgb = FALSE; - TRACE("context %p, src_bo_addr %s, src_format %s, src_box %s, src_row_pitch %u, src_slice_pitch %u, " "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_x %u, dst_y %u, dst_z %u.\n", context, debug_const_bo_address(src_bo_addr), debug_d3dformat(src_format->id), debug_box(src_box), @@ -2046,7 +2113,9 @@ static void wined3d_texture_gl_upload_data(struct wined3d_context *context, decompress = (dst_texture->resource.format_flags & WINED3DFMT_FLAG_DECOMPRESS) || (src_format->decompress && src_format->id != dst_texture->resource.format->id);
- if (src_format->upload || decompress) + if (src_format->upload || decompress + || (alpha_fixup_format_id = wined3d_get_alpha_fixup_format(src_format->id, + dst_texture->resource.format)) != WINED3DFMT_UNKNOWN) { const struct wined3d_format *compressed_format = src_format; unsigned int dst_row_pitch, dst_slice_pitch; @@ -2059,6 +2128,11 @@ static void wined3d_texture_gl_upload_data(struct wined3d_context *context, { src_format = wined3d_resource_get_decompress_format(&dst_texture->resource); } + else if (alpha_fixup_format_id != WINED3DFMT_UNKNOWN) + { + src_format = wined3d_get_format(context->device->adapter, alpha_fixup_format_id, 0); + assert(!!src_format); + } else { if (dst_texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) @@ -2085,6 +2159,9 @@ static void wined3d_texture_gl_upload_data(struct wined3d_context *context, if (decompress) compressed_format->decompress(src_mem, converted_mem, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch, update_w, update_h, 1); + else if (alpha_fixup_format_id != WINED3DFMT_UNKNOWN) + wined3d_fixup_alpha(src_format, src_mem, src_row_pitch, converted_mem, dst_row_pitch, + update_w, update_h); else src_format->upload(src_mem, converted_mem, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch, update_w, update_h, 1);
Signed-off-by: Paul Gofman gofmanp@gmail.com --- v2: - no changes.
dlls/ddraw/tests/ddraw7.c | 142 ++++++++++++++++++++++++-------------- 1 file changed, 89 insertions(+), 53 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 7f2c3e9751..12d330c123 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -16539,6 +16539,7 @@ static void test_surface_format_conversion_alpha(void) const char *name; unsigned int block_size, x_blocks, y_blocks; DWORD support_flag; + BOOL broken_software_blit; } formats[] = { @@ -16561,7 +16562,10 @@ static void test_surface_format_conversion_alpha(void) sizeof(DDPIXELFORMAT), DDPF_RGB, 0, {16}, {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000} }, - "R5G6B5", 2, 4, 4, + "R5G6B5", 2, 4, 4, 0, TRUE, + /* Looks broken for sysmem texture convertions on Windows (at least with hardware + * device), the result is either error from _Blt() or a copy of the source data + * without any conversion. */ }, { { @@ -16600,6 +16604,18 @@ static void test_surface_format_conversion_alpha(void) }, };
+ static const struct + { + DWORD src_caps, dst_caps; + } + test_caps[] = + { + {DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY}, + {DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY, DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY}, + {DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY}, + {DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY}, + }; + static const struct { enum test_format_id src_format; @@ -16636,11 +16652,12 @@ static void test_surface_format_conversion_alpha(void) const struct test_format *src_format, *dst_format; IDirectDrawSurface7 *src_surf, *dst_surf; DDSURFACEDESC2 surface_desc, lock; - unsigned int i, x, y, pitch; + unsigned int i, j, x, y, pitch; IDirect3DDevice7 *device; DWORD supported_fmts; IDirectDraw7 *ddraw; ULONG refcount; + BOOL is_wine; HWND window; BOOL passed; HRESULT hr; @@ -16662,12 +16679,13 @@ static void test_surface_format_conversion_alpha(void) &supported_fmts); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ is_wine = !strcmp(winetest_platform, "wine"); + memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; surface_desc.dwWidth = 4; surface_desc.dwHeight = 4; - surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
for (i = 0; i < ARRAY_SIZE(tests); ++i) { @@ -16685,63 +16703,81 @@ static void test_surface_format_conversion_alpha(void) continue; }
- U4(surface_desc).ddpfPixelFormat = src_format->fmt; - hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &src_surf, NULL); - ok(hr == DD_OK, "Test %u, got unexpected hr %#x.\n", i, hr); - - U4(surface_desc).ddpfPixelFormat = dst_format->fmt; - hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &dst_surf, NULL); - ok(hr == DD_OK, "Test %u, got unexpected hr %#x.\n", i, hr); - - memset(&lock, 0, sizeof(lock)); - lock.dwSize = sizeof(lock); - hr = IDirectDrawSurface7_Lock(src_surf, NULL, &lock, 0, NULL); - ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - pitch = U1(lock).lPitch; - for (y = 0; y < src_format->y_blocks; ++y) - memcpy((BYTE*)lock.lpSurface + y * pitch, - (BYTE *)tests[i].src_data + y * src_format->x_blocks * src_format->block_size, - src_format->block_size * src_format->x_blocks); - hr = IDirectDrawSurface7_Unlock(src_surf, NULL); - ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + for (j = 0; j < ARRAY_SIZE(test_caps); ++j) + { + if (!is_wine && ((test_caps[j].src_caps | test_caps[j].dst_caps) & DDSCAPS_SYSTEMMEMORY) + && (src_format->broken_software_blit || dst_format->broken_software_blit)) + continue;
- hr = IDirectDrawSurface7_Blt(dst_surf, NULL, src_surf, NULL, DDBLT_WAIT, NULL); - ok(hr == DD_OK, "Test %s -> %s, got unexpected hr %#x.\n", - src_format->name, dst_format->name, hr); + U4(surface_desc).ddpfPixelFormat = src_format->fmt; + surface_desc.ddsCaps.dwCaps = test_caps[j].src_caps; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &src_surf, NULL); + ok(hr == DD_OK, "Test (%u, %u), got unexpected hr %#x.\n", j, i, hr); + + U4(surface_desc).ddpfPixelFormat = dst_format->fmt; + surface_desc.ddsCaps.dwCaps = test_caps[j].dst_caps; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &dst_surf, NULL); + ok(hr == DD_OK, "Test (%u, %u), got unexpected hr %#x.\n", j, i, hr); + + memset(&lock, 0, sizeof(lock)); + lock.dwSize = sizeof(lock); + hr = IDirectDrawSurface7_Lock(src_surf, NULL, &lock, 0, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + pitch = U1(lock).lPitch; + for (y = 0; y < src_format->y_blocks; ++y) + memcpy((BYTE*)lock.lpSurface + y * pitch, + (BYTE *)tests[i].src_data + y * src_format->x_blocks * src_format->block_size, + src_format->block_size * src_format->x_blocks); + hr = IDirectDrawSurface7_Unlock(src_surf, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDrawSurface7_Blt(dst_surf, NULL, src_surf, NULL, DDBLT_WAIT, NULL); + if (!is_wine && FAILED(hr)) + { + /* Some software blits are rejected on Windows. */ + IDirectDrawSurface7_Release(dst_surf); + IDirectDrawSurface7_Release(src_surf); + skip("Skipping test (%u, %u), cannot blit %s -> %s, hr %#x.\n", j, i, + src_format->name, dst_format->name, hr); + continue; + } + ok(hr == DD_OK, "Test (%u, %s -> %s), got unexpected hr %#x.\n", j, + src_format->name, dst_format->name, hr);
- memset(&lock, 0, sizeof(lock)); - lock.dwSize = sizeof(lock); - hr = IDirectDrawSurface7_Lock(dst_surf, NULL, &lock, 0, NULL); - ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - pitch = U1(lock).lPitch; + memset(&lock, 0, sizeof(lock)); + lock.dwSize = sizeof(lock); + hr = IDirectDrawSurface7_Lock(dst_surf, NULL, &lock, 0, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + pitch = U1(lock).lPitch;
- for (y = 0; y < dst_format->y_blocks; ++y) - { - const void *expected_data = tests[i].expected_data; + for (y = 0; y < dst_format->y_blocks; ++y) + { + const void *expected_data = tests[i].expected_data;
- passed = !memcmp((BYTE*)lock.lpSurface + y * pitch, - (BYTE *)expected_data + y * dst_format->x_blocks * dst_format->block_size, - dst_format->block_size * dst_format->x_blocks); - todo_wine_if(tests[i].todo) - ok(passed, "Test %s -> %s, row %u, unexpected surface data.\n", - src_format->name, dst_format->name, y); + passed = !memcmp((BYTE*)lock.lpSurface + y * pitch, + (BYTE *)expected_data + y * dst_format->x_blocks * dst_format->block_size, + dst_format->block_size * dst_format->x_blocks); + todo_wine_if(tests[i].todo) + ok(passed, "Test (%u, %s -> %s), row %u, unexpected surface data.\n", j, + src_format->name, dst_format->name, y);
- if (!passed && !(!strcmp(winetest_platform, "wine") && tests[i].todo)) - { - for (x = 0; x < dst_format->x_blocks * dst_format->block_size / 4; ++x) - trace("Test %u, x %u, y %u, got 0x%08x, expected 0x%08x.\n", i, x, y, - *(unsigned int *)((BYTE *)lock.lpSurface + y * pitch + x * 4), - *(unsigned int *)((BYTE *)expected_data + y * dst_format->x_blocks - * dst_format->block_size + x * 4)); + if (!passed && !(is_wine && tests[i].todo)) + { + for (x = 0; x < dst_format->x_blocks * dst_format->block_size / 4; ++x) + trace("Test (%u, %u), x %u, y %u, got 0x%08x, expected 0x%08x.\n", j, i, x, y, + *(unsigned int *)((BYTE *)lock.lpSurface + y * pitch + x * 4), + *(unsigned int *)((BYTE *)expected_data + y * dst_format->x_blocks + * dst_format->block_size + x * 4)); + } + if (!passed) + break; } - if (!passed) - break; - } - hr = IDirectDrawSurface7_Unlock(dst_surf, NULL); - ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_Unlock(dst_surf, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
- IDirectDrawSurface7_Release(dst_surf); - IDirectDrawSurface7_Release(src_surf); + IDirectDrawSurface7_Release(dst_surf); + IDirectDrawSurface7_Release(src_surf); + } }
IDirect3DDevice7_Release(device);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59872
Your paranoid android.
=== w8adm (32 bit report) ===
ddraw: ddraw7.c:3951: Test failed: Lit quad with light has color 0x00000000. ddraw7.c:3951: Test failed: Lit quad with singular world matrix has color 0x00000000. ddraw7.c:3951: Test failed: Lit quad with transformation matrix has color 0x00000000.
=== w1064v1809 (32 bit report) ===
ddraw: 19d0:ddraw7: unhandled exception c0000005 at 738240F8
=== w1064v1809_2scr (32 bit report) ===
ddraw: 1a60:ddraw7: unhandled exception c0000005 at 74CB40F8
=== w1064v1809_ar (32 bit report) ===
ddraw: 0230:ddraw7: unhandled exception c0000005 at 72CE40F8
=== w1064v1809_he (32 bit report) ===
ddraw: 199c:ddraw7: unhandled exception c0000005 at 738040F8
=== w1064v1809_ja (32 bit report) ===
ddraw: 1a34:ddraw7: unhandled exception c0000005 at 71D640F8
=== w1064v1809_zh_CN (32 bit report) ===
ddraw: 02a4:ddraw7: unhandled exception c0000005 at 71A040F8
Signed-off-by: Paul Gofman gofmanp@gmail.com --- v2: - no changes.
dlls/ddraw/tests/ddraw4.c | 312 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 312 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index fdcf6dff87..bea0f66dce 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -16504,6 +16504,317 @@ static void test_d32_support(void) DestroyWindow(window); }
+static void test_surface_format_conversion_alpha(void) +{ + static const unsigned int rgba_data[4 * 4] = + { + 0xff00ff00, 0xff0000ff, 0xff0000ff, 0xff0000ff, + 0xff0000ff, 0xff00ff00, 0xff0000ff, 0xff0000ff, + 0xff00ff00, 0xff0000ff, 0xff00ff00, 0xff0000ff, + 0xff00ff00, 0xff0000ff, 0xff0000ff, 0xff00ff00, + }; + static const unsigned int rgbx_data[4 * 4] = + { + 0x0000ff00, 0x000000ff, 0x000000ff, 0x000000ff, + 0x000000ff, 0x0000ff00, 0x000000ff, 0x000000ff, + 0x0000ff00, 0x000000ff, 0x0000ff00, 0x000000ff, + 0x0000ff00, 0x000000ff, 0x000000ff, 0x0000ff00, + }; + static const unsigned short int r5g6b5_data[4 * 4] = + { + 0x07e0, 0x001f, 0x001f, 0x001f, + 0x001f, 0x07e0, 0x001f, 0x001f, + 0x07e0, 0x001f, 0x07e0, 0x001f, + 0x07e0, 0x001f, 0x001f, 0x07e0, + }; + static const unsigned short int r5g5b5x1_data[4 * 4] = + { + 0x03e0, 0x001f, 0x001f, 0x001f, + 0x001f, 0x03e0, 0x001f, 0x001f, + 0x03e0, 0x001f, 0x03e0, 0x001f, + 0x03e0, 0x001f, 0x001f, 0x03e0, + }; + static const unsigned short int r5g5b5a1_data[4 * 4] = + { + 0x83e0, 0x801f, 0x801f, 0x801f, + 0x801f, 0x83e0, 0x801f, 0x801f, + 0x83e0, 0x801f, 0x83e0, 0x801f, + 0x83e0, 0x801f, 0x801f, 0x83e0, + }; + static const unsigned int dxt1_data[8] = + { + 0x001f07e0, 0x14445154, + }; + static const unsigned int dxt2_data[16] = + { + 0xffffffff, 0xffffffff, 0x001f07e0, 0x14445154, + }; + + enum test_format_id + { + FMT_RGBA, + FMT_RGBX, + FMT_R5G6B5, + FMT_R5G5B5X1, + FMT_R5G5B5A1, + FMT_DXT1, + FMT_DXT2, + FMT_DXT3, + }; + + static const struct test_format + { + DDPIXELFORMAT fmt; + const char *name; + unsigned int block_size, x_blocks, y_blocks; + DWORD support_flag; + BOOL broken_software_blit; + } + formats[] = + { + { + { + sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0, + {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000} + }, + "RGBA", 4, 4, 4, + }, + { + { + sizeof(DDPIXELFORMAT), DDPF_RGB, 0, + {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000} + }, + "RGBX", 4, 4, 4, + }, + { + { + sizeof(DDPIXELFORMAT), DDPF_RGB, 0, + {16}, {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000} + }, + "R5G6B5", 2, 4, 4, 0, TRUE, + /* Looks broken for sysmem texture convertions on Windows (at least with hardware + * device), the result is either error from _Blt() or a copy of the source data + * without any conversion. */ + }, + { + { + sizeof(DDPIXELFORMAT), DDPF_RGB, 0, + {16}, {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000} + }, + "R5G5B5X1", 2, 4, 4, + }, + { + { + sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0, + {16}, {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000} + }, + "R5G5B5A1", 2, 4, 4, + }, + { + { + sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '1'), + {0}, {0}, {0}, {0}, {0} + }, + "DXT1", 8, 1, 1, SUPPORT_DXT1, + }, + { + { + sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '2'), + {0}, {0}, {0}, {0}, {0} + }, + "DXT2", 16, 1, 1, SUPPORT_DXT2, + }, + { + { + sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '3'), + {0}, {0}, {0}, {0}, {0} + }, + "DXT3", 16, 1, 1, SUPPORT_DXT3, + }, + }; + + static const struct + { + DWORD src_caps, dst_caps; + } + test_caps[] = + { + {DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY}, + {DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY, DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY}, + {DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY}, + {DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY}, + }; + + static const struct + { + enum test_format_id src_format; + const void *src_data; + enum test_format_id dst_format; + const void *expected_data; + BOOL todo; + } + tests[] = + { +#if 0 + /* The following 3 tests give different results on AMD and NVIDIA on Windows, disabling. */ + {FMT_RGBX, rgbx_data, FMT_RGBA, rgba_data}, + {FMT_RGBA, rgba_data, FMT_RGBX, rgbx_data}, + {FMT_R5G5B5X1, r5g5b5x1_data, FMT_RGBA, rgba_data}, +#endif + {FMT_R5G6B5, r5g6b5_data, FMT_RGBA, rgba_data}, + {FMT_R5G6B5, r5g6b5_data, FMT_R5G5B5A1, r5g5b5a1_data}, + {FMT_R5G5B5X1, r5g5b5x1_data, FMT_R5G5B5A1, r5g5b5x1_data, TRUE}, + {FMT_R5G5B5A1, r5g5b5a1_data, FMT_R5G6B5, r5g6b5_data}, + {FMT_RGBA, rgba_data, FMT_DXT1, dxt1_data}, + {FMT_RGBX, rgbx_data, FMT_DXT1, dxt1_data}, + {FMT_RGBA, rgba_data, FMT_DXT2, dxt2_data}, + {FMT_RGBX, rgbx_data, FMT_DXT2, dxt2_data}, + {FMT_RGBA, rgba_data, FMT_DXT3, dxt2_data}, + {FMT_RGBX, rgbx_data, FMT_DXT3, dxt2_data}, + {FMT_DXT1, dxt1_data, FMT_DXT2, dxt2_data}, + {FMT_DXT1, dxt1_data, FMT_RGBA, rgba_data}, + {FMT_DXT1, dxt1_data, FMT_RGBX, rgba_data}, + {FMT_DXT3, dxt2_data, FMT_RGBA, rgba_data}, + {FMT_DXT3, dxt2_data, FMT_RGBX, rgba_data}, + }; + + const struct test_format *src_format, *dst_format; + IDirectDrawSurface4 *src_surf, *dst_surf; + DDSURFACEDESC2 surface_desc, lock; + unsigned int i, j, x, y, pitch; + IDirect3DDevice3 *device; + DWORD supported_fmts; + IDirectDraw4 *ddraw; + ULONG refcount; + BOOL is_wine; + HWND window; + BOOL passed; + HRESULT hr; + + window = create_window(); + if (!(device = create_device(window, DDSCL_NORMAL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice3_EnumTextureFormats(device, test_block_formats_creation_cb, + &supported_fmts); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + is_wine = !strcmp(winetest_platform, "wine"); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.dwWidth = 4; + surface_desc.dwHeight = 4; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + src_format = &formats[tests[i].src_format]; + dst_format = &formats[tests[i].dst_format]; + + if (~supported_fmts & dst_format->support_flag) + { + skip("%s format is not supported, skipping test %u.\n", dst_format->name, i); + continue; + } + if (~supported_fmts & src_format->support_flag) + { + skip("%s format is not supported, skipping test %u.\n", src_format->name, i); + continue; + } + + for (j = 0; j < ARRAY_SIZE(test_caps); ++j) + { + if (!is_wine && ((test_caps[j].src_caps | test_caps[j].dst_caps) & DDSCAPS_SYSTEMMEMORY) + && (src_format->broken_software_blit || dst_format->broken_software_blit)) + continue; + + U4(surface_desc).ddpfPixelFormat = src_format->fmt; + surface_desc.ddsCaps.dwCaps = test_caps[j].src_caps; + hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &src_surf, NULL); + ok(hr == DD_OK, "Test (%u, %u), got unexpected hr %#x.\n", j, i, hr); + + U4(surface_desc).ddpfPixelFormat = dst_format->fmt; + surface_desc.ddsCaps.dwCaps = test_caps[j].dst_caps; + hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &dst_surf, NULL); + ok(hr == DD_OK, "Test (%u, %u), got unexpected hr %#x.\n", j, i, hr); + + memset(&lock, 0, sizeof(lock)); + lock.dwSize = sizeof(lock); + hr = IDirectDrawSurface4_Lock(src_surf, NULL, &lock, 0, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + pitch = U1(lock).lPitch; + for (y = 0; y < src_format->y_blocks; ++y) + memcpy((BYTE*)lock.lpSurface + y * pitch, + (BYTE *)tests[i].src_data + y * src_format->x_blocks * src_format->block_size, + src_format->block_size * src_format->x_blocks); + hr = IDirectDrawSurface4_Unlock(src_surf, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDrawSurface4_Blt(dst_surf, NULL, src_surf, NULL, DDBLT_WAIT, NULL); + if (!is_wine && FAILED(hr)) + { + /* Some software blits are rejected on Windows. */ + IDirectDrawSurface4_Release(dst_surf); + IDirectDrawSurface4_Release(src_surf); + skip("Skipping test (%u, %u), cannot blit %s -> %s, hr %#x.\n", j, i, + src_format->name, dst_format->name, hr); + continue; + } + ok(hr == DD_OK, "Test (%u, %s -> %s), got unexpected hr %#x.\n", j, + src_format->name, dst_format->name, hr); + + memset(&lock, 0, sizeof(lock)); + lock.dwSize = sizeof(lock); + hr = IDirectDrawSurface4_Lock(dst_surf, NULL, &lock, 0, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + pitch = U1(lock).lPitch; + + for (y = 0; y < dst_format->y_blocks; ++y) + { + const void *expected_data = tests[i].expected_data; + + passed = !memcmp((BYTE*)lock.lpSurface + y * pitch, + (BYTE *)expected_data + y * dst_format->x_blocks * dst_format->block_size, + dst_format->block_size * dst_format->x_blocks); + todo_wine_if(tests[i].todo) + ok(passed, "Test (%u, %s -> %s), row %u, unexpected surface data.\n", j, + src_format->name, dst_format->name, y); + + if (!passed && !(is_wine && tests[i].todo)) + { + for (x = 0; x < dst_format->x_blocks * dst_format->block_size / 4; ++x) + trace("Test (%u, %u), x %u, y %u, got 0x%08x, expected 0x%08x.\n", j, i, x, y, + *(unsigned int *)((BYTE *)lock.lpSurface + y * pitch + x * 4), + *(unsigned int *)((BYTE *)expected_data + y * dst_format->x_blocks + * dst_format->block_size + x * 4)); + } + if (!passed) + break; + } + hr = IDirectDrawSurface4_Unlock(dst_surf, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + IDirectDrawSurface4_Release(dst_surf); + IDirectDrawSurface4_Release(src_surf); + } + } + + IDirect3DDevice3_Release(device); + refcount = IDirectDraw4_Release(ddraw); + ok(!refcount, "%u references left.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw4) { DDDEVICEIDENTIFIER identifier; @@ -16638,4 +16949,5 @@ START_TEST(ddraw4) test_clipper_refcount(); test_caps(); test_d32_support(); + test_surface_format_conversion_alpha(); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59873
Your paranoid android.
=== w864 (64 bit report) ===
ddraw: ddraw4.c:3362: Test failed: Failed to create surface, hr 0x887601c2. 05c0:ddraw4: unhandled exception c0000005 at 00000000004AC9E2
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59871
Your paranoid android.
=== w1064v1809 (32 bit report) ===
ddraw: 19a0:ddraw7: unhandled exception c0000005 at 73E040F8
=== w1064v1809_2scr (32 bit report) ===
ddraw: 1a30:ddraw7: unhandled exception c0000005 at 73A940F8
=== w1064v1809_ar (32 bit report) ===
ddraw: 1954:ddraw7: unhandled exception c0000005 at 72CE40F8
=== w1064v1809_he (32 bit report) ===
ddraw: 1ba8:ddraw7: unhandled exception c0000005 at 731C40F8
=== w1064v1809_ja (32 bit report) ===
ddraw: 1b0c:ddraw7: unhandled exception c0000005 at 723640F8
=== w1064v1809_zh_CN (32 bit report) ===
ddraw: 1ac0:ddraw7: unhandled exception c0000005 at 734440F8