wined3d: Don't DISCARD or NOOVERWRITE non-dynamic buffers.

Shaiya locks a non-dynamic buffer with the DISCARD flag and expects
the contents to be retained. The SDK says DISCARD requires dynamic
resources, and Windows 7 returns an error in this situation, crashing
Shaiya. This patch sticks to the Windows XP behavior and allows the
lock, but ignores the DISCARD flag to retain the buffer contents.
This commit is contained in:
Stefan Dösinger 2010-03-11 12:05:23 +01:00 committed by Alexandre Julliard
parent eb355ece4a
commit 04752991b1
1 changed files with 7 additions and 2 deletions

View File

@ -1033,7 +1033,7 @@ static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *ifac
/* IWineD3DBuffer methods */ /* IWineD3DBuffer methods */
static DWORD buffer_sanitize_flags(DWORD flags) static DWORD buffer_sanitize_flags(struct wined3d_buffer *buffer, DWORD flags)
{ {
/* Not all flags make sense together, but Windows never returns an error. Catch the /* Not all flags make sense together, but Windows never returns an error. Catch the
* cases that could cause issues */ * cases that could cause issues */
@ -1055,6 +1055,11 @@ static DWORD buffer_sanitize_flags(DWORD flags)
WARN("WINED3DLOCK_DISCARD and WINED3DLOCK_NOOVERWRITE used together, ignoring\n"); WARN("WINED3DLOCK_DISCARD and WINED3DLOCK_NOOVERWRITE used together, ignoring\n");
return 0; return 0;
} }
else if (flags & (WINED3DLOCK_DISCARD | WINED3DLOCK_NOOVERWRITE) && !(buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
{
WARN("DISCARD or NOOVERWRITE lock on non-dynamic buffer, ignoring\n");
return 0;
}
return flags; return flags;
} }
@ -1085,7 +1090,7 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset,
TRACE("iface %p, offset %u, size %u, data %p, flags %#x\n", iface, offset, size, data, flags); TRACE("iface %p, offset %u, size %u, data %p, flags %#x\n", iface, offset, size, data, flags);
flags = buffer_sanitize_flags(flags); flags = buffer_sanitize_flags(This, flags);
if (!(flags & WINED3DLOCK_READONLY)) if (!(flags & WINED3DLOCK_READONLY))
{ {
if (!buffer_add_dirty_area(This, offset, size)) return E_OUTOFMEMORY; if (!buffer_add_dirty_area(This, offset, size)) return E_OUTOFMEMORY;