mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 09:35:52 +00:00
d3d8: Filter out redundant buffer discards.
I was unable to write tests for this; it seems it doesn't consistently work on Windows. However, Rayman 3 seems to rely on it; it maps the same buffer twice immediately after creation, with DISCARD flags on both maps, and expects the same address to be returned. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53752
This commit is contained in:
parent
c96d34e86e
commit
379ae701c0
|
@ -192,6 +192,11 @@ static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface, UINT
|
|||
TRACE("iface %p, offset %u, size %u, data %p, flags %#lx.\n",
|
||||
iface, offset, size, data, flags);
|
||||
|
||||
if (buffer->discarded)
|
||||
flags &= ~D3DLOCK_DISCARD;
|
||||
if (flags & D3DLOCK_DISCARD)
|
||||
buffer->discarded = true;
|
||||
|
||||
wined3d_box.left = offset;
|
||||
wined3d_box.right = offset + size;
|
||||
wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
|
||||
|
@ -508,6 +513,11 @@ static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface, UINT o
|
|||
TRACE("iface %p, offset %u, size %u, data %p, flags %#lx.\n",
|
||||
iface, offset, size, data, flags);
|
||||
|
||||
if (buffer->discarded)
|
||||
flags &= ~D3DLOCK_DISCARD;
|
||||
if (flags & D3DLOCK_DISCARD)
|
||||
buffer->discarded = true;
|
||||
|
||||
wined3d_box.left = offset;
|
||||
wined3d_box.right = offset + size;
|
||||
wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
|
||||
|
|
|
@ -217,6 +217,7 @@ struct d3d8_vertexbuffer
|
|||
IDirect3DDevice8 *parent_device;
|
||||
struct wined3d_buffer *draw_buffer;
|
||||
DWORD fvf, usage;
|
||||
bool discarded;
|
||||
};
|
||||
|
||||
HRESULT vertexbuffer_init(struct d3d8_vertexbuffer *buffer, struct d3d8_device *device,
|
||||
|
@ -232,6 +233,7 @@ struct d3d8_indexbuffer
|
|||
enum wined3d_format_id format;
|
||||
DWORD usage;
|
||||
bool sysmem;
|
||||
bool discarded;
|
||||
};
|
||||
|
||||
HRESULT indexbuffer_init(struct d3d8_indexbuffer *buffer, struct d3d8_device *device,
|
||||
|
|
|
@ -2516,7 +2516,8 @@ static HRESULT WINAPI d3d8_device_DrawPrimitive(IDirect3DDevice8 *iface,
|
|||
D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count)
|
||||
{
|
||||
struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
|
||||
unsigned int vertex_count;
|
||||
struct d3d8_vertexbuffer *vb;
|
||||
unsigned int vertex_count, i;
|
||||
|
||||
TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n",
|
||||
iface, primitive_type, start_vertex, primitive_count);
|
||||
|
@ -2529,6 +2530,16 @@ static HRESULT WINAPI d3d8_device_DrawPrimitive(IDirect3DDevice8 *iface,
|
|||
wined3d_primitive_type_from_d3d(primitive_type), 0);
|
||||
wined3d_device_apply_stateblock(device->wined3d_device, device->state);
|
||||
wined3d_device_context_draw(device->immediate_context, start_vertex, vertex_count, 0, 0);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(device->stateblock_state->streams); ++i)
|
||||
{
|
||||
if (device->stateblock_state->streams[i].buffer)
|
||||
{
|
||||
vb = wined3d_buffer_get_parent(device->stateblock_state->streams[i].buffer);
|
||||
vb->discarded = false;
|
||||
}
|
||||
}
|
||||
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
return D3D_OK;
|
||||
|
@ -2539,7 +2550,9 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitive(IDirect3DDevice8 *iface,
|
|||
UINT start_idx, UINT primitive_count)
|
||||
{
|
||||
struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
|
||||
unsigned int index_count;
|
||||
struct d3d8_vertexbuffer *vb;
|
||||
struct d3d8_indexbuffer *ib;
|
||||
unsigned int index_count, i;
|
||||
int base_vertex_index;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -2567,6 +2580,17 @@ static HRESULT WINAPI d3d8_device_DrawIndexedPrimitive(IDirect3DDevice8 *iface,
|
|||
}
|
||||
wined3d_device_context_draw_indexed(device->immediate_context, base_vertex_index, start_idx, index_count, 0, 0);
|
||||
|
||||
ib = wined3d_buffer_get_parent(device->stateblock_state->index_buffer);
|
||||
ib->discarded = false;
|
||||
for (i = 0; i < ARRAY_SIZE(device->stateblock_state->streams); ++i)
|
||||
{
|
||||
if (device->stateblock_state->streams[i].buffer)
|
||||
{
|
||||
vb = wined3d_buffer_get_parent(device->stateblock_state->streams[i].buffer);
|
||||
vb->discarded = false;
|
||||
}
|
||||
}
|
||||
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
return D3D_OK;
|
||||
|
|
Loading…
Reference in a new issue