From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 61 +++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 26 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index e2106f4b110..ea4a900c82b 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -1933,9 +1933,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, - const RECT *unaligned_rect, const struct volume *size, const struct pixel_format_desc *desc, - void **out_memory, uint32_t *out_row_pitch, RECT *out_rect, const struct pixel_format_desc **out_desc) +static HRESULT d3dx_sub_resource_decompress(struct d3dx_sub_resource *sub_rsrc, const struct pixel_format_desc *desc, + BOOL is_dst, void **out_memory, uint32_t *out_row_pitch, const struct pixel_format_desc **out_desc) { void (*fetch_dxt_texel)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel); const struct pixel_format_desc *uncompressed_desc = NULL; @@ -1963,34 +1962,48 @@ static HRESULT d3dx_image_decompress(const void *memory, uint32_t row_pitch, con return E_NOTIMPL; }
- if (!(uncompressed_mem = malloc(size->width * size->height * size->depth * uncompressed_desc->bytes_per_pixel))) + if (!(uncompressed_mem = malloc(sub_rsrc->width * sub_rsrc->height * sub_rsrc->depth * uncompressed_desc->bytes_per_pixel))) return E_OUTOFMEMORY;
- if (unaligned_rect && EqualRect(rect, unaligned_rect)) - goto exit; + /* + * For compressed destination sub resources, width/height will represent + * the entire set of compressed blocks our destination rectangle touches. + * If we're only updating a sub-area of any blocks, we need to decompress + * the pixels outside of the sub-area. + */ + if (is_dst) + { + const RECT aligned_rect = { 0, 0, sub_rsrc->width, sub_rsrc->height };
- TRACE("Decompressing image.\n"); - tmp_pitch = row_pitch * desc->block_width / desc->block_byte_count; - for (y = 0; y < size->height; ++y) + /* + * If our destination covers the entire set of blocks, no + * decompression needs to be done, just return the allocated memory. + */ + if (EqualRect(&aligned_rect, &sub_rsrc->unaligned_rect)) + goto exit; + } + + TRACE("Decompressing sub resource.\n"); + tmp_pitch = sub_rsrc->row_pitch * desc->block_width / desc->block_byte_count; + for (y = 0; y < sub_rsrc->height; ++y) { - BYTE *ptr = &uncompressed_mem[y * size->width * uncompressed_desc->bytes_per_pixel]; - for (x = 0; x < size->width; ++x) + BYTE *ptr = &uncompressed_mem[y * sub_rsrc->width * uncompressed_desc->bytes_per_pixel]; + for (x = 0; x < sub_rsrc->width; ++x) { const POINT pt = { x, y };
- if (!PtInRect(unaligned_rect, pt)) - fetch_dxt_texel(tmp_pitch, (BYTE *)memory, x + rect->left, y + rect->top, ptr); + if (!is_dst) + fetch_dxt_texel(tmp_pitch, (BYTE *)sub_rsrc->data, x + sub_rsrc->unaligned_rect.left, + y + sub_rsrc->unaligned_rect.top, ptr); + else if (!PtInRect(&sub_rsrc->unaligned_rect, pt)) + fetch_dxt_texel(tmp_pitch, (BYTE *)sub_rsrc->data, x, y, ptr); ptr += uncompressed_desc->bytes_per_pixel; } }
exit: *out_memory = uncompressed_mem; - *out_row_pitch = size->width * uncompressed_desc->bytes_per_pixel; - if (unaligned_rect) - *out_rect = *unaligned_rect; - else - SetRect(out_rect, 0, 0, size->width, size->height); + *out_row_pitch = sub_rsrc->width * uncompressed_desc->bytes_per_pixel; *out_desc = uncompressed_desc;
return S_OK; @@ -2111,10 +2124,9 @@ static HRESULT d3dx_load_sub_resource_from_sub_resource(struct d3dx_sub_resource const struct pixel_format_desc *uncompressed_desc; uint32_t uncompressed_row_pitch; void *uncompressed_mem = NULL; - RECT uncompressed_rect;
- hr = d3dx_image_decompress(src_sub_rsrc->data, src_sub_rsrc->row_pitch, &src_sub_rsrc->unaligned_rect, NULL, - &src_size, src_desc, &uncompressed_mem, &uncompressed_row_pitch, &uncompressed_rect, &uncompressed_desc); + hr = d3dx_sub_resource_decompress(src_sub_rsrc, src_desc, FALSE, &uncompressed_mem, &uncompressed_row_pitch, + &uncompressed_desc); if (SUCCEEDED(hr)) { struct d3dx_sub_resource uncompressed_sub_rsrc; @@ -2135,14 +2147,11 @@ static HRESULT d3dx_load_sub_resource_from_sub_resource(struct d3dx_sub_resource { const struct pixel_format_desc *uncompressed_desc; struct d3dx_sub_resource uncompressed_sub_rsrc; - RECT uncompressed_rect, aligned_rect; uint32_t uncompressed_row_pitch; void *uncompressed_mem = NULL;
- SetRect(&aligned_rect, 0, 0, dst_sub_rsrc->width, dst_sub_rsrc->height); - hr = d3dx_image_decompress(dst_sub_rsrc->data, dst_sub_rsrc->row_pitch, &aligned_rect, - &dst_sub_rsrc->unaligned_rect, &dst_size_aligned, dst_desc, &uncompressed_mem, &uncompressed_row_pitch, - &uncompressed_rect, &uncompressed_desc); + hr = d3dx_sub_resource_decompress(dst_sub_rsrc, dst_desc, TRUE, &uncompressed_mem, &uncompressed_row_pitch, + &uncompressed_desc); if (FAILED(hr)) return hr;