From: Paul Gofman Subject: [PATCH 3/6] ddraw: Sync draw texture for drawing. Message-Id: <20210225222301.933270-3-pgofman@codeweavers.com> Date: Fri, 26 Feb 2021 01:22:58 +0300 In-Reply-To: <20210225222301.933270-1-pgofman@codeweavers.com> References: <20210225222301.933270-1-pgofman@codeweavers.com> Signed-off-by: Paul Gofman --- 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 5e5856b5916..882044b1dee 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -714,6 +714,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 4fe75d36545..8a9a084e1f9 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -3437,6 +3437,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) @@ -3491,6 +3532,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: @@ -3703,6 +3745,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: @@ -4029,6 +4072,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: @@ -4165,6 +4209,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: @@ -4287,6 +4332,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(); @@ -4441,6 +4487,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(); @@ -4788,7 +4835,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); @@ -5280,6 +5327,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(); @@ -5742,7 +5790,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; @@ -6132,8 +6180,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 f1a0d7c6d40..6ae0ad07af9 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -154,6 +154,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, 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); @@ -316,6 +317,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, 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); } @@ -438,6 +440,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, 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