Commit aa8487a4 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ddraw: Store wined3d state in d3d_device.

parent 9492a10f
...@@ -437,7 +437,6 @@ static void ddraw_destroy(struct ddraw *This) ...@@ -437,7 +437,6 @@ static void ddraw_destroy(struct ddraw *This)
if (This->wined3d_swapchain) if (This->wined3d_swapchain)
ddraw_destroy_swapchain(This); ddraw_destroy_swapchain(This);
wined3d_stateblock_decref(This->state);
wined3d_device_decref(This->wined3d_device); wined3d_device_decref(This->wined3d_device);
wined3d_decref(This->wined3d); wined3d_decref(This->wined3d);
...@@ -797,6 +796,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, ...@@ -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_rendertarget_view *rtv = NULL, *dsv = NULL;
struct wined3d_stateblock *stateblock; struct wined3d_stateblock *stateblock;
BOOL restore_state = FALSE; BOOL restore_state = FALSE;
struct d3d_device *device;
RECT clip_rect; RECT clip_rect;
HRESULT hr; HRESULT hr;
...@@ -924,14 +924,15 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, ...@@ -924,14 +924,15 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (cooplevel & DDSCL_MULTITHREADED && !(ddraw->cooperative_level & DDSCL_MULTITHREADED)) if (cooplevel & DDSCL_MULTITHREADED && !(ddraw->cooperative_level & DDSCL_MULTITHREADED))
wined3d_device_set_multithreaded(ddraw->wined3d_device); wined3d_device_set_multithreaded(ddraw->wined3d_device);
device = ddraw->d3ddevice;
if (ddraw->wined3d_swapchain) if (ddraw->wined3d_swapchain)
{ {
if (!(ddraw->flags & DDRAW_NO3D)) if (!(ddraw->flags & DDRAW_NO3D) && device)
{ {
restore_state = TRUE; restore_state = TRUE;
if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device, 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); ERR("Failed to create stateblock, hr %#lx.\n", hr);
goto done; goto done;
...@@ -968,7 +969,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, ...@@ -968,7 +969,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
wined3d_rendertarget_view_decref(rtv); wined3d_rendertarget_view_decref(rtv);
} }
wined3d_stateblock_apply(stateblock, ddraw->state); wined3d_stateblock_apply(stateblock, device->state);
wined3d_stateblock_decref(stateblock); wined3d_stateblock_decref(stateblock);
} }
...@@ -5127,15 +5128,5 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de ...@@ -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); ddraw->immediate_context = wined3d_device_get_immediate_context(ddraw->wined3d_device);
list_init(&ddraw->surface_list); 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; return DD_OK;
} }
...@@ -132,9 +132,6 @@ struct ddraw ...@@ -132,9 +132,6 @@ struct ddraw
struct FvfToDecl *decls; struct FvfToDecl *decls;
UINT numConvertedDecls, declArraySize; UINT numConvertedDecls, declArraySize;
struct wined3d_stateblock *state;
const struct wined3d_stateblock_state *stateblock_state;
unsigned int frames; unsigned int frames;
DWORD prev_frame_time; DWORD prev_frame_time;
}; };
......
...@@ -284,10 +284,6 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) ...@@ -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_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. */ /* Release the wined3d device. This won't destroy it. */
if (!wined3d_device_decref(This->wined3d_device)) if (!wined3d_device_decref(This->wined3d_device))
ERR("The wined3d device (%p) was destroyed unexpectedly.\n", 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) ...@@ -325,6 +321,18 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
IDirect3DDevice3_DeleteViewport(&This->IDirect3DDevice3_iface, &vp->IDirect3DViewport3_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); TRACE("Releasing render target %p.\n", This->rt_iface);
rt_iface = This->rt_iface; rt_iface = This->rt_iface;
This->rt_iface = NULL; This->rt_iface = NULL;
...@@ -332,11 +340,6 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) ...@@ -332,11 +340,6 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
IUnknown_Release(rt_iface); IUnknown_Release(rt_iface);
TRACE("Render target release done.\n"); 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 */ /* Now free the structure */
free(This); free(This);
wined3d_mutex_unlock(); wined3d_mutex_unlock();
...@@ -6776,15 +6779,15 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device ...@@ -6776,15 +6779,15 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device
return WINED3D_ZB_TRUE; 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; struct wined3d_viewport vp;
RECT rect; RECT rect;
wined3d_device_context_get_viewports(ddraw->immediate_context, NULL, &vp); wined3d_device_context_get_viewports(device->immediate_context, NULL, &vp);
wined3d_stateblock_set_viewport(ddraw->state, &vp); wined3d_stateblock_set_viewport(device->state, &vp);
wined3d_device_context_get_scissor_rects(ddraw->immediate_context, NULL, &rect); wined3d_device_context_get_scissor_rects(device->immediate_context, NULL, &rect);
wined3d_stateblock_set_scissor_rect(ddraw->state, &rect); wined3d_stateblock_set_scissor_rect(device->state, &rect);
} }
static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, const GUID *guid, 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 ...@@ -6838,13 +6841,19 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c
device->legacy_projection = ident; device->legacy_projection = ident;
device->legacy_clipspace = 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. */ /* This is for convenience. */
device->wined3d_device = ddraw->wined3d_device; device->wined3d_device = ddraw->wined3d_device;
device->immediate_context = ddraw->immediate_context; device->immediate_context = ddraw->immediate_context;
wined3d_device_incref(ddraw->wined3d_device); 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->vertex_buffer, WINED3D_BIND_VERTEX_BUFFER);
wined3d_streaming_buffer_init(&device->index_buffer, WINED3D_BIND_INDEX_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 ...@@ -6865,19 +6874,19 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c
ddraw->d3ddevice = device; 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)); d3d_device_update_depth_stencil(device));
if (version == 1) /* Color keying is initially enabled for version 1 devices. */ 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) 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) 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, IDirect3DDevice3_SetRenderState(&device->IDirect3DDevice3_iface,
D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE); D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
} }
ddraw_reset_viewport_state(ddraw); device_reset_viewport_state(device);
return D3D_OK; return D3D_OK;
} }
......
...@@ -4346,7 +4346,7 @@ static HRESULT WINAPI ddraw_surface4_GetUniquenessValue(IDirectDrawSurface4 *ifa ...@@ -4346,7 +4346,7 @@ static HRESULT WINAPI ddraw_surface4_GetUniquenessValue(IDirectDrawSurface4 *ifa
static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD MaxLOD) static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD MaxLOD)
{ {
struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface); struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
HRESULT hr; struct d3d_device *device;
TRACE("iface %p, lod %lu.\n", iface, MaxLOD); TRACE("iface %p, lod %lu.\n", iface, MaxLOD);
...@@ -4357,12 +4357,18 @@ static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD Ma ...@@ -4357,12 +4357,18 @@ static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD Ma
return DDERR_INVALIDOBJECT; return DDERR_INVALIDOBJECT;
} }
hr = wined3d_stateblock_set_texture_lod(surface->ddraw->state, surface->wined3d_texture, MaxLOD); wined3d_texture_set_lod(surface->wined3d_texture, MaxLOD);
if (SUCCEEDED(hr) && surface->draw_texture) if (surface->draw_texture)
hr = wined3d_stateblock_set_texture_lod(surface->ddraw->state, surface->draw_texture, MaxLOD); wined3d_texture_set_lod(surface->draw_texture, MaxLOD);
wined3d_mutex_unlock();
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_ ...@@ -6761,20 +6767,21 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
if (ddraw->cooperative_level & DDSCL_EXCLUSIVE) if (ddraw->cooperative_level & DDSCL_EXCLUSIVE)
{ {
struct wined3d_swapchain_desc swapchain_desc; struct wined3d_swapchain_desc swapchain_desc;
struct d3d_device *device;
wined3d_swapchain_get_desc(ddraw->wined3d_swapchain, &swapchain_desc); wined3d_swapchain_get_desc(ddraw->wined3d_swapchain, &swapchain_desc);
swapchain_desc.backbuffer_width = mode.width; swapchain_desc.backbuffer_width = mode.width;
swapchain_desc.backbuffer_height = mode.height; swapchain_desc.backbuffer_height = mode.height;
swapchain_desc.backbuffer_format = mode.format_id; swapchain_desc.backbuffer_format = mode.format_id;
if (ddraw->d3ddevice) if ((device = ddraw->d3ddevice))
{ {
if (ddraw->d3ddevice->recording) if (device->recording)
wined3d_stateblock_decref(ddraw->d3ddevice->recording); wined3d_stateblock_decref(device->recording);
ddraw->d3ddevice->recording = NULL; device->recording = NULL;
ddraw->d3ddevice->update_state = ddraw->d3ddevice->state; device->update_state = device->state;
wined3d_stateblock_reset(device->state);
} }
wined3d_stateblock_reset(ddraw->state);
if (FAILED(hr = wined3d_device_reset(ddraw->wined3d_device, if (FAILED(hr = wined3d_device_reset(ddraw->wined3d_device,
&swapchain_desc, NULL, ddraw_reset_enum_callback, TRUE))) &swapchain_desc, NULL, ddraw_reset_enum_callback, TRUE)))
...@@ -6784,8 +6791,9 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ ...@@ -6784,8 +6791,9 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
return hr_ddraw_from_wined3d(hr); return hr_ddraw_from_wined3d(hr);
} }
wined3d_stateblock_set_render_state(ddraw->state, WINED3D_RS_ZENABLE, if (device)
!!swapchain_desc.enable_auto_depth_stencil); wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE,
!!swapchain_desc.enable_auto_depth_stencil);
} }
} }
......
...@@ -75,6 +75,7 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface) ...@@ -75,6 +75,7 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface)
{ {
struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer7(iface); struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer7(iface);
ULONG ref = InterlockedDecrement(&buffer->ref); ULONG ref = InterlockedDecrement(&buffer->ref);
struct d3d_device *device;
TRACE("%p decreasing refcount to %lu.\n", buffer, ref); TRACE("%p decreasing refcount to %lu.\n", buffer, ref);
...@@ -85,8 +86,12 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface) ...@@ -85,8 +86,12 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface)
* stream source in wined3d and they should get unset there before * stream source in wined3d and they should get unset there before
* they are destroyed. */ * they are destroyed. */
wined3d_mutex_lock(); 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_vertex_declaration_decref(buffer->wined3d_declaration);
wined3d_buffer_decref(buffer->wined3d_buffer); wined3d_buffer_decref(buffer->wined3d_buffer);
......
...@@ -3346,3 +3346,13 @@ unsigned int CDECL wined3d_stateblock_set_texture_lod(struct wined3d_stateblock ...@@ -3346,3 +3346,13 @@ unsigned int CDECL wined3d_stateblock_set_texture_lod(struct wined3d_stateblock
return old; 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);
}
}
...@@ -268,6 +268,7 @@ ...@@ -268,6 +268,7 @@
@ cdecl wined3d_stateblock_set_vs_consts_b(ptr long long ptr) @ 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_f(ptr long long ptr)
@ cdecl wined3d_stateblock_set_vs_consts_i(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_map(ptr ptr long long ptr ptr)
@ cdecl wined3d_streaming_buffer_unmap(ptr) @ cdecl wined3d_streaming_buffer_unmap(ptr)
...@@ -317,6 +318,7 @@ ...@@ -317,6 +318,7 @@
@ cdecl wined3d_texture_incref(ptr) @ cdecl wined3d_texture_incref(ptr)
@ cdecl wined3d_texture_release_dc(ptr long ptr) @ cdecl wined3d_texture_release_dc(ptr long ptr)
@ cdecl wined3d_texture_set_color_key(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_overlay_position(ptr long long long)
@ cdecl wined3d_texture_set_sub_resource_parent(ptr long ptr ptr) @ cdecl wined3d_texture_set_sub_resource_parent(ptr long ptr ptr)
@ cdecl wined3d_texture_update_desc(ptr long ptr long) @ cdecl wined3d_texture_update_desc(ptr long ptr long)
......
...@@ -2884,6 +2884,8 @@ HRESULT __cdecl wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned ...@@ -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_level_count(const struct wined3d_texture *texture);
unsigned int __cdecl wined3d_texture_get_lod(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); 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, HRESULT __cdecl wined3d_texture_get_overlay_position(const struct wined3d_texture *texture,
unsigned int sub_resource_idx, LONG *x, LONG *y); unsigned int sub_resource_idx, LONG *x, LONG *y);
void * __cdecl wined3d_texture_get_parent(const struct wined3d_texture *texture); void * __cdecl wined3d_texture_get_parent(const struct wined3d_texture *texture);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment