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