Commit 66f37aae authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

d3d9: Upload sysmem vertex buffers into the streaming buffer in d3d9_device_DrawPrimitive().

As for d3d8.
parent 50b67f98
......@@ -384,10 +384,7 @@ static ULONG WINAPI d3d9_indexbuffer_AddRef(IDirect3DIndexBuffer9 *iface)
if (refcount == 1)
{
IDirect3DDevice9Ex_AddRef(buffer->parent_device);
if (buffer->draw_buffer)
wined3d_buffer_incref(buffer->draw_buffer);
else
wined3d_buffer_incref(buffer->wined3d_buffer);
wined3d_buffer_incref(buffer->wined3d_buffer);
}
return refcount;
......@@ -402,13 +399,9 @@ static ULONG WINAPI d3d9_indexbuffer_Release(IDirect3DIndexBuffer9 *iface)
if (!refcount)
{
struct wined3d_buffer *draw_buffer = buffer->draw_buffer;
IDirect3DDevice9Ex *device = buffer->parent_device;
if (draw_buffer)
wined3d_buffer_decref(draw_buffer);
else
wined3d_buffer_decref(buffer->wined3d_buffer);
wined3d_buffer_decref(buffer->wined3d_buffer);
/* Release the device last, as it may cause the device to be destroyed. */
IDirect3DDevice9Ex_Release(device);
......@@ -589,8 +582,6 @@ static void STDMETHODCALLTYPE d3d9_indexbuffer_wined3d_object_destroyed(void *pa
{
struct d3d9_indexbuffer *buffer = parent;
if (buffer->draw_buffer)
wined3d_buffer_decref(buffer->wined3d_buffer);
d3d9_resource_cleanup(&buffer->resource);
heap_free(buffer);
}
......@@ -603,7 +594,6 @@ static const struct wined3d_parent_ops d3d9_indexbuffer_wined3d_parent_ops =
HRESULT indexbuffer_init(struct d3d9_indexbuffer *buffer, struct d3d9_device *device,
UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
{
const struct wined3d_parent_ops *parent_ops = &d3d9_null_wined3d_parent_ops;
struct wined3d_buffer_desc desc;
HRESULT hr;
......@@ -631,26 +621,17 @@ HRESULT indexbuffer_init(struct d3d9_indexbuffer *buffer, struct d3d9_device *de
desc.structure_byte_stride = 0;
if (desc.access & WINED3D_RESOURCE_ACCESS_GPU)
{
desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
parent_ops = &d3d9_indexbuffer_wined3d_parent_ops;
}
buffer->IDirect3DIndexBuffer9_iface.lpVtbl = &d3d9_indexbuffer_vtbl;
buffer->format = wined3dformat_from_d3dformat(format);
buffer->usage = usage;
buffer->sysmem = !(desc.access & WINED3D_RESOURCE_ACCESS_GPU);
d3d9_resource_init(&buffer->resource);
wined3d_mutex_lock();
hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, parent_ops, &buffer->wined3d_buffer);
if (SUCCEEDED(hr) && !(desc.access & WINED3D_RESOURCE_ACCESS_GPU))
{
desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
desc.access = WINED3D_RESOURCE_ACCESS_GPU;
if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer,
&d3d9_indexbuffer_wined3d_parent_ops, &buffer->draw_buffer)))
wined3d_buffer_decref(buffer->wined3d_buffer);
}
hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer,
&d3d9_indexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
wined3d_mutex_unlock();
if (FAILED(hr))
{
......
......@@ -206,9 +206,9 @@ struct d3d9_indexbuffer
struct d3d9_resource resource;
struct wined3d_buffer *wined3d_buffer;
IDirect3DDevice9Ex *parent_device;
struct wined3d_buffer *draw_buffer;
enum wined3d_format_id format;
DWORD usage;
bool sysmem;
};
HRESULT indexbuffer_init(struct d3d9_indexbuffer *buffer, struct d3d9_device *device,
......
......@@ -1002,7 +1002,7 @@ static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource)
if (desc.bind_flags & WINED3D_BIND_INDEX_BUFFER)
{
index_buffer = wined3d_resource_get_parent(resource);
if (index_buffer && index_buffer->draw_buffer)
if (index_buffer && index_buffer->sysmem)
return D3D_OK;
}
......@@ -2969,34 +2969,41 @@ static void d3d9_device_upload_sysmem_vertex_buffers(struct d3d9_device *device,
}
}
static void d3d9_device_upload_sysmem_index_buffer(struct d3d9_device *device,
unsigned int start_idx, unsigned int idx_count)
static HRESULT d3d9_device_upload_sysmem_index_buffer(struct d3d9_device *device,
unsigned int *start_idx, unsigned int idx_count)
{
const struct wined3d_stateblock_state *state = device->stateblock_state;
struct wined3d_box box = {0, 0, 0, 1, 0, 1};
struct wined3d_resource *dst_resource;
struct d3d9_indexbuffer *d3d9_buffer;
struct wined3d_buffer *dst_buffer;
struct wined3d_resource_desc desc;
enum wined3d_format_id format;
unsigned int idx_size;
unsigned int src_offset, idx_size, buffer_size, pos;
struct wined3d_resource_desc resource_desc;
struct wined3d_resource *index_buffer;
struct wined3d_map_desc map_desc;
struct wined3d_box box;
HRESULT hr;
if (!device->sysmem_ib)
return;
return S_OK;
dst_buffer = state->index_buffer;
format = state->index_format;
d3d9_buffer = wined3d_buffer_get_parent(dst_buffer);
dst_resource = wined3d_buffer_get_resource(dst_buffer);
wined3d_resource_get_desc(dst_resource, &desc);
idx_size = format == WINED3DFMT_R16_UINT ? 2 : 4;
box.left = start_idx * idx_size;
box.right = min(box.left + idx_count * idx_size, desc.size);
if (FAILED(hr = wined3d_device_context_copy_sub_resource_region(device->immediate_context,
dst_resource, 0, box.left, 0, 0,
wined3d_buffer_get_resource(d3d9_buffer->wined3d_buffer), 0, &box, 0)))
ERR("Failed to update buffer.\n");
index_buffer = wined3d_buffer_get_resource(state->index_buffer);
wined3d_resource_get_desc(index_buffer, &resource_desc);
idx_size = (state->index_format == WINED3DFMT_R16_UINT) ? 2 : 4;
src_offset = (*start_idx) * idx_size;
buffer_size = min(idx_count * idx_size, resource_desc.size - src_offset);
wined3d_box_set(&box, src_offset, 0, buffer_size, 1, 0, 1);
if (FAILED(hr = wined3d_resource_map(index_buffer, 0, &map_desc, &box, WINED3D_MAP_READ)))
{
wined3d_mutex_unlock();
return hr;
}
wined3d_streaming_buffer_upload(device->wined3d_device, &device->index_buffer,
map_desc.data, buffer_size, idx_size, &pos);
wined3d_resource_unmap(index_buffer, 0);
wined3d_device_context_set_index_buffer(device->immediate_context,
device->index_buffer.buffer, state->index_format, pos);
*start_idx = 0;
return S_OK;
}
static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface,
......@@ -3055,11 +3062,11 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface
}
index_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
d3d9_device_upload_sysmem_vertex_buffers(device, base_vertex_idx, min_vertex_idx, vertex_count);
d3d9_device_upload_sysmem_index_buffer(device, start_idx, index_count);
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_draw_indexed(device->immediate_context, base_vertex_idx, start_idx, index_count, 0, 0);
d3d9_rts_flag_auto_gen_mipmap(device);
wined3d_mutex_unlock();
......@@ -3745,15 +3752,13 @@ static HRESULT WINAPI d3d9_device_SetIndices(IDirect3DDevice9Ex *iface, IDirect3
if (!ib)
wined3d_buffer = NULL;
else if (ib->draw_buffer)
wined3d_buffer = ib->draw_buffer;
else
wined3d_buffer = ib->wined3d_buffer;
wined3d_mutex_lock();
wined3d_stateblock_set_index_buffer(device->update_state, wined3d_buffer, ib ? ib->format : WINED3DFMT_UNKNOWN);
if (!device->recording)
device->sysmem_ib = ib && ib->draw_buffer;
device->sysmem_ib = ib && ib->sysmem;
wined3d_mutex_unlock();
return D3D_OK;
......
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