Commit c93440b7 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

d3d9: Upload mapped dynamic vertex and index buffers before every draw.

parent 346f783c
......@@ -3120,6 +3120,17 @@ static HRESULT d3d9_device_upload_sysmem_index_buffer(struct d3d9_device *device
return S_OK;
}
static void d3d9_device_flush_mapped_vertex_buffers(struct d3d9_device *device)
{
for (unsigned int i = 0; i < WINED3D_MAX_STREAMS; ++i)
{
struct wined3d_buffer *buffer = device->stateblock_state->streams[i].buffer;
if (buffer)
wined3d_device_context_flush_mapped_buffer(device->immediate_context, buffer);
}
}
static void d3d9_device_upload_managed_textures(struct d3d9_device *device)
{
const struct wined3d_stateblock_state *state = device->stateblock_state;
......@@ -3159,6 +3170,7 @@ static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface,
vertex_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
d3d9_device_upload_managed_textures(device);
d3d9_device_upload_sysmem_vertex_buffers(device, 0, start_vertex, vertex_count);
d3d9_device_flush_mapped_vertex_buffers(device);
d3d9_generate_auto_mipmaps(device);
wined3d_device_context_set_primitive_type(device->immediate_context,
wined3d_primitive_type_from_d3d(primitive_type), 0);
......@@ -3200,11 +3212,13 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface
index_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
d3d9_device_upload_managed_textures(device);
d3d9_device_upload_sysmem_vertex_buffers(device, base_vertex_idx, min_vertex_idx, vertex_count);
d3d9_device_flush_mapped_vertex_buffers(device);
d3d9_generate_auto_mipmaps(device);
wined3d_device_context_set_primitive_type(device->immediate_context,
wined3d_primitive_type_from_d3d(primitive_type), 0);
wined3d_device_apply_stateblock(device->wined3d_device, device->state);
d3d9_device_upload_sysmem_index_buffer(device, &start_idx, index_count);
wined3d_device_context_flush_mapped_buffer(device->immediate_context, device->stateblock_state->index_buffer);
wined3d_device_context_draw_indexed(device->immediate_context, base_vertex_idx, start_idx, index_count, 0,
device->stateblock_state->streams[0].frequency);
d3d9_rts_flag_auto_gen_mipmap(device);
......
......@@ -26720,7 +26720,6 @@ static void test_draw_mapped_buffer(void)
unsigned int color, i;
IDirect3D9 *d3d;
ULONG refcount;
BOOL test_pass;
HWND window;
HRESULT hr;
void *data;
......@@ -26741,11 +26740,10 @@ static void test_draw_mapped_buffer(void)
{
D3DPOOL pool;
DWORD usage;
BOOL ignore_wine_result;
}
tests[] =
{
{D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, TRUE},
{D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC},
{D3DPOOL_MANAGED, 0},
{D3DPOOL_SYSTEMMEM, 0},
};
......@@ -26825,11 +26823,7 @@ static void test_draw_mapped_buffer(void)
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
color = getPixelColor(device, 160, 120);
test_pass = color_match(color, 0x00ff0000, 1);
todo_wine_if(tests[i].ignore_wine_result && !test_pass)
ok(test_pass, "Got unexpected color 0x%08x, test %u.\n", color, i);
ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x, test %u.\n", color, i);
color = getPixelColor(device, 480, 360);
ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x, test %u.\n", color, i);
......@@ -27458,7 +27452,7 @@ static void test_dynamic_map_synchronization(void)
hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
ok(hr == S_OK, "Failed to get render target, hr %#lx.\n", hr);
check_rt_color_todo(rt, 0x0000ff00);
check_rt_color(rt, 0x0000ff00);
IDirect3DSurface9_Release(rt);
IDirect3DVertexBuffer9_Release(buffer);
......@@ -3459,6 +3459,34 @@ static DWORD WINAPI wined3d_cs_run(void *ctx)
FreeLibraryAndExitThread(wined3d_module, 0);
}
void CDECL wined3d_device_context_flush_mapped_buffer(struct wined3d_device_context *context,
struct wined3d_buffer *buffer)
{
struct wined3d_client_resource *client = &buffer->resource.client;
/* d3d9 applications can draw from a mapped dynamic buffer.
* Castlevania 2 depends on this behaviour.
* This means that we need to upload a pending discard bo, without actually
* unmapping it. */
assert(context == &context->device->cs->c);
if (wined3d_bo_address_is_null(&client->mapped_upload.addr))
return;
if (client->mapped_upload.flags & UPLOAD_BO_UPLOAD_ON_UNMAP)
wined3d_device_context_upload_bo(context, &buffer->resource, 0,
&client->mapped_box, &client->mapped_upload, buffer->resource.size, buffer->resource.size);
if (client->mapped_upload.flags & UPLOAD_BO_RENAME_ON_UNMAP)
{
client->mapped_upload.flags &= ~UPLOAD_BO_RENAME_ON_UNMAP;
/* This logic matches wined3d_cs_map_upload_bo(). */
if (client->mapped_upload.addr.buffer_object->coherent && wined3d_map_persistent())
client->mapped_upload.flags &= ~UPLOAD_BO_UPLOAD_ON_UNMAP;
}
}
struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device,
const enum wined3d_feature_level *levels, unsigned int level_count)
{
......
......@@ -103,6 +103,7 @@
@ cdecl wined3d_device_context_draw_indirect(ptr ptr long long)
@ cdecl wined3d_device_context_execute_command_list(ptr ptr long)
@ cdecl wined3d_device_context_flush(ptr)
@ cdecl wined3d_device_context_flush_mapped_buffer(ptr ptr)
@ cdecl wined3d_device_context_generate_mipmaps(ptr ptr)
@ cdecl wined3d_device_context_get_blend_state(ptr ptr ptr)
@ cdecl wined3d_device_context_get_constant_buffer(ptr long long ptr)
......
......@@ -2458,6 +2458,8 @@ void __cdecl wined3d_device_context_draw_indirect(struct wined3d_device_context
void __cdecl wined3d_device_context_execute_command_list(struct wined3d_device_context *context,
struct wined3d_command_list *list, bool restore_state);
void __cdecl wined3d_device_context_flush(struct wined3d_device_context *context);
void __cdecl wined3d_device_context_flush_mapped_buffer(struct wined3d_device_context *context,
struct wined3d_buffer *buffer);
void __cdecl wined3d_device_context_generate_mipmaps(struct wined3d_device_context *context,
struct wined3d_shader_resource_view *view);
struct wined3d_blend_state * __cdecl wined3d_device_context_get_blend_state(
......
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