From: Zebediah Figura zfigura@codeweavers.com
As for d3d8. --- dlls/d3d9/buffer.c | 29 ++++---------------- dlls/d3d9/d3d9_private.h | 2 +- dlls/d3d9/device.c | 59 ++++++++++++++++++++++------------------ 3 files changed, 38 insertions(+), 52 deletions(-)
diff --git a/dlls/d3d9/buffer.c b/dlls/d3d9/buffer.c index bcb97011fe5..0ffb48a66c8 100644 --- a/dlls/d3d9/buffer.c +++ b/dlls/d3d9/buffer.c @@ -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)) { diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index c3eb9728f6e..eb01b15338a 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -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, diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 0995eb7f2c4..9f071d7a8d2 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -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;