From: Paul Gofman gofmanp@gmail.com
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 Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- This supersedes patch 173405.
dlls/ddraw/tests/ddraw7.c | 6 ++-- dlls/wined3d/texture.c | 89 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 6 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 1592d2e081f..7f2c3e9751e 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 8d3c25cf15d..d4d90c280a1 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1963,6 +1963,79 @@ 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 uint8_t *src, + unsigned int src_row_pitch, uint8_t *dst, 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; + + switch (byte_count) + { + case 2: + for (y = 0; y < height; ++y) + { + const uint16_t *src_row = (const uint16_t *)&src[y * src_row_pitch]; + uint16_t *dst_row = (uint16_t *)&dst[y * dst_row_pitch]; + + for (x = 0; x < width; ++x) + { + dst_row[x] = src_row[x] | alpha_mask; + } + } + break; + + case 4: + for (y = 0; y < height; ++y) + { + const uint32_t *src_row = (const uint32_t *)&src[y * src_row_pitch]; + uint32_t *dst_row = (uint32_t *)&dst[y * dst_row_pitch]; + + for (x = 0; x < width; ++x) + { + dst_row[x] = src_row[x] | alpha_mask; + } + } + break; + + default: + ERR("Unsupported byte count %u.\n", byte_count); + break; + } +} + 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 +2043,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 +2119,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 +2134,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 +2165,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);
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=60078
Your paranoid android.
=== w8adm (32 bit report) ===
ddraw: ddraw7.c:3036: Test failed: Failed to create surface, hr 0x887601c2. 0d24:ddraw7: unhandled exception c0000005 at 00510105
=== w1064v1809 (32 bit report) ===
ddraw: 1940:ddraw7: unhandled exception c0000005 at 72DB40F8
=== w1064v1809_2scr (32 bit report) ===
ddraw: 1a64:ddraw7: unhandled exception c0000005 at 732F40F8
=== w1064v1809_ar (32 bit report) ===
ddraw: 1090:ddraw7: unhandled exception c0000005 at 72CE40F8
=== w1064v1809_he (32 bit report) ===
ddraw: 19ac:ddraw7: unhandled exception c0000005 at 737040F8
=== w1064v1809_ja (32 bit report) ===
ddraw: 15bc:ddraw7: unhandled exception c0000005 at 71D640F8
=== w1064v1809_zh_CN (32 bit report) ===
ddraw: 1a38:ddraw7: unhandled exception c0000005 at 72DF40F8