d3dx9: Preserve the contents of unaligned compressed destination surfaces.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
This commit is contained in:
parent
a1381fbedb
commit
ec44170322
2 changed files with 34 additions and 32 deletions
|
@ -1876,8 +1876,8 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT d3dx_image_decompress(const void *memory, uint32_t row_pitch, const RECT *rect,
|
static HRESULT d3dx_image_decompress(const void *memory, uint32_t row_pitch, const RECT *rect,
|
||||||
const struct volume *size, const struct pixel_format_desc *desc, void **out_memory,
|
const RECT *unaligned_rect, const struct volume *size, const struct pixel_format_desc *desc,
|
||||||
uint32_t *out_row_pitch, RECT *out_rect, const struct pixel_format_desc **out_desc)
|
void **out_memory, uint32_t *out_row_pitch, RECT *out_rect, const struct pixel_format_desc **out_desc)
|
||||||
{
|
{
|
||||||
void (*fetch_dxt_texel)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel);
|
void (*fetch_dxt_texel)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel);
|
||||||
const struct pixel_format_desc *uncompressed_desc = NULL;
|
const struct pixel_format_desc *uncompressed_desc = NULL;
|
||||||
|
@ -1908,6 +1908,9 @@ static HRESULT d3dx_image_decompress(const void *memory, uint32_t row_pitch, con
|
||||||
if (!(uncompressed_mem = malloc(size->width * size->height * size->depth * uncompressed_desc->bytes_per_pixel)))
|
if (!(uncompressed_mem = malloc(size->width * size->height * size->depth * uncompressed_desc->bytes_per_pixel)))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
if (unaligned_rect && EqualRect(rect, unaligned_rect))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
TRACE("Decompressing image.\n");
|
TRACE("Decompressing image.\n");
|
||||||
tmp_pitch = row_pitch * desc->block_width / desc->block_byte_count;
|
tmp_pitch = row_pitch * desc->block_width / desc->block_byte_count;
|
||||||
for (y = 0; y < size->height; ++y)
|
for (y = 0; y < size->height; ++y)
|
||||||
|
@ -1915,14 +1918,21 @@ static HRESULT d3dx_image_decompress(const void *memory, uint32_t row_pitch, con
|
||||||
BYTE *ptr = &uncompressed_mem[y * size->width * uncompressed_desc->bytes_per_pixel];
|
BYTE *ptr = &uncompressed_mem[y * size->width * uncompressed_desc->bytes_per_pixel];
|
||||||
for (x = 0; x < size->width; ++x)
|
for (x = 0; x < size->width; ++x)
|
||||||
{
|
{
|
||||||
fetch_dxt_texel(tmp_pitch, (BYTE *)memory, x + rect->left, y + rect->top, ptr);
|
const POINT pt = { x, y };
|
||||||
|
|
||||||
|
if (!PtInRect(unaligned_rect, pt))
|
||||||
|
fetch_dxt_texel(tmp_pitch, (BYTE *)memory, x + rect->left, y + rect->top, ptr);
|
||||||
ptr += uncompressed_desc->bytes_per_pixel;
|
ptr += uncompressed_desc->bytes_per_pixel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
*out_memory = uncompressed_mem;
|
*out_memory = uncompressed_mem;
|
||||||
*out_row_pitch = size->width * uncompressed_desc->bytes_per_pixel;
|
*out_row_pitch = size->width * uncompressed_desc->bytes_per_pixel;
|
||||||
SetRect(out_rect, 0, 0, size->width, size->height);
|
if (unaligned_rect)
|
||||||
|
*out_rect = *unaligned_rect;
|
||||||
|
else
|
||||||
|
SetRect(out_rect, 0, 0, size->width, size->height);
|
||||||
*out_desc = uncompressed_desc;
|
*out_desc = uncompressed_desc;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -1991,7 +2001,7 @@ static HRESULT d3dx_load_image_from_memory(void *dst_memory, uint32_t dst_row_pi
|
||||||
void *uncompressed_mem = NULL;
|
void *uncompressed_mem = NULL;
|
||||||
RECT uncompressed_rect;
|
RECT uncompressed_rect;
|
||||||
|
|
||||||
hr = d3dx_image_decompress(src_memory, src_row_pitch, src_rect, &src_size, src_desc,
|
hr = d3dx_image_decompress(src_memory, src_row_pitch, src_rect, NULL, &src_size, src_desc,
|
||||||
&uncompressed_mem, &uncompressed_row_pitch, &uncompressed_rect, &uncompressed_desc);
|
&uncompressed_mem, &uncompressed_row_pitch, &uncompressed_rect, &uncompressed_desc);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
@ -2006,29 +2016,21 @@ static HRESULT d3dx_load_image_from_memory(void *dst_memory, uint32_t dst_row_pi
|
||||||
/* Same as the above, need to decompress the destination prior to modifying. */
|
/* Same as the above, need to decompress the destination prior to modifying. */
|
||||||
if (dst_desc->type == FORMAT_DXT)
|
if (dst_desc->type == FORMAT_DXT)
|
||||||
{
|
{
|
||||||
size_t dst_uncompressed_size = dst_size_aligned.width * dst_size_aligned.height * sizeof(DWORD);
|
const struct pixel_format_desc *uncompressed_desc;
|
||||||
BOOL dst_misaligned = dst_rect->left != dst_rect_aligned->left
|
uint32_t uncompressed_row_pitch;
|
||||||
|| dst_rect->top != dst_rect_aligned->top
|
void *uncompressed_mem = NULL;
|
||||||
|| dst_rect->right != dst_rect_aligned->right
|
BYTE *uncompressed_mem_offset;
|
||||||
|| dst_rect->bottom != dst_rect_aligned->bottom;
|
RECT uncompressed_rect;
|
||||||
const struct pixel_format_desc *dst_uncompressed_desc;
|
|
||||||
BYTE *dst_uncompressed, *dst_uncompressed_aligned;
|
|
||||||
uint32_t dst_uncompressed_row_pitch;
|
|
||||||
RECT dst_uncompressed_rect;
|
|
||||||
|
|
||||||
dst_uncompressed_aligned = malloc(dst_uncompressed_size);
|
hr = d3dx_image_decompress(dst_memory, dst_row_pitch, dst_rect_aligned, dst_rect, &dst_size_aligned, dst_desc,
|
||||||
if (!dst_uncompressed_aligned)
|
&uncompressed_mem, &uncompressed_row_pitch, &uncompressed_rect, &uncompressed_desc);
|
||||||
return E_OUTOFMEMORY;
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
if (dst_misaligned) memset(dst_uncompressed_aligned, 0, dst_uncompressed_size);
|
uncompressed_mem_offset = (BYTE *)uncompressed_mem + (dst_rect->top - dst_rect_aligned->top) * uncompressed_row_pitch
|
||||||
dst_uncompressed_row_pitch = dst_size_aligned.width * sizeof(DWORD);
|
+ (dst_rect->left - dst_rect_aligned->left) * uncompressed_desc->bytes_per_pixel;
|
||||||
dst_uncompressed_desc = get_format_info(D3DFMT_A8B8G8R8);
|
hr = d3dx_load_image_from_memory(uncompressed_mem_offset, uncompressed_row_pitch, uncompressed_desc, dst_palette,
|
||||||
dst_uncompressed = dst_uncompressed_aligned + (dst_rect->top - dst_rect_aligned->top) * dst_uncompressed_row_pitch
|
&uncompressed_rect, &uncompressed_rect, src_memory, src_row_pitch, src_desc, src_palette,
|
||||||
+ (dst_rect->left - dst_rect_aligned->left) * sizeof(DWORD);
|
|
||||||
|
|
||||||
SetRect(&dst_uncompressed_rect, 0, 0, dst_size.width, dst_size.height);
|
|
||||||
hr = d3dx_load_image_from_memory(dst_uncompressed, dst_uncompressed_row_pitch, dst_uncompressed_desc, dst_palette,
|
|
||||||
&dst_uncompressed_rect, &dst_uncompressed_rect, src_memory_offset, src_row_pitch, src_desc, src_palette,
|
|
||||||
src_rect, filter_flags, color_key);
|
src_rect, filter_flags, color_key);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
@ -2051,10 +2053,10 @@ static HRESULT d3dx_load_image_from_memory(void *dst_memory, uint32_t dst_row_pi
|
||||||
default:
|
default:
|
||||||
ERR("Unexpected destination compressed format %u.\n", dst_desc->format);
|
ERR("Unexpected destination compressed format %u.\n", dst_desc->format);
|
||||||
}
|
}
|
||||||
tx_compress_dxtn(4, dst_size_aligned.width, dst_size_aligned.height, dst_uncompressed_aligned, gl_format,
|
tx_compress_dxtn(4, dst_size_aligned.width, dst_size_aligned.height, uncompressed_mem, gl_format,
|
||||||
dst_memory, dst_row_pitch);
|
dst_memory, dst_row_pitch);
|
||||||
}
|
}
|
||||||
free(dst_uncompressed_aligned);
|
free(uncompressed_mem);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1651,14 +1651,14 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
|
||||||
|
|
||||||
get_surface_decompressed_readback(device, newsurf, &surface_rb);
|
get_surface_decompressed_readback(device, newsurf, &surface_rb);
|
||||||
|
|
||||||
check_readback_pixel_4bpp(&surface_rb, 0, 0, 0xff0000ff, TRUE); /* Blue block, top left. */
|
check_readback_pixel_4bpp(&surface_rb, 0, 0, 0xff0000ff, FALSE); /* Blue block, top left. */
|
||||||
check_readback_pixel_4bpp(&surface_rb, 3, 3, 0xff000000, FALSE); /* Blue block, bottom right. */
|
check_readback_pixel_4bpp(&surface_rb, 3, 3, 0xff000000, FALSE); /* Blue block, bottom right. */
|
||||||
check_readback_pixel_4bpp(&surface_rb, 7, 0, 0xff00ff00, TRUE); /* Green block, top right. */
|
check_readback_pixel_4bpp(&surface_rb, 7, 0, 0xff00ff00, FALSE); /* Green block, top right. */
|
||||||
check_readback_pixel_4bpp(&surface_rb, 4, 3, 0xff000000, FALSE); /* Green block, bottom left. */
|
check_readback_pixel_4bpp(&surface_rb, 4, 3, 0xff000000, FALSE); /* Green block, bottom left. */
|
||||||
check_readback_pixel_4bpp(&surface_rb, 3, 4, 0xff000000, FALSE); /* Red block, top right. */
|
check_readback_pixel_4bpp(&surface_rb, 3, 4, 0xff000000, FALSE); /* Red block, top right. */
|
||||||
check_readback_pixel_4bpp(&surface_rb, 0, 7, 0xffff0000, TRUE); /* Red block, bottom left. */
|
check_readback_pixel_4bpp(&surface_rb, 0, 7, 0xffff0000, FALSE); /* Red block, bottom left. */
|
||||||
check_readback_pixel_4bpp(&surface_rb, 4, 4, 0xff000000, FALSE); /* Black block, top left. */
|
check_readback_pixel_4bpp(&surface_rb, 4, 4, 0xff000000, FALSE); /* Black block, top left. */
|
||||||
check_readback_pixel_4bpp(&surface_rb, 7, 7, 0xff000000, TRUE); /* Black block, bottom right. */
|
check_readback_pixel_4bpp(&surface_rb, 7, 7, 0xff000000, FALSE); /* Black block, bottom right. */
|
||||||
|
|
||||||
release_surface_readback(&surface_rb);
|
release_surface_readback(&surface_rb);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue