From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 104 ++++++++++++++++++---------------- dlls/d3dx9_36/tests/surface.c | 5 -- 2 files changed, 56 insertions(+), 53 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index b9a11f682b4..1b6a4c0ad19 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -1417,7 +1417,7 @@ static HRESULT d3dx_image_tga_rle_decode_row(const uint8_t **src, uint32_t src_b
static void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size, const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, - const struct volume *dst_size, const struct pixel_format_desc *dst_format, D3DCOLOR color_key, + const struct volume *dst_size, const struct pixel_format_desc *dst_format, uint8_t *color_key, const PALETTEENTRY *palette); static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_size, uint32_t src_header_size, struct d3dx_image *image) @@ -1463,7 +1463,7 @@ static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_siz dst_desc = get_format_info(D3DFMT_A8B8G8R8); d3dx_calculate_pixels_size(dst_desc->format, 256, 1, &dst_row_pitch, &dst_slice_pitch); convert_argb_pixels(src_palette, src_row_pitch, src_slice_pitch, &image_map_size, src_desc, (BYTE *)palette, - dst_row_pitch, dst_slice_pitch, &image_map_size, dst_desc, 0, NULL); + dst_row_pitch, dst_slice_pitch, &image_map_size, dst_desc, NULL, NULL);
/* Initialize unused palette entries to 0xff. */ if (header->color_map_length < 256) @@ -2441,44 +2441,33 @@ static void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitc
static void convert_argb_pixel(const uint8_t *src_ptr, const struct pixel_format_desc *src_fmt, uint8_t *dst_ptr, const struct pixel_format_desc *dst_fmt, const PALETTEENTRY *palette, struct argb_conversion_info *conv_info, - D3DCOLOR color_key, const struct pixel_format_desc *ck_format, struct argb_conversion_info *ck_conv_info) + uint8_t *color_key) { + const BOOL is_color_key = (color_key && !memcmp(color_key, src_ptr, src_fmt->bytes_per_pixel)); + if (format_types_match(src_fmt, dst_fmt) && src_fmt->bytes_per_pixel <= 4 && dst_fmt->bytes_per_pixel <= 4) { DWORD channels[4]; DWORD val;
- get_relevant_argb_components(conv_info, src_ptr, channels); - val = make_argb_color(conv_info, channels); - - if (color_key) + if (!is_color_key) { - DWORD ck_pixel; - - get_relevant_argb_components(ck_conv_info, src_ptr, channels); - ck_pixel = make_argb_color(ck_conv_info, channels); - if (ck_pixel == color_key) - val &= ~conv_info->destmask[0]; + get_relevant_argb_components(conv_info, src_ptr, channels); + val = make_argb_color(conv_info, channels); + } + else + { + val = 0; } memcpy(dst_ptr, &val, dst_fmt->bytes_per_pixel); } else { - struct d3dx_color color, tmp; + struct d3dx_color color;
format_to_d3dx_color(src_fmt, src_ptr, palette, &color); - tmp = color; - - if (color_key) - { - DWORD ck_pixel; - - format_from_d3dx_color(ck_format, &tmp, (BYTE *)&ck_pixel); - if (ck_pixel == color_key) - tmp.value.w = 0.0f; - } - - color = tmp; + if (is_color_key) + memset(&color.value, 0, sizeof(color.value)); format_from_d3dx_color(dst_fmt, &color, dst_ptr); } } @@ -2492,17 +2481,15 @@ static void convert_argb_pixel(const uint8_t *src_ptr, const struct pixel_format */ static void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size, const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, - const struct volume *dst_size, const struct pixel_format_desc *dst_format, D3DCOLOR color_key, + const struct volume *dst_size, const struct pixel_format_desc *dst_format, uint8_t *color_key, const PALETTEENTRY *palette) { - /* Color keys are always represented in D3DFMT_A8R8G8B8 format. */ - const struct pixel_format_desc *ck_format = color_key ? get_format_info(D3DFMT_A8R8G8B8) : NULL; - struct argb_conversion_info conv_info, ck_conv_info; + struct argb_conversion_info conv_info; UINT min_width, min_height, min_depth; UINT x, y, z;
TRACE("src %p, src_row_pitch %u, src_slice_pitch %u, src_size %p, src_format %p, dst %p, " - "dst_row_pitch %u, dst_slice_pitch %u, dst_size %p, dst_format %p, color_key 0x%08lx, palette %p.\n", + "dst_row_pitch %u, dst_slice_pitch %u, dst_size %p, dst_format %p, color_key %p, palette %p.\n", src, src_row_pitch, src_slice_pitch, src_size, src_format, dst, dst_row_pitch, dst_slice_pitch, dst_size, dst_format, color_key, palette);
@@ -2512,9 +2499,6 @@ static void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_sl min_height = min(src_size->height, dst_size->height); min_depth = min(src_size->depth, dst_size->depth);
- if (color_key) - init_argb_conversion_info(src_format, ck_format, &ck_conv_info); - for (z = 0; z < min_depth; z++) { const BYTE *src_slice_ptr = src + z * src_slice_pitch; BYTE *dst_slice_ptr = dst + z * dst_slice_pitch; @@ -2524,8 +2508,7 @@ static void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_sl BYTE *dst_ptr = dst_slice_ptr + y * dst_row_pitch;
for (x = 0; x < min_width; x++) { - convert_argb_pixel(src_ptr, src_format, dst_ptr, dst_format, palette, - &conv_info, color_key, ck_format, &ck_conv_info); + convert_argb_pixel(src_ptr, src_format, dst_ptr, dst_format, palette, &conv_info, color_key);
src_ptr += src_format->bytes_per_pixel; dst_ptr += dst_format->bytes_per_pixel; @@ -2552,23 +2535,18 @@ static void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_sl static void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size, const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size, const struct pixel_format_desc *dst_format, - D3DCOLOR color_key, const PALETTEENTRY *palette) + uint8_t *color_key, const PALETTEENTRY *palette) { - /* Color keys are always represented in D3DFMT_A8R8G8B8 format. */ - const struct pixel_format_desc *ck_format = color_key ? get_format_info(D3DFMT_A8R8G8B8) : NULL; - struct argb_conversion_info conv_info, ck_conv_info; + struct argb_conversion_info conv_info; UINT x, y, z;
TRACE("src %p, src_row_pitch %u, src_slice_pitch %u, src_size %p, src_format %p, dst %p, " - "dst_row_pitch %u, dst_slice_pitch %u, dst_size %p, dst_format %p, color_key 0x%08lx, palette %p.\n", + "dst_row_pitch %u, dst_slice_pitch %u, dst_size %p, dst_format %p, color_key %p, palette %p.\n", src, src_row_pitch, src_slice_pitch, src_size, src_format, dst, dst_row_pitch, dst_slice_pitch, dst_size, dst_format, color_key, palette);
init_argb_conversion_info(src_format, dst_format, &conv_info);
- if (color_key) - init_argb_conversion_info(src_format, ck_format, &ck_conv_info); - for (z = 0; z < dst_size->depth; z++) { BYTE *dst_slice_ptr = dst + z * dst_slice_pitch; @@ -2583,8 +2561,7 @@ static void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT s { const BYTE *src_ptr = src_row_ptr + (x * src_size->width / dst_size->width) * src_format->bytes_per_pixel;
- convert_argb_pixel(src_ptr, src_format, dst_ptr, dst_format, palette, - &conv_info, color_key, ck_format, &ck_conv_info); + convert_argb_pixel(src_ptr, src_format, dst_ptr, dst_format, palette, &conv_info, color_key); dst_ptr += dst_format->bytes_per_pixel; } } @@ -2727,11 +2704,38 @@ static const char *debug_d3dx_pixels(struct d3dx_pixels *pixels) pixels->size.width, pixels->size.height, pixels->size.depth, wine_dbgstr_rect(&pixels->unaligned_rect)); }
+static BOOL get_format_color_key(const struct pixel_format_desc *fmt, const PALETTEENTRY *palette, + uint32_t in_color_key, uint8_t *out_color_key) +{ + /* Color keys are always represented in D3DFMT_A8R8G8B8 format. */ + const struct pixel_format_desc *ck_format = get_format_info(D3DFMT_A8R8G8B8); + struct d3dx_color tmp_color; + + if (fmt == ck_format) + { + memcpy(out_color_key, &in_color_key, sizeof(in_color_key)); + return TRUE; + } + + if (is_index_format(fmt)) + { + FIXME("Color keying for indexed formats is currently unimplemented.\n"); + return FALSE; + } + + format_to_d3dx_color(ck_format, (const uint8_t *)&in_color_key, palette, &tmp_color); + format_from_d3dx_color(fmt, &tmp_color, out_color_key); + + return TRUE; +} + HRESULT d3dx_load_pixels_from_pixels(struct d3dx_pixels *dst_pixels, const struct pixel_format_desc *dst_desc, struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_desc, uint32_t filter_flags, uint32_t color_key) { struct volume src_size, dst_size, dst_size_aligned; + uint8_t *src_color_key = NULL; + uint8_t color_key_buf[16]; HRESULT hr = S_OK;
TRACE("dst_pixels %s, dst_desc %p, src_pixels %s, src_desc %p, filter_flags %#x, color_key %#x.\n", @@ -2859,11 +2863,15 @@ HRESULT d3dx_load_pixels_from_pixels(struct d3dx_pixels *dst_pixels, goto exit; }
+ assert(src_desc->bytes_per_pixel <= sizeof(color_key_buf)); + if (color_key && get_format_color_key(src_desc, src_pixels->palette, color_key, color_key_buf)) + src_color_key = color_key_buf; + if ((filter_flags & 0xf) == D3DX_FILTER_NONE) { convert_argb_pixels(src_pixels->data, src_pixels->row_pitch, src_pixels->slice_pitch, &src_size, src_desc, (BYTE *)dst_pixels->data, dst_pixels->row_pitch, dst_pixels->slice_pitch, &dst_size, dst_desc, - color_key, src_pixels->palette); + src_color_key, src_pixels->palette); } else /* if ((filter & 0xf) == D3DX_FILTER_POINT) */ { @@ -2874,7 +2882,7 @@ HRESULT d3dx_load_pixels_from_pixels(struct d3dx_pixels *dst_pixels, * D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented. */ point_filter_argb_pixels(src_pixels->data, src_pixels->row_pitch, src_pixels->slice_pitch, &src_size, src_desc, (BYTE *)dst_pixels->data, dst_pixels->row_pitch, dst_pixels->slice_pitch, &dst_size, - dst_desc, color_key, src_pixels->palette); + dst_desc, src_color_key, src_pixels->palette); }
exit: diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 7a150724cd6..082abca5dc5 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -2150,12 +2150,10 @@ static void test_color_key(IDirect3DDevice9 *device) /* Color key with alpha channel unset. */ { D3DFMT_R8G8B8, NULL, { 0, 0, 4, 4 }, r8g8b8_4_4, r8g8b8_4_4_expected, 0x00008080, - .todo = TRUE }, /* Same color key as before except the alpha channel is set. */ { D3DFMT_R8G8B8, NULL, { 0, 0, 4, 4 }, r8g8b8_4_4, r8g8b8_4_4_expected, 0xff008080, - .todo = TRUE }, /* Color key on a palette. */ { @@ -2168,16 +2166,13 @@ static void test_color_key(IDirect3DDevice9 *device) }, { D3DFMT_A32B32G32R32F, NULL, { 0, 0, 4, 4 }, a32r32g32b32_4_4, a32r32g32b32_4_4_expected, 0xffff0000, - .todo = TRUE }, /* 5. */ { D3DFMT_R32F, NULL, { 0, 0, 4, 4 }, r32_4_4, r32_4_4_expected, 0xffff0000, - .todo = TRUE }, { D3DFMT_Q8W8V8U8, NULL, { 0, 0, 4, 4 }, q8w8v8u8_4_4, q8w8v8u8_4_4_expected, 0xffff0000, - .todo = TRUE }, /* Color key is ignored for compressed formats. */ {