ddraw: Store wined3d state in d3d_device.

This commit is contained in:
Paul Gofman 2024-03-19 11:27:42 -06:00 committed by Alexandre Julliard
parent 9492a10f44
commit aa8487a4b3
8 changed files with 79 additions and 55 deletions

View file

@ -437,7 +437,6 @@ static void ddraw_destroy(struct ddraw *This)
if (This->wined3d_swapchain)
ddraw_destroy_swapchain(This);
wined3d_stateblock_decref(This->state);
wined3d_device_decref(This->wined3d_device);
wined3d_decref(This->wined3d);
@ -797,6 +796,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
struct wined3d_rendertarget_view *rtv = NULL, *dsv = NULL;
struct wined3d_stateblock *stateblock;
BOOL restore_state = FALSE;
struct d3d_device *device;
RECT clip_rect;
HRESULT hr;
@ -924,14 +924,15 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (cooplevel & DDSCL_MULTITHREADED && !(ddraw->cooperative_level & DDSCL_MULTITHREADED))
wined3d_device_set_multithreaded(ddraw->wined3d_device);
device = ddraw->d3ddevice;
if (ddraw->wined3d_swapchain)
{
if (!(ddraw->flags & DDRAW_NO3D))
if (!(ddraw->flags & DDRAW_NO3D) && device)
{
restore_state = TRUE;
if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device,
ddraw->state, WINED3D_SBT_ALL, &stateblock)))
device->state, WINED3D_SBT_ALL, &stateblock)))
{
ERR("Failed to create stateblock, hr %#lx.\n", hr);
goto done;
@ -968,7 +969,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
wined3d_rendertarget_view_decref(rtv);
}
wined3d_stateblock_apply(stateblock, ddraw->state);
wined3d_stateblock_apply(stateblock, device->state);
wined3d_stateblock_decref(stateblock);
}
@ -5127,15 +5128,5 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de
ddraw->immediate_context = wined3d_device_get_immediate_context(ddraw->wined3d_device);
list_init(&ddraw->surface_list);
if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device, NULL, WINED3D_SBT_PRIMARY, &ddraw->state)))
{
ERR("Failed to create the primary stateblock, hr %#lx.\n", hr);
wined3d_device_decref(ddraw->wined3d_device);
wined3d_decref(ddraw->wined3d);
return hr;
}
ddraw->stateblock_state = wined3d_stateblock_get_state(ddraw->state);
return DD_OK;
}

View file

@ -132,9 +132,6 @@ struct ddraw
struct FvfToDecl *decls;
UINT numConvertedDecls, declArraySize;
struct wined3d_stateblock *state;
const struct wined3d_stateblock_state *stateblock_state;
unsigned int frames;
DWORD prev_frame_time;
};

View file

@ -284,10 +284,6 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
wined3d_device_context_set_rendertarget_views(This->immediate_context, 0, 1, &null_rtv, FALSE);
wined3d_stateblock_decref(This->state);
if (This->recording)
wined3d_stateblock_decref(This->recording);
/* Release the wined3d device. This won't destroy it. */
if (!wined3d_device_decref(This->wined3d_device))
ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This->wined3d_device);
@ -325,6 +321,18 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
IDirect3DDevice3_DeleteViewport(&This->IDirect3DDevice3_iface, &vp->IDirect3DViewport3_iface);
}
wined3d_stateblock_decref(This->state);
if (This->recording)
wined3d_stateblock_decref(This->recording);
/* Releasing the render target below may release the last reference to the ddraw object. Detach
* the device from it before so it doesn't try to save / restore state on the teared down device. */
if (This->ddraw)
{
This->ddraw->d3ddevice = NULL;
This->ddraw = NULL;
}
TRACE("Releasing render target %p.\n", This->rt_iface);
rt_iface = This->rt_iface;
This->rt_iface = NULL;
@ -332,11 +340,6 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
IUnknown_Release(rt_iface);
TRACE("Render target release done.\n");
/* Releasing the render target above may have released the last
* reference to the ddraw object. */
if (This->ddraw)
This->ddraw->d3ddevice = NULL;
/* Now free the structure */
free(This);
wined3d_mutex_unlock();
@ -6776,15 +6779,15 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device
return WINED3D_ZB_TRUE;
}
static void ddraw_reset_viewport_state(struct ddraw *ddraw)
static void device_reset_viewport_state(struct d3d_device *device)
{
struct wined3d_viewport vp;
RECT rect;
wined3d_device_context_get_viewports(ddraw->immediate_context, NULL, &vp);
wined3d_stateblock_set_viewport(ddraw->state, &vp);
wined3d_device_context_get_scissor_rects(ddraw->immediate_context, NULL, &rect);
wined3d_stateblock_set_scissor_rect(ddraw->state, &rect);
wined3d_device_context_get_viewports(device->immediate_context, NULL, &vp);
wined3d_stateblock_set_viewport(device->state, &vp);
wined3d_device_context_get_scissor_rects(device->immediate_context, NULL, &rect);
wined3d_stateblock_set_scissor_rect(device->state, &rect);
}
static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, const GUID *guid,
@ -6838,13 +6841,19 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c
device->legacy_projection = ident;
device->legacy_clipspace = ident;
if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device, NULL, WINED3D_SBT_PRIMARY, &device->state)))
{
ERR("Failed to create the primary stateblock, hr %#lx.\n", hr);
ddraw_handle_table_destroy(&device->handle_table);
return hr;
}
device->stateblock_state = wined3d_stateblock_get_state(device->state);
device->update_state = device->state;
/* This is for convenience. */
device->wined3d_device = ddraw->wined3d_device;
device->immediate_context = ddraw->immediate_context;
wined3d_device_incref(ddraw->wined3d_device);
device->update_state = device->state = ddraw->state;
device->stateblock_state = ddraw->stateblock_state;
wined3d_stateblock_incref(ddraw->state);
wined3d_streaming_buffer_init(&device->vertex_buffer, WINED3D_BIND_VERTEX_BUFFER);
wined3d_streaming_buffer_init(&device->index_buffer, WINED3D_BIND_INDEX_BUFFER);
@ -6865,19 +6874,19 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c
ddraw->d3ddevice = device;
wined3d_stateblock_set_render_state(ddraw->state, WINED3D_RS_ZENABLE,
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE,
d3d_device_update_depth_stencil(device));
if (version == 1) /* Color keying is initially enabled for version 1 devices. */
wined3d_stateblock_set_render_state(ddraw->state, WINED3D_RS_COLORKEYENABLE, TRUE);
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_COLORKEYENABLE, TRUE);
else if (version == 2)
wined3d_stateblock_set_render_state(ddraw->state, WINED3D_RS_SPECULARENABLE, TRUE);
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_SPECULARENABLE, TRUE);
if (version < 7)
{
wined3d_stateblock_set_render_state(ddraw->state, WINED3D_RS_NORMALIZENORMALS, TRUE);
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_NORMALIZENORMALS, TRUE);
IDirect3DDevice3_SetRenderState(&device->IDirect3DDevice3_iface,
D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
}
ddraw_reset_viewport_state(ddraw);
device_reset_viewport_state(device);
return D3D_OK;
}

View file

@ -4346,7 +4346,7 @@ static HRESULT WINAPI ddraw_surface4_GetUniquenessValue(IDirectDrawSurface4 *ifa
static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD MaxLOD)
{
struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
HRESULT hr;
struct d3d_device *device;
TRACE("iface %p, lod %lu.\n", iface, MaxLOD);
@ -4357,12 +4357,18 @@ static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD Ma
return DDERR_INVALIDOBJECT;
}
hr = wined3d_stateblock_set_texture_lod(surface->ddraw->state, surface->wined3d_texture, MaxLOD);
if (SUCCEEDED(hr) && surface->draw_texture)
hr = wined3d_stateblock_set_texture_lod(surface->ddraw->state, surface->draw_texture, MaxLOD);
wined3d_mutex_unlock();
wined3d_texture_set_lod(surface->wined3d_texture, MaxLOD);
if (surface->draw_texture)
wined3d_texture_set_lod(surface->draw_texture, MaxLOD);
return hr;
if ((device = surface->ddraw->d3ddevice))
{
wined3d_stateblock_texture_changed(device->state, surface->wined3d_texture);
if (surface->draw_texture)
wined3d_stateblock_texture_changed(device->state, surface->draw_texture);
}
wined3d_mutex_unlock();
return DD_OK;
}
/*****************************************************************************
@ -6761,20 +6767,21 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
if (ddraw->cooperative_level & DDSCL_EXCLUSIVE)
{
struct wined3d_swapchain_desc swapchain_desc;
struct d3d_device *device;
wined3d_swapchain_get_desc(ddraw->wined3d_swapchain, &swapchain_desc);
swapchain_desc.backbuffer_width = mode.width;
swapchain_desc.backbuffer_height = mode.height;
swapchain_desc.backbuffer_format = mode.format_id;
if (ddraw->d3ddevice)
if ((device = ddraw->d3ddevice))
{
if (ddraw->d3ddevice->recording)
wined3d_stateblock_decref(ddraw->d3ddevice->recording);
ddraw->d3ddevice->recording = NULL;
ddraw->d3ddevice->update_state = ddraw->d3ddevice->state;
if (device->recording)
wined3d_stateblock_decref(device->recording);
device->recording = NULL;
device->update_state = device->state;
wined3d_stateblock_reset(device->state);
}
wined3d_stateblock_reset(ddraw->state);
if (FAILED(hr = wined3d_device_reset(ddraw->wined3d_device,
&swapchain_desc, NULL, ddraw_reset_enum_callback, TRUE)))
@ -6784,8 +6791,9 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
return hr_ddraw_from_wined3d(hr);
}
wined3d_stateblock_set_render_state(ddraw->state, WINED3D_RS_ZENABLE,
!!swapchain_desc.enable_auto_depth_stencil);
if (device)
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE,
!!swapchain_desc.enable_auto_depth_stencil);
}
}

View file

@ -75,6 +75,7 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface)
{
struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer7(iface);
ULONG ref = InterlockedDecrement(&buffer->ref);
struct d3d_device *device;
TRACE("%p decreasing refcount to %lu.\n", buffer, ref);
@ -85,8 +86,12 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface)
* stream source in wined3d and they should get unset there before
* they are destroyed. */
wined3d_mutex_lock();
if (buffer->ddraw->stateblock_state->streams[0].buffer == buffer->wined3d_buffer)
wined3d_stateblock_set_stream_source(buffer->ddraw->state, 0, NULL, 0, 0);
if ((device = buffer->ddraw->d3ddevice))
{
if (device->stateblock_state->streams[0].buffer == buffer->wined3d_buffer)
wined3d_stateblock_set_stream_source(device->state, 0, NULL, 0, 0);
}
wined3d_vertex_declaration_decref(buffer->wined3d_declaration);
wined3d_buffer_decref(buffer->wined3d_buffer);

View file

@ -3346,3 +3346,13 @@ unsigned int CDECL wined3d_stateblock_set_texture_lod(struct wined3d_stateblock
return old;
}
void CDECL wined3d_stateblock_texture_changed(struct wined3d_stateblock *stateblock,
const struct wined3d_texture *texture)
{
for (unsigned int i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i)
{
if (stateblock->stateblock_state.textures[i] == texture)
stateblock->changed.textures |= (1u << i);
}
}

View file

@ -268,6 +268,7 @@
@ cdecl wined3d_stateblock_set_vs_consts_b(ptr long long ptr)
@ cdecl wined3d_stateblock_set_vs_consts_f(ptr long long ptr)
@ cdecl wined3d_stateblock_set_vs_consts_i(ptr long long ptr)
@ cdecl wined3d_stateblock_texture_changed(ptr ptr)
@ cdecl wined3d_streaming_buffer_map(ptr ptr long long ptr ptr)
@ cdecl wined3d_streaming_buffer_unmap(ptr)
@ -317,6 +318,7 @@
@ cdecl wined3d_texture_incref(ptr)
@ cdecl wined3d_texture_release_dc(ptr long ptr)
@ cdecl wined3d_texture_set_color_key(ptr long ptr)
@ cdecl wined3d_texture_set_lod(ptr long)
@ cdecl wined3d_texture_set_overlay_position(ptr long long long)
@ cdecl wined3d_texture_set_sub_resource_parent(ptr long ptr ptr)
@ cdecl wined3d_texture_update_desc(ptr long ptr long)

View file

@ -2884,6 +2884,8 @@ HRESULT __cdecl wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned
unsigned int __cdecl wined3d_texture_get_level_count(const struct wined3d_texture *texture);
unsigned int __cdecl wined3d_texture_get_lod(const struct wined3d_texture *texture);
unsigned int __cdecl wined3d_texture_set_lod(struct wined3d_texture *texture, unsigned int lod);
void __cdecl wined3d_stateblock_texture_changed(struct wined3d_stateblock *stateblock,
const struct wined3d_texture *texture);
HRESULT __cdecl wined3d_texture_get_overlay_position(const struct wined3d_texture *texture,
unsigned int sub_resource_idx, LONG *x, LONG *y);
void * __cdecl wined3d_texture_get_parent(const struct wined3d_texture *texture);