[PATCH v2 3/6] ddraw: Sync draw texture for drawing.

Paul Gofman pgofman at codeweavers.com
Thu Feb 25 17:20:11 CST 2021


Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
 dlls/ddraw/ddraw_private.h |  2 ++
 dlls/ddraw/device.c        | 58 +++++++++++++++++++++++++++++++++++---
 dlls/ddraw/executebuffer.c |  3 ++
 3 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index c6fb8d5f3a3..0c65b9940ba 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -708,6 +708,8 @@ static inline struct wined3d_texture *ddraw_surface_get_any_texture(struct ddraw
     return ddraw_surface_get_draw_texture(surface, flags);
 }
 
+void d3d_device_sync_surfaces(struct d3d_device *device) DECLSPEC_HIDDEN;
+
 /* Used for generic dumping */
 struct flag_info
 {
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index ea81972064e..00ee9bbbfa4 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -3427,6 +3427,47 @@ static HRESULT d3d_device_prepare_vertex_buffer(struct d3d_device *device, UINT
     return D3D_OK;
 }
 
+static void d3d_device_sync_rendertarget(struct d3d_device *device)
+{
+    struct wined3d_rendertarget_view *rtv;
+
+    if (device->hardware_device)
+        return;
+
+    if ((rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
+        ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(rtv), DDRAW_SURFACE_RW);
+
+    if ((rtv = wined3d_device_get_depth_stencil_view(device->wined3d_device)))
+        ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(rtv), DDRAW_SURFACE_RW);
+}
+
+void d3d_device_sync_surfaces(struct d3d_device *device)
+{
+    const struct wined3d_stateblock_state *state = device->stateblock_state;
+    struct ddraw_surface *surface;
+    unsigned int i, j;
+
+    if (device->hardware_device)
+        return;
+
+    d3d_device_sync_rendertarget(device);
+
+    for (i = 0; i < ARRAY_SIZE(state->textures); ++i)
+    {
+        if (!state->textures[i])
+            continue;
+
+        j = 0;
+        while ((surface = wined3d_texture_get_sub_resource_parent(state->textures[i], j)))
+        {
+            if (!surface->draw_texture)
+                break;
+            ddraw_surface_get_draw_texture(surface, DDRAW_SURFACE_READ);
+            ++j;
+        }
+    }
+}
+
 static HRESULT d3d_device7_DrawPrimitive(IDirect3DDevice7 *iface,
         D3DPRIMITIVETYPE primitive_type, DWORD fvf, void *vertices,
         DWORD vertex_count, DWORD flags)
@@ -3481,6 +3522,7 @@ static HRESULT d3d_device7_DrawPrimitive(IDirect3DDevice7 *iface,
     wined3d_stateblock_set_vertex_declaration(device->state, ddraw_find_decl(device->ddraw, fvf));
     wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0);
     wined3d_device_apply_stateblock(device->wined3d_device, device->state);
+    d3d_device_sync_surfaces(device);
     hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vertex_count);
 
 done:
@@ -3693,6 +3735,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
     wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0);
     wined3d_stateblock_set_base_vertex_index(device->state, vb_pos / stride);
     wined3d_device_apply_stateblock(device->wined3d_device, device->state);
+    d3d_device_sync_surfaces(device);
     hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(*indices), index_count);
 
 done:
@@ -4019,6 +4062,7 @@ static HRESULT d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, D3DPRIM
 
     wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0);
     wined3d_device_apply_stateblock(device->wined3d_device, device->state);
+    d3d_device_sync_surfaces(device);
     hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / dst_stride, vertex_count);
 
 done:
@@ -4155,6 +4199,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
     wined3d_stateblock_set_vertex_declaration(device->state, ddraw_find_decl(device->ddraw, fvf));
     wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0);
     wined3d_device_apply_stateblock(device->wined3d_device, device->state);
+    d3d_device_sync_surfaces(device);
     hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), index_count);
 
 done:
@@ -4277,6 +4322,7 @@ static HRESULT d3d_device7_DrawPrimitiveVB(IDirect3DDevice7 *iface, D3DPRIMITIVE
     /* Now draw the primitives */
     wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0);
     wined3d_device_apply_stateblock(device->wined3d_device, device->state);
+    d3d_device_sync_surfaces(device);
     hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, vertex_count);
 
     wined3d_mutex_unlock();
@@ -4431,6 +4477,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
 
     wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0);
     wined3d_device_apply_stateblock(device->wined3d_device, device->state);
+    d3d_device_sync_surfaces(device);
     hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), index_count);
 
     wined3d_mutex_unlock();
@@ -4778,7 +4825,7 @@ static HRESULT d3d_device7_SetTexture(IDirect3DDevice7 *iface,
     TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture);
 
     if (surf && (surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE))
-        wined3d_texture = surf->wined3d_texture;
+        wined3d_texture = ddraw_surface_get_draw_texture(surf, 0);
 
     wined3d_mutex_lock();
     wined3d_stateblock_set_texture(device->update_state, stage, wined3d_texture);
@@ -5270,6 +5317,7 @@ static HRESULT d3d_device7_Clear(IDirect3DDevice7 *iface, DWORD count,
 
     wined3d_mutex_lock();
     wined3d_device_apply_stateblock(device->wined3d_device, device->state);
+    d3d_device_sync_rendertarget(device);
     hr = wined3d_device_clear(device->wined3d_device, count, (RECT *)rects, flags, &c, z, stencil);
     wined3d_mutex_unlock();
 
@@ -5732,7 +5780,7 @@ static HRESULT d3d_device7_PreLoad(IDirect3DDevice7 *iface, IDirectDrawSurface7
         return DDERR_INVALIDPARAMS;
 
     wined3d_mutex_lock();
-    wined3d_resource_preload(wined3d_texture_get_resource(surface->wined3d_texture));
+    wined3d_resource_preload(wined3d_texture_get_resource(ddraw_surface_get_draw_texture(surface, 0)));
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -6122,8 +6170,10 @@ static void copy_mipmap_chain(struct d3d_device *device, struct ddraw_surface *d
             UINT src_h = src_rect.bottom - src_rect.top;
             RECT dst_rect = {point.x, point.y, point.x + src_w, point.y + src_h};
 
-            if (FAILED(hr = wined3d_texture_blt(dst_level->wined3d_texture, dst_level->sub_resource_idx, &dst_rect,
-                    src_level->wined3d_texture, src_level->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT)))
+            if (FAILED(hr = wined3d_texture_blt(ddraw_surface_get_any_texture(dst_level, DDRAW_SURFACE_RW),
+                    dst_level->sub_resource_idx, &dst_rect,
+                    ddraw_surface_get_any_texture(src_level, DDRAW_SURFACE_READ),
+                    src_level->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT)))
                 ERR("Blit failed, hr %#x.\n", hr);
 
             ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c
index e0a9445bf71..d87878883c7 100644
--- a/dlls/ddraw/executebuffer.c
+++ b/dlls/ddraw/executebuffer.c
@@ -81,6 +81,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d
                         ddraw_find_decl(device->ddraw, D3DFVF_TLVERTEX));
 
                 wined3d_device_apply_stateblock(device->wined3d_device, device->state);
+                d3d_device_sync_surfaces(device);
                 for (i = 0; i < count; ++i)
                     wined3d_device_draw_primitive(device->wined3d_device, p[i].wFirst, p[i].wCount);
 
@@ -189,6 +190,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d
                         ddraw_find_decl(device->ddraw, D3DFVF_TLVERTEX));
                 wined3d_stateblock_set_index_buffer(device->state, buffer->index_buffer, WINED3DFMT_R16_UINT);
                 wined3d_device_apply_stateblock(device->wined3d_device, device->state);
+                d3d_device_sync_surfaces(device);
                 wined3d_device_draw_indexed_primitive(device->wined3d_device, index_pos, index_count);
 
                 buffer->index_pos = index_pos + index_count;
@@ -310,6 +312,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d
                                     ddraw_find_decl(device->ddraw, op == D3DPROCESSVERTICES_TRANSFORMLIGHT
                                     ? D3DFVF_VERTEX : D3DFVF_LVERTEX));
                             wined3d_device_apply_stateblock(device->wined3d_device, device->state);
+                            d3d_device_sync_surfaces(device);
                             wined3d_device_process_vertices(device->wined3d_device, ci->wStart, ci->wDest,
                                     ci->dwCount, buffer->dst_vertex_buffer, NULL, 0, D3DFVF_TLVERTEX);
                             break;
-- 
2.29.2




More information about the wine-devel mailing list