d3dx9: Introduce a function for copying pixels.
This commit is contained in:
parent
a4df391976
commit
08a5dbbb8e
|
@ -72,6 +72,9 @@ HRESULT write_buffer_to_file(const WCHAR *filename, ID3DXBuffer *buffer) DECLSPE
|
||||||
const struct pixel_format_desc *get_format_info(D3DFORMAT format) DECLSPEC_HIDDEN;
|
const struct pixel_format_desc *get_format_info(D3DFORMAT format) DECLSPEC_HIDDEN;
|
||||||
const struct pixel_format_desc *get_format_info_idx(int idx) DECLSPEC_HIDDEN;
|
const struct pixel_format_desc *get_format_info_idx(int idx) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch,
|
||||||
|
BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *size,
|
||||||
|
const struct pixel_format_desc *format) DECLSPEC_HIDDEN;
|
||||||
void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch,
|
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,
|
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,
|
BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size,
|
||||||
|
|
|
@ -460,11 +460,7 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur
|
||||||
if (FAILED(hr)) return hr;
|
if (FAILED(hr)) return hr;
|
||||||
|
|
||||||
pixel_format = get_format_info(src_desc.Format);
|
pixel_format = get_format_info(src_desc.Format);
|
||||||
if (pixel_format->type != FORMAT_ARGB)
|
if (pixel_format->type == FORMAT_UNKNOWN) return E_NOTIMPL;
|
||||||
{
|
|
||||||
FIXME("Unsupported pixel format %#x\n", src_desc.Format);
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
file_size = calculate_dds_file_size(src_desc.Format, src_desc.Width, src_desc.Height, 1, 1, 1);
|
file_size = calculate_dds_file_size(src_desc.Format, src_desc.Width, src_desc.Height, 1, 1, 1);
|
||||||
|
|
||||||
|
@ -504,8 +500,8 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur
|
||||||
volume.width = src_desc.Width;
|
volume.width = src_desc.Width;
|
||||||
volume.height = src_desc.Height;
|
volume.height = src_desc.Height;
|
||||||
volume.depth = 1;
|
volume.depth = 1;
|
||||||
convert_argb_pixels(locked_rect.pBits, locked_rect.Pitch, 0, &volume, pixel_format,
|
copy_pixels(locked_rect.pBits, locked_rect.Pitch, 0, pixels, dst_pitch, 0,
|
||||||
pixels, dst_pitch, 0, &volume, pixel_format, 0);
|
&volume, pixel_format);
|
||||||
|
|
||||||
IDirect3DSurface9_UnlockRect(src_surface);
|
IDirect3DSurface9_UnlockRect(src_surface);
|
||||||
|
|
||||||
|
@ -1354,6 +1350,37 @@ static void format_from_vec4(const struct pixel_format_desc *format, const struc
|
||||||
*dst |= (DWORD)(src->w * ((1 << format->bits[0]) - 1) + 0.5f) << format->shift[0];
|
*dst |= (DWORD)(src->w * ((1 << format->bits[0]) - 1) + 0.5f) << format->shift[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* copy_pixels
|
||||||
|
*
|
||||||
|
* Copies the source buffer to the destination buffer.
|
||||||
|
* Works for any pixel format.
|
||||||
|
* The source and the destination must be block-aligned.
|
||||||
|
*/
|
||||||
|
void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch,
|
||||||
|
BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *size,
|
||||||
|
const struct pixel_format_desc *format)
|
||||||
|
{
|
||||||
|
UINT row, slice;
|
||||||
|
BYTE *dst_addr;
|
||||||
|
const BYTE *src_addr;
|
||||||
|
UINT row_block_count = (size->width + format->block_width - 1) / format->block_width;
|
||||||
|
UINT row_count = (size->height + format->block_height - 1) / format->block_height;
|
||||||
|
|
||||||
|
for (slice = 0; slice < size->depth; slice++)
|
||||||
|
{
|
||||||
|
src_addr = src + slice * src_slice_pitch;
|
||||||
|
dst_addr = dst + slice * dst_slice_pitch;
|
||||||
|
|
||||||
|
for (row = 0; row < row_count; row++)
|
||||||
|
{
|
||||||
|
memcpy(dst_addr, src_addr, row_block_count * format->block_byte_count);
|
||||||
|
src_addr += src_row_pitch;
|
||||||
|
dst_addr += dst_row_pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* convert_argb_pixels
|
* convert_argb_pixels
|
||||||
*
|
*
|
||||||
|
@ -1584,7 +1611,6 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
|
||||||
D3DSURFACE_DESC surfdesc;
|
D3DSURFACE_DESC surfdesc;
|
||||||
D3DLOCKED_RECT lockrect;
|
D3DLOCKED_RECT lockrect;
|
||||||
struct volume src_size, dst_size;
|
struct volume src_size, dst_size;
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
TRACE("(%p, %p, %s, %p, %#x, %u, %p, %s %#x, 0x%08x)\n",
|
TRACE("(%p, %p, %s, %p, %#x, %u, %p, %s %#x, 0x%08x)\n",
|
||||||
dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), src_memory, src_format,
|
dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), src_memory, src_format,
|
||||||
|
@ -1644,12 +1670,6 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
|
||||||
&& dst_size.width == src_size.width
|
&& dst_size.width == src_size.width
|
||||||
&& dst_size.height == src_size.height) /* Simple copy. */
|
&& dst_size.height == src_size.height) /* Simple copy. */
|
||||||
{
|
{
|
||||||
UINT row_block_count = ((src_size.width + srcformatdesc->block_width - 1) / srcformatdesc->block_width);
|
|
||||||
UINT row_count = (src_size.height + srcformatdesc->block_height - 1) / srcformatdesc->block_height;
|
|
||||||
const BYTE *src_addr;
|
|
||||||
BYTE *dst_addr;
|
|
||||||
UINT row;
|
|
||||||
|
|
||||||
if (src_rect->left & (srcformatdesc->block_width - 1)
|
if (src_rect->left & (srcformatdesc->block_width - 1)
|
||||||
|| src_rect->top & (srcformatdesc->block_height - 1)
|
|| src_rect->top & (srcformatdesc->block_height - 1)
|
||||||
|| (src_rect->right & (srcformatdesc->block_width - 1)
|
|| (src_rect->right & (srcformatdesc->block_width - 1)
|
||||||
|
@ -1661,20 +1681,11 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
|
||||||
return D3DXERR_INVALIDDATA;
|
return D3DXERR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr = IDirect3DSurface9_LockRect(dst_surface, &lockrect, dst_rect, 0)))
|
if (FAILED(IDirect3DSurface9_LockRect(dst_surface, &lockrect, dst_rect, 0)))
|
||||||
return D3DXERR_INVALIDDATA;
|
return D3DXERR_INVALIDDATA;
|
||||||
|
|
||||||
src_addr = src_memory;
|
copy_pixels(src_memory, src_pitch, 0, lockrect.pBits, lockrect.Pitch, 0,
|
||||||
src_addr += (src_rect->top / srcformatdesc->block_height) * src_pitch;
|
&src_size, srcformatdesc);
|
||||||
src_addr += (src_rect->left / srcformatdesc->block_width) * srcformatdesc->block_byte_count;
|
|
||||||
dst_addr = lockrect.pBits;
|
|
||||||
|
|
||||||
for (row = 0; row < row_count; ++row)
|
|
||||||
{
|
|
||||||
memcpy(dst_addr, src_addr, row_block_count * srcformatdesc->block_byte_count);
|
|
||||||
src_addr += src_pitch;
|
|
||||||
dst_addr += lockrect.Pitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDirect3DSurface9_UnlockRect(dst_surface);
|
IDirect3DSurface9_UnlockRect(dst_surface);
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,11 +150,7 @@ HRESULT WINAPI D3DXLoadVolumeFromMemory(IDirect3DVolume9 *dst_volume,
|
||||||
if (desc.Format == src_format
|
if (desc.Format == src_format
|
||||||
&& dst_size.width == src_size.width && dst_size.height == src_size.height && dst_size.depth == src_size.depth)
|
&& dst_size.width == src_size.width && dst_size.height == src_size.height && dst_size.depth == src_size.depth)
|
||||||
{
|
{
|
||||||
UINT row, slice;
|
|
||||||
BYTE *dst_addr;
|
|
||||||
const BYTE *src_addr;
|
const BYTE *src_addr;
|
||||||
UINT row_block_count = (src_size.width + src_format_desc->block_width - 1) / src_format_desc->block_width;
|
|
||||||
UINT row_count = (src_size.height + src_format_desc->block_height - 1) / src_format_desc->block_height;
|
|
||||||
|
|
||||||
if (src_box->Left & (src_format_desc->block_width - 1)
|
if (src_box->Left & (src_format_desc->block_width - 1)
|
||||||
|| src_box->Top & (src_format_desc->block_height - 1)
|
|| src_box->Top & (src_format_desc->block_height - 1)
|
||||||
|
@ -168,26 +164,17 @@ HRESULT WINAPI D3DXLoadVolumeFromMemory(IDirect3DVolume9 *dst_volume,
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
src_addr = src_memory;
|
||||||
|
src_addr += src_box->Front * src_slice_pitch;
|
||||||
|
src_addr += (src_box->Top / src_format_desc->block_height) * src_row_pitch;
|
||||||
|
src_addr += (src_box->Left / src_format_desc->block_width) * src_format_desc->block_byte_count;
|
||||||
|
|
||||||
hr = IDirect3DVolume9_LockBox(dst_volume, &locked_box, dst_box, 0);
|
hr = IDirect3DVolume9_LockBox(dst_volume, &locked_box, dst_box, 0);
|
||||||
if (FAILED(hr)) return hr;
|
if (FAILED(hr)) return hr;
|
||||||
|
|
||||||
for (slice = 0; slice < src_size.depth; slice++)
|
copy_pixels(src_addr, src_row_pitch, src_slice_pitch,
|
||||||
{
|
locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch,
|
||||||
src_addr = src_memory;
|
&dst_size, dst_format_desc);
|
||||||
src_addr += (src_box->Front + slice) * src_slice_pitch;
|
|
||||||
src_addr += (src_box->Top / src_format_desc->block_height) * src_row_pitch;
|
|
||||||
src_addr += (src_box->Left / src_format_desc->block_width) * src_format_desc->block_byte_count;
|
|
||||||
|
|
||||||
dst_addr = locked_box.pBits;
|
|
||||||
dst_addr += slice * locked_box.SlicePitch;
|
|
||||||
|
|
||||||
for (row = 0; row < row_count; row++)
|
|
||||||
{
|
|
||||||
memcpy(dst_addr, src_addr, row_block_count * src_format_desc->block_byte_count);
|
|
||||||
src_addr += src_row_pitch;
|
|
||||||
dst_addr += locked_box.RowPitch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IDirect3DVolume9_UnlockBox(dst_volume);
|
IDirect3DVolume9_UnlockBox(dst_volume);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue