Commit 9ab14dff authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

d3dx9: Use a staging texture to update unmappable surfaces in D3DXLoadSurfaceFromMemory().

parent 9bac6f15
......@@ -1753,9 +1753,12 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
DWORD filter, D3DCOLOR color_key)
{
const struct pixel_format_desc *srcformatdesc, *destformatdesc;
IDirect3DSurface9 *surface = dst_surface;
IDirect3DDevice9 *device;
D3DSURFACE_DESC surfdesc;
D3DLOCKED_RECT lockrect;
struct volume src_size, dst_size;
HRESULT hr;
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,
......@@ -1811,6 +1814,26 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
return E_NOTIMPL;
}
if (surfdesc.Pool == D3DPOOL_DEFAULT && !(surfdesc.Usage & D3DUSAGE_DYNAMIC))
{
IDirect3DSurface9_GetDevice(dst_surface, &device);
hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, surfdesc.Width,
surfdesc.Height, surfdesc.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);
IDirect3DDevice9_Release(device);
if (FAILED(hr))
{
WARN("Failed to create staging surface, hr %#x.\n", hr);
return D3DERR_INVALIDCALL;
}
}
if (FAILED(IDirect3DSurface9_LockRect(surface, &lockrect, dst_rect, 0)))
{
if (surface != dst_surface)
IDirect3DSurface9_Release(surface);
return D3DXERR_INVALIDDATA;
}
if (src_format == surfdesc.Format
&& dst_size.width == src_size.width
&& dst_size.height == src_size.height
......@@ -1824,16 +1847,12 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
&& src_size.height != surfdesc.Height))
{
WARN("Source rect %s is misaligned.\n", wine_dbgstr_rect(src_rect));
return D3DXERR_INVALIDDATA;
hr = D3DXERR_INVALIDDATA;
goto done;
}
if (FAILED(IDirect3DSurface9_LockRect(dst_surface, &lockrect, dst_rect, 0)))
return D3DXERR_INVALIDDATA;
copy_pixels(src_memory, src_pitch, 0, lockrect.pBits, lockrect.Pitch, 0,
&src_size, srcformatdesc);
IDirect3DSurface9_UnlockRect(dst_surface);
}
else /* Stretching or format conversion. */
{
......@@ -1841,12 +1860,10 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
|| !is_conversion_to_supported(destformatdesc))
{
FIXME("Unsupported format conversion %#x -> %#x.\n", src_format, surfdesc.Format);
return E_NOTIMPL;
hr = E_NOTIMPL;
goto done;
}
if (FAILED(IDirect3DSurface9_LockRect(dst_surface, &lockrect, dst_rect, 0)))
return D3DXERR_INVALIDDATA;
if ((filter & 0xf) == D3DX_FILTER_NONE)
{
convert_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc,
......@@ -1862,11 +1879,23 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
point_filter_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc,
lockrect.pBits, lockrect.Pitch, 0, &dst_size, destformatdesc, color_key, src_palette);
}
}
IDirect3DSurface9_UnlockRect(dst_surface);
hr = D3D_OK;
done:
IDirect3DSurface9_UnlockRect(surface);
if (surface != dst_surface)
{
if (SUCCEEDED(hr))
{
IDirect3DSurface9_GetDevice(dst_surface, &device);
hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, dst_surface, NULL);
IDirect3DDevice9_Release(device);
}
IDirect3DSurface9_Release(surface);
}
return D3D_OK;
return hr;
}
/************************************************************
......
......@@ -867,7 +867,6 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget returned %#x, expected %#x.\n", hr, D3D_OK);
hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
todo_wine
ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x.\n", hr, D3D_OK);
hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_NONE, 0);
todo_wine
......
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