Zebediah Figura : d3d9: Upload sysmem vertex buffers into the streaming buffer in d3d9_device_DrawPrimitive().
Alexandre Julliard
julliard at winehq.org
Wed Jul 13 16:54:56 CDT 2022
Module: wine
Branch: master
Commit: 66f37aae7e25740857aeb8ea9c2f0395781389f5
URL: https://gitlab.winehq.org/wine/wine/-/commit/66f37aae7e25740857aeb8ea9c2f0395781389f5
Author: Zebediah Figura <zfigura at codeweavers.com>
Date: Fri Jul 8 18:33:33 2022 -0500
d3d9: Upload sysmem vertex buffers into the streaming buffer in d3d9_device_DrawPrimitive().
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;
More information about the wine-cvs
mailing list