Commit c9582456 authored by Michael Müller's avatar Michael Müller Committed by Vitaly Lipatov

ddraw: Allow size and format conversions in IDirect3DTexture2::Load.

parent 09199cb9
......@@ -5321,6 +5321,46 @@ static struct ddraw_surface *get_sub_mimaplevel(struct ddraw_surface *surface)
return impl_from_IDirectDrawSurface7(next_level);
}
static BOOL compare_format(DDPIXELFORMAT *format1, DDPIXELFORMAT *format2)
{
if ((format1->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_FOURCC)) !=
(format2->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_FOURCC)))
return FALSE;
if (format1->dwFlags & (DDPF_RGB|DDPF_YUV))
{
if (!(format1->dwFlags & DDPF_ALPHA))
{
/* The RGB and YUV bits are stored in the same fields */
if (format1->u1.dwRGBBitCount != format2->u1.dwRGBBitCount)
return FALSE;
if (format1->u2.dwRBitMask != format2->u2.dwRBitMask)
return FALSE;
if (format1->u3.dwGBitMask != format2->u3.dwGBitMask)
return FALSE;
if (format1->u4.dwBBitMask != format2->u4.dwBBitMask)
return FALSE;
}
if (format1->dwFlags & (DDPF_ALPHAPIXELS | DDPF_ALPHA))
{
if (format1->u5.dwRGBAlphaBitMask != format2->u5.dwRGBAlphaBitMask)
return FALSE;
}
}
if (format1->dwFlags & DDPF_FOURCC)
{
if (format1->dwFourCC != format2->dwFourCC)
return FALSE;
}
return TRUE;
}
/*****************************************************************************
* IDirect3DTexture2::Load
*
......@@ -5342,7 +5382,7 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
{
struct ddraw_surface *dst_surface = impl_from_IDirect3DTexture2(iface);
struct ddraw_surface *src_surface = unsafe_impl_from_IDirect3DTexture2(src_texture);
struct wined3d_resource *dst_resource, *src_resource;
RECT src_rect, dst_rect;
HRESULT hr;
TRACE("iface %p, src_texture %p.\n", iface, src_texture);
......@@ -5355,90 +5395,62 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
wined3d_mutex_lock();
dst_resource = wined3d_texture_get_resource(ddraw_surface_get_default_texture(dst_surface, DDRAW_SURFACE_WRITE));
src_resource = wined3d_texture_get_resource(ddraw_surface_get_default_texture(src_surface, DDRAW_SURFACE_READ));
if (((src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
!= (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP))
|| (src_surface->surface_desc.u2.dwMipMapCount != dst_surface->surface_desc.u2.dwMipMapCount))
{
ERR("Trying to load surfaces with different mip-map counts.\n");
}
for (;;)
{
struct ddraw_palette *dst_pal, *src_pal;
DDSURFACEDESC *src_desc, *dst_desc;
DDSURFACEDESC *src_desc = (DDSURFACEDESC *)&src_surface->surface_desc;
TRACE("Copying surface %p to surface %p.\n", src_surface, dst_surface);
/* Suppress the ALLOCONLOAD flag */
dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
/* Get the palettes */
dst_pal = dst_surface->palette;
src_pal = src_surface->palette;
if (src_pal)
if (compare_format(&src_surface->surface_desc.u4.ddpfPixelFormat,
&dst_surface->surface_desc.u4.ddpfPixelFormat))
{
PALETTEENTRY palent[256];
struct ddraw_palette *dst_pal, *src_pal;
if (!dst_pal)
{
wined3d_mutex_unlock();
return DDERR_NOPALETTEATTACHED;
}
IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent);
IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent);
}
/* Get the palettes */
dst_pal = dst_surface->palette;
src_pal = src_surface->palette;
/* Copy one surface on the other */
dst_desc = (DDSURFACEDESC *)&(dst_surface->surface_desc);
src_desc = (DDSURFACEDESC *)&(src_surface->surface_desc);
if (src_pal)
{
PALETTEENTRY palent[256];
if ((src_desc->dwWidth != dst_desc->dwWidth) || (src_desc->dwHeight != dst_desc->dwHeight))
{
/* Should also check for same pixel format, u1.lPitch, ... */
ERR("Error in surface sizes.\n");
wined3d_mutex_unlock();
return D3DERR_TEXTURE_LOAD_FAILED;
}
else
{
struct wined3d_map_desc src_map_desc, dst_map_desc;
if (!dst_pal)
{
wined3d_mutex_unlock();
return DDERR_NOPALETTEATTACHED;
}
IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent);
IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent);
}
/* Copy the src blit color key if the source has one, don't erase
* the destination's ckey if the source has none */
if (src_desc->dwFlags & DDSD_CKSRCBLT)
{
IDirectDrawSurface7_SetColorKey(&dst_surface->IDirectDrawSurface7_iface,
DDCKEY_SRCBLT, &src_desc->ddckCKSrcBlt);
}
}
else
{
if (src_desc->dwFlags & DDSD_CKSRCBLT)
return E_FAIL;
}
if (FAILED(hr = wined3d_resource_map(src_resource,
src_surface->sub_resource_idx, &src_map_desc, NULL, WINED3D_MAP_READ)))
{
ERR("Failed to lock source surface, hr %#lx.\n", hr);
wined3d_mutex_unlock();
return D3DERR_TEXTURE_LOAD_FAILED;
}
if (FAILED(hr = wined3d_resource_map(dst_resource,
dst_surface->sub_resource_idx, &dst_map_desc, NULL, WINED3D_MAP_WRITE)))
{
ERR("Failed to lock destination surface, hr %#lx.\n", hr);
wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx);
wined3d_mutex_unlock();
return D3DERR_TEXTURE_LOAD_FAILED;
}
/* Suppress the ALLOCONLOAD flag */
dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
if (dst_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
memcpy(dst_map_desc.data, src_map_desc.data, src_surface->surface_desc.u1.dwLinearSize);
else
memcpy(dst_map_desc.data, src_map_desc.data, src_map_desc.row_pitch * src_desc->dwHeight);
SetRect(&src_rect, 0, 0, src_surface->surface_desc.dwWidth, src_surface->surface_desc.dwHeight);
SetRect(&dst_rect, 0, 0, dst_surface->surface_desc.dwWidth, dst_surface->surface_desc.dwHeight);
wined3d_resource_unmap(dst_resource, dst_surface->sub_resource_idx);
wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx);
hr = wined3d_device_context_blt(dst_surface->ddraw->immediate_context,
ddraw_surface_get_default_texture(dst_surface, DDRAW_SURFACE_WRITE),
dst_surface->sub_resource_idx, &dst_rect,
ddraw_surface_get_default_texture(src_surface, DDRAW_SURFACE_READ),
src_surface->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_LINEAR);
if (FAILED(hr))
{
ERR("Failed to blit surface, hr %#lx.\n", hr);
wined3d_mutex_unlock();
return hr;
}
if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
......@@ -5451,12 +5463,11 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
else
dst_surface = NULL;
if (src_surface && !dst_surface)
return DDERR_NOTFOUND;
if (!src_surface || !dst_surface)
{
if (src_surface != dst_surface)
ERR("Loading surface with different mipmap structure.\n");
break;
}
}
wined3d_mutex_unlock();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment