Fixes Sim City 3000 Building Architect.
-- v5: ddraw/tests: Add tests for multiple devices. ddraw: Support multiple devices per ddraw object. ddraw: Sync wined3d render target in d3d_device_sync_rendertarget(). ddraw: Store wined3d state in d3d_device. wined3d: Factor out wined3d_texture_set_lod() function. ddraw: Don't apply state in ddraw_surface_blt(). ddraw: Store matrix handle in the global table. ddraw: Store surface handles in the global table. ddraw: Store material handles in the global table.
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ddraw/device.c | 10 +--------- dlls/ddraw/main.c | 38 ++++++++++++++++++++++++++++++++++++++ dlls/ddraw/material.c | 4 ++-- dlls/ddraw/viewport.c | 2 +- 4 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index bc1d91ee00b..725c925e602 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -303,14 +303,6 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) case DDRAW_HANDLE_FREE: break;
- case DDRAW_HANDLE_MATERIAL: - { - struct d3d_material *m = entry->object; - FIXME("Material handle %#lx (%p) not unset properly.\n", i + 1, m); - m->Handle = 0; - break; - } - case DDRAW_HANDLE_MATRIX: { /* No FIXME here because this might happen because of sloppy applications. */ @@ -2936,7 +2928,7 @@ static HRESULT WINAPI d3d_device3_SetLightState(IDirect3DDevice3 *iface, { struct d3d_material *m;
- if (!(m = ddraw_get_object(&device->handle_table, value - 1, DDRAW_HANDLE_MATERIAL))) + if (!(m = ddraw_get_object(NULL, value - 1, DDRAW_HANDLE_MATERIAL))) { WARN("Invalid material handle.\n"); wined3d_mutex_unlock(); diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c index 1ba2900704f..b4e6b3d4893 100644 --- a/dlls/ddraw/main.c +++ b/dlls/ddraw/main.c @@ -37,6 +37,8 @@ static HINSTANCE instance; /* value of ForceRefreshRate */ DWORD force_refresh_rate = 0;
+static struct ddraw_handle_table global_handle_table; + /* Structure for converting DirectDrawEnumerateA to DirectDrawEnumerateExA */ struct callback_info { @@ -137,6 +139,9 @@ DWORD ddraw_allocate_handle(struct ddraw_handle_table *t, void *object, enum ddr { struct ddraw_handle_entry *entry;
+ if (!t) + t = &global_handle_table; + if (t->free_entries) { DWORD idx = t->free_entries - t->entries; @@ -181,6 +186,9 @@ void *ddraw_free_handle(struct ddraw_handle_table *t, DWORD handle, enum ddraw_h struct ddraw_handle_entry *entry; void *object;
+ if (!t) + t = &global_handle_table; + if (handle == DDRAW_INVALID_HANDLE || handle >= t->entry_count) { WARN("Invalid handle %#lx passed.\n", handle); @@ -206,6 +214,9 @@ void *ddraw_get_object(struct ddraw_handle_table *t, DWORD handle, enum ddraw_ha { struct ddraw_handle_entry *entry;
+ if (!t) + t = &global_handle_table; + if (handle == DDRAW_INVALID_HANDLE || handle >= t->entry_count) { WARN("Invalid handle %#lx passed.\n", handle); @@ -815,6 +826,12 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) return FALSE; }
+ if (!ddraw_handle_table_init(&global_handle_table, 64)) + { + UnregisterClassA(DDRAW_WINDOW_CLASS_NAME, inst); + return FALSE; + } + /* On Windows one can force the refresh rate that DirectDraw uses by * setting an override value in dxdiag. This is documented in KB315614 * (main article), KB230002, and KB217348. By comparing registry dumps @@ -866,6 +883,7 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) if (WARN_ON(ddraw)) { struct ddraw *ddraw; + unsigned int i;
LIST_FOR_EACH_ENTRY(ddraw, &global_ddraw_list, struct ddraw, ddraw_list_entry) { @@ -884,6 +902,26 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) surface->ref2, surface->ref1, surface->gamma_count); } } + + for (i = 0; i < global_handle_table.entry_count; ++i) + { + struct ddraw_handle_entry *entry = &global_handle_table.entries[i]; + + switch (entry->type) + { + case DDRAW_HANDLE_FREE: + break; + + case DDRAW_HANDLE_MATERIAL: + WARN("Material handle %#x (%p) not unset properly.\n", i + 1, entry->object); + break; + + default: + WARN("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type); + break; + } + } + ddraw_handle_table_destroy(&global_handle_table); }
if (reserved) break; diff --git a/dlls/ddraw/material.c b/dlls/ddraw/material.c index d8cb41f1733..efc739c8dbb 100644 --- a/dlls/ddraw/material.c +++ b/dlls/ddraw/material.c @@ -143,7 +143,7 @@ static ULONG WINAPI d3d_material3_Release(IDirect3DMaterial3 *iface) if (material->Handle) { wined3d_mutex_lock(); - ddraw_free_handle(&material->ddraw->d3ddevice->handle_table, material->Handle - 1, DDRAW_HANDLE_MATERIAL); + ddraw_free_handle(NULL, material->Handle - 1, DDRAW_HANDLE_MATERIAL); wined3d_mutex_unlock(); }
@@ -300,7 +300,7 @@ static HRESULT WINAPI d3d_material3_GetHandle(IDirect3DMaterial3 *iface, material->active_device = device_impl; if (!material->Handle) { - DWORD h = ddraw_allocate_handle(&device_impl->handle_table, material, DDRAW_HANDLE_MATERIAL); + DWORD h = ddraw_allocate_handle(NULL, material, DDRAW_HANDLE_MATERIAL); if (h == DDRAW_INVALID_HANDLE) { ERR("Failed to allocate a material handle.\n"); diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c index 4eda2fe4763..98b03c60d72 100644 --- a/dlls/ddraw/viewport.c +++ b/dlls/ddraw/viewport.c @@ -627,7 +627,7 @@ static HRESULT WINAPI d3d_viewport_SetBackground(IDirect3DViewport3 *iface, D3DM
wined3d_mutex_lock();
- if (!(m = ddraw_get_object(&viewport->ddraw->d3ddevice->handle_table, material - 1, DDRAW_HANDLE_MATERIAL))) + if (!(m = ddraw_get_object(NULL, material - 1, DDRAW_HANDLE_MATERIAL))) { WARN("Invalid material handle %#lx.\n", material); wined3d_mutex_unlock();
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ddraw/device.c | 10 +--------- dlls/ddraw/executebuffer.c | 6 ++---- dlls/ddraw/main.c | 4 ++++ dlls/ddraw/surface.c | 5 ++--- 4 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 725c925e602..9677c352258 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -319,14 +319,6 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) break; }
- case DDRAW_HANDLE_SURFACE: - { - struct ddraw_surface *surf = entry->object; - FIXME("Texture handle %#lx (%p) not unset properly.\n", i + 1, surf); - surf->Handle = 0; - break; - } - default: FIXME("Handle %#lx (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type); break; @@ -2760,7 +2752,7 @@ static HRESULT WINAPI d3d_device3_SetRenderState(IDirect3DDevice3 *iface, break; }
- surf = ddraw_get_object(&device->handle_table, value - 1, DDRAW_HANDLE_SURFACE); + surf = ddraw_get_object(NULL, value - 1, DDRAW_HANDLE_SURFACE); if (!surf) { WARN("Invalid texture handle.\n"); diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index 320ce6649d4..c6988a3347b 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -347,14 +347,12 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d
instr += size;
- if (!(dst = ddraw_get_object(&device->handle_table, - ci->hDestTexture - 1, DDRAW_HANDLE_SURFACE))) + if (!(dst = ddraw_get_object(NULL, ci->hDestTexture - 1, DDRAW_HANDLE_SURFACE))) { WARN("Invalid destination texture handle %#lx.\n", ci->hDestTexture); continue; } - if (!(src = ddraw_get_object(&device->handle_table, - ci->hSrcTexture - 1, DDRAW_HANDLE_SURFACE))) + if (!(src = ddraw_get_object(NULL, ci->hSrcTexture - 1, DDRAW_HANDLE_SURFACE))) { WARN("Invalid source texture handle %#lx.\n", ci->hSrcTexture); continue; diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c index b4e6b3d4893..a08cfd12613 100644 --- a/dlls/ddraw/main.c +++ b/dlls/ddraw/main.c @@ -916,6 +916,10 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) WARN("Material handle %#x (%p) not unset properly.\n", i + 1, entry->object); break;
+ case DDRAW_HANDLE_SURFACE: + WARN("Texture handle %#x (%p) not unset properly.\n", i + 1, entry->object); + break; + default: WARN("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type); break; diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index a096c5d7d8e..46fefb2f727 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -5441,7 +5441,6 @@ static HRESULT WINAPI d3d_texture2_GetHandle(IDirect3DTexture2 *iface, IDirect3DDevice2 *device, D3DTEXTUREHANDLE *handle) { struct ddraw_surface *surface = impl_from_IDirect3DTexture2(iface); - struct d3d_device *device_impl = unsafe_impl_from_IDirect3DDevice2(device);
TRACE("iface %p, device %p, handle %p.\n", iface, device, handle);
@@ -5449,7 +5448,7 @@ static HRESULT WINAPI d3d_texture2_GetHandle(IDirect3DTexture2 *iface,
if (!surface->Handle) { - DWORD h = ddraw_allocate_handle(&device_impl->handle_table, surface, DDRAW_HANDLE_SURFACE); + DWORD h = ddraw_allocate_handle(NULL, surface, DDRAW_HANDLE_SURFACE); if (h == DDRAW_INVALID_HANDLE) { ERR("Failed to allocate a texture handle.\n"); @@ -6060,7 +6059,7 @@ static void STDMETHODCALLTYPE ddraw_surface_wined3d_object_destroyed(void *paren
/* Having a texture handle set implies that the device still exists. */ if (surface->Handle) - ddraw_free_handle(&surface->ddraw->d3ddevice->handle_table, surface->Handle - 1, DDRAW_HANDLE_SURFACE); + ddraw_free_handle(NULL, surface->Handle - 1, DDRAW_HANDLE_SURFACE);
/* Reduce the ddraw surface count. */ list_remove(&surface->surface_list_entry);
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ddraw/device.c | 19 ++++--------------- dlls/ddraw/executebuffer.c | 8 ++++---- dlls/ddraw/main.c | 4 ++++ 3 files changed, 12 insertions(+), 19 deletions(-)
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 9677c352258..f903455a177 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -303,14 +303,6 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) case DDRAW_HANDLE_FREE: break;
- case DDRAW_HANDLE_MATRIX: - { - /* No FIXME here because this might happen because of sloppy applications. */ - WARN("Leftover matrix handle %#lx (%p), deleting.\n", i + 1, entry->object); - IDirect3DDevice_DeleteMatrix(&This->IDirect3DDevice_iface, i + 1); - break; - } - case DDRAW_HANDLE_STATEBLOCK: { /* No FIXME here because this might happen because of sloppy applications. */ @@ -1304,7 +1296,6 @@ static HRESULT WINAPI d3d_device1_EnumTextureFormats(IDirect3DDevice *iface, *****************************************************************************/ static HRESULT WINAPI d3d_device1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle) { - struct d3d_device *device = impl_from_IDirect3DDevice(iface); D3DMATRIX *matrix; DWORD h;
@@ -1321,7 +1312,7 @@ static HRESULT WINAPI d3d_device1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIX
wined3d_mutex_lock();
- h = ddraw_allocate_handle(&device->handle_table, matrix, DDRAW_HANDLE_MATRIX); + h = ddraw_allocate_handle(NULL, matrix, DDRAW_HANDLE_MATRIX); if (h == DDRAW_INVALID_HANDLE) { ERR("Failed to allocate a matrix handle.\n"); @@ -1370,7 +1361,7 @@ static HRESULT WINAPI d3d_device1_SetMatrix(IDirect3DDevice *iface,
wined3d_mutex_lock();
- m = ddraw_get_object(&device->handle_table, matrix_handle - 1, DDRAW_HANDLE_MATRIX); + m = ddraw_get_object(NULL, matrix_handle - 1, DDRAW_HANDLE_MATRIX); if (!m) { WARN("Invalid matrix handle.\n"); @@ -1419,7 +1410,6 @@ static HRESULT WINAPI d3d_device1_SetMatrix(IDirect3DDevice *iface, static HRESULT WINAPI d3d_device1_GetMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE D3DMatHandle, D3DMATRIX *D3DMatrix) { - struct d3d_device *device = impl_from_IDirect3DDevice(iface); D3DMATRIX *m;
TRACE("iface %p, matrix_handle %#lx, matrix %p.\n", iface, D3DMatHandle, D3DMatrix); @@ -1428,7 +1418,7 @@ static HRESULT WINAPI d3d_device1_GetMatrix(IDirect3DDevice *iface,
wined3d_mutex_lock();
- m = ddraw_get_object(&device->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX); + m = ddraw_get_object(NULL, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX); if (!m) { WARN("Invalid matrix handle.\n"); @@ -1460,14 +1450,13 @@ static HRESULT WINAPI d3d_device1_GetMatrix(IDirect3DDevice *iface, *****************************************************************************/ static HRESULT WINAPI d3d_device1_DeleteMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE D3DMatHandle) { - struct d3d_device *device = impl_from_IDirect3DDevice(iface); D3DMATRIX *m;
TRACE("iface %p, matrix_handle %#lx.\n", iface, D3DMatHandle);
wined3d_mutex_lock();
- m = ddraw_free_handle(&device->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX); + m = ddraw_free_handle(NULL, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX); if (!m) { WARN("Invalid matrix handle.\n"); diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index c6988a3347b..0cf0bf121f3 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -209,9 +209,9 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d D3DMATRIXMULTIPLY *ci = (D3DMATRIXMULTIPLY *)instr; struct wined3d_matrix *a, *b, *c;
- a = ddraw_get_object(&device->handle_table, ci->hDestMatrix - 1, DDRAW_HANDLE_MATRIX); - b = ddraw_get_object(&device->handle_table, ci->hSrcMatrix1 - 1, DDRAW_HANDLE_MATRIX); - c = ddraw_get_object(&device->handle_table, ci->hSrcMatrix2 - 1, DDRAW_HANDLE_MATRIX); + a = ddraw_get_object(NULL, ci->hDestMatrix - 1, DDRAW_HANDLE_MATRIX); + b = ddraw_get_object(NULL, ci->hSrcMatrix1 - 1, DDRAW_HANDLE_MATRIX); + c = ddraw_get_object(NULL, ci->hSrcMatrix2 - 1, DDRAW_HANDLE_MATRIX);
if (!a || !b || !c) { @@ -235,7 +235,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d D3DSTATE *ci = (D3DSTATE *)instr; D3DMATRIX *m;
- m = ddraw_get_object(&device->handle_table, ci->dwArg[0] - 1, DDRAW_HANDLE_MATRIX); + m = ddraw_get_object(NULL, ci->dwArg[0] - 1, DDRAW_HANDLE_MATRIX); if (!m) { ERR("Invalid matrix handle %#lx.\n", ci->dwArg[0]); diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c index a08cfd12613..1b03f950cef 100644 --- a/dlls/ddraw/main.c +++ b/dlls/ddraw/main.c @@ -920,6 +920,10 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) WARN("Texture handle %#x (%p) not unset properly.\n", i + 1, entry->object); break;
+ case DDRAW_HANDLE_MATRIX: + WARN("Leftover matrix handle %#x (%p), deleting.\n", i + 1, entry->object); + break; + default: WARN("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type); break;
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ddraw/surface.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 46fefb2f727..1231fac05c8 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -1563,7 +1563,6 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT * const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) { struct ddraw *ddraw = dst_surface->ddraw; - struct wined3d_device *wined3d_device = ddraw->wined3d_device; struct wined3d_color colour; DWORD wined3d_flags; HRESULT hr; @@ -1578,7 +1577,6 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT * dst_surface->palette, fill_colour, &colour)) return DDERR_INVALIDPARAMS;
- wined3d_device_apply_stateblock(wined3d_device, ddraw->state); ddraw_surface_get_draw_texture(dst_surface, dst_rect ? DDRAW_SURFACE_RW : DDRAW_SURFACE_WRITE); hr = wined3d_device_context_clear_rendertarget_view(ddraw->immediate_context, ddraw_surface_get_rendertarget_view(dst_surface), @@ -1597,7 +1595,6 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT * dst_surface->palette, fill_colour, &colour)) return DDERR_INVALIDPARAMS;
- wined3d_device_apply_stateblock(wined3d_device, ddraw->state); ddraw_surface_get_draw_texture(dst_surface, dst_rect ? DDRAW_SURFACE_RW : DDRAW_SURFACE_WRITE); return wined3d_device_context_clear_rendertarget_view(ddraw->immediate_context, ddraw_surface_get_rendertarget_view(dst_surface),
From: Paul Gofman pgofman@codeweavers.com
--- dlls/wined3d/stateblock.c | 20 +++----------------- dlls/wined3d/texture.c | 24 ++++++++++++++++++++++++ include/wine/wined3d.h | 1 + 3 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 0cf8e91c3c9..a834a02fddf 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -3321,28 +3321,14 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, unsigned int CDECL wined3d_stateblock_set_texture_lod(struct wined3d_stateblock *stateblock, struct wined3d_texture *texture, unsigned int lod) { - struct wined3d_resource *resource; - unsigned int old = texture->lod; + unsigned int old;
TRACE("texture %p, lod %u.\n", texture, lod);
- /* The d3d9:texture test shows that SetLOD is ignored on non-managed - * textures. The call always returns 0, and GetLOD always returns 0. */ - resource = &texture->resource; - if (!(resource->usage & WINED3DUSAGE_MANAGED)) - { - TRACE("Ignoring LOD on texture with resource access %s.\n", - wined3d_debug_resource_access(resource->access)); - return 0; - } + old = wined3d_texture_set_lod(texture, lod);
- if (lod >= texture->level_count) - lod = texture->level_count - 1; - - if (texture->lod != lod) + if (old != lod) { - texture->lod = lod; - for (unsigned int i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) { /* Mark the texture as changed. The next time the appplication diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index a9c8e152cf2..7fb06d71dcd 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1784,6 +1784,30 @@ unsigned int CDECL wined3d_texture_get_lod(const struct wined3d_texture *texture return texture->lod; }
+unsigned int CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, unsigned int lod) +{ + struct wined3d_resource *resource; + unsigned int old = texture->lod; + + TRACE("texture %p, returning %u.\n", texture, texture->lod); + + /* The d3d9:texture test shows that SetLOD is ignored on non-managed + * textures. The call always returns 0, and GetLOD always returns 0. */ + resource = &texture->resource; + if (!(resource->usage & WINED3DUSAGE_MANAGED)) + { + TRACE("Ignoring LOD on texture with resource access %s.\n", + wined3d_debug_resource_access(resource->access)); + return 0; + } + + if (lod >= texture->level_count) + lod = texture->level_count - 1; + + texture->lod = lod; + return old; +} + UINT CDECL wined3d_texture_get_level_count(const struct wined3d_texture *texture) { TRACE("texture %p, returning %u.\n", texture, texture->level_count); diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 492065711f3..0b906886585 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2883,6 +2883,7 @@ ULONG __cdecl wined3d_texture_decref(struct wined3d_texture *texture); HRESULT __cdecl wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc); 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); 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);
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ddraw/ddraw.c | 19 ++++---------- dlls/ddraw/ddraw_private.h | 3 --- dlls/ddraw/device.c | 53 ++++++++++++++++++++++---------------- dlls/ddraw/surface.c | 36 ++++++++++++++++---------- dlls/ddraw/vertexbuffer.c | 9 +++++-- dlls/wined3d/stateblock.c | 10 +++++++ dlls/wined3d/wined3d.spec | 2 ++ include/wine/wined3d.h | 2 ++ 8 files changed, 79 insertions(+), 55 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index efbe01f3b8b..21497cd7a8b 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -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; } diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 6fc93b91860..f5b38f8f9d6 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -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; }; diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index f903455a177..59027a34ae1 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -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; }
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 1231fac05c8..8073bcd4d48 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -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); } }
diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c index 34f84b2466a..14f3c8a3ef2 100644 --- a/dlls/ddraw/vertexbuffer.c +++ b/dlls/ddraw/vertexbuffer.c @@ -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); diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index a834a02fddf..1dcc3e3be49 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -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); + } +} diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index accb6f65658..fee5ed0dd7a 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -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) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 0b906886585..1336f10ff7a 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -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);
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ddraw/ddraw.c | 23 ----------------- dlls/ddraw/ddraw_private.h | 1 + dlls/ddraw/device.c | 51 ++++++++++++++++++++++++++++++++------ dlls/ddraw/viewport.c | 6 +++-- 4 files changed, 48 insertions(+), 33 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 21497cd7a8b..121944b1000 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -793,7 +793,6 @@ static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface) static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, DWORD cooplevel, BOOL restore_mode_on_normal) { - struct wined3d_rendertarget_view *rtv = NULL, *dsv = NULL; struct wined3d_stateblock *stateblock; BOOL restore_state = FALSE; struct d3d_device *device; @@ -937,16 +936,6 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, ERR("Failed to create stateblock, hr %#lx.\n", hr); goto done; } - - rtv = wined3d_device_context_get_rendertarget_view(ddraw->immediate_context, 0); - /* Rendering to the wined3d frontbuffer. */ - if (rtv && !wined3d_rendertarget_view_get_sub_resource_parent(rtv)) - rtv = NULL; - else if (rtv) - wined3d_rendertarget_view_incref(rtv); - - if ((dsv = wined3d_device_context_get_depth_stencil_view(ddraw->immediate_context))) - wined3d_rendertarget_view_incref(dsv); }
ddraw_destroy_swapchain(ddraw); @@ -957,18 +946,6 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (restore_state) { - if (dsv) - { - wined3d_device_context_set_depth_stencil_view(ddraw->immediate_context, dsv); - wined3d_rendertarget_view_decref(dsv); - } - - if (rtv) - { - wined3d_device_context_set_rendertarget_views(ddraw->immediate_context, 0, 1, &rtv, FALSE); - wined3d_rendertarget_view_decref(rtv); - } - wined3d_stateblock_apply(stateblock, device->state); wined3d_stateblock_decref(stateblock); } diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index f5b38f8f9d6..e5a8327204c 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -327,6 +327,7 @@ struct d3d_device struct wined3d_device_context *immediate_context; struct ddraw *ddraw; IUnknown *rt_iface; + struct ddraw_surface *target, *target_ds;
struct wined3d_streaming_buffer vertex_buffer, index_buffer;
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 59027a34ae1..cdcc332f235 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -336,6 +336,8 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) TRACE("Releasing render target %p.\n", This->rt_iface); rt_iface = This->rt_iface; This->rt_iface = NULL; + This->target = NULL; + This->target_ds = NULL; if (This->version != 1) IUnknown_Release(rt_iface); TRACE("Render target release done.\n"); @@ -1844,6 +1846,7 @@ static HRESULT d3d_device_set_render_target(struct d3d_device *device, IUnknown_AddRef(rt_iface); IUnknown_Release(device->rt_iface); device->rt_iface = rt_iface; + device->target = target; d3d_device_update_depth_stencil(device);
return D3D_OK; @@ -1887,6 +1890,8 @@ static HRESULT d3d_device7_SetRenderTarget(IDirect3DDevice7 *iface, IDirectDrawSurface7_AddRef(target); IUnknown_Release(device->rt_iface); device->rt_iface = (IUnknown *)target; + device->target = NULL; + device->target_ds = NULL; wined3d_mutex_unlock(); return DDERR_INVALIDPIXELFORMAT; } @@ -1946,6 +1951,8 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface, IDirectDrawSurface4_AddRef(target); IUnknown_Release(device->rt_iface); device->rt_iface = (IUnknown *)target; + device->target = NULL; + device->target_ds = NULL; wined3d_mutex_unlock(); return DDERR_INVALIDPIXELFORMAT; } @@ -1956,6 +1963,8 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface, IDirectDrawSurface4_AddRef(target); IUnknown_Release(device->rt_iface); device->rt_iface = (IUnknown *)target; + device->target = NULL; + device->target_ds = NULL; wined3d_mutex_unlock(); return D3D_OK; } @@ -1995,6 +2004,8 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface, WARN("Surface %p is a depth buffer.\n", target_impl); IUnknown_Release(device->rt_iface); device->rt_iface = (IUnknown *)target; + device->target = NULL; + device->target_ds = NULL; wined3d_mutex_unlock(); return DDERR_INVALIDPIXELFORMAT; } @@ -2005,6 +2016,8 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface, IDirectDrawSurface_AddRef(target); IUnknown_Release(device->rt_iface); device->rt_iface = (IUnknown *)target; + device->target = NULL; + device->target_ds = NULL; wined3d_mutex_unlock(); return D3D_OK; } @@ -3367,16 +3380,36 @@ static HRESULT WINAPI d3d_device2_MultiplyTransform(IDirect3DDevice2 *iface, *****************************************************************************/ static void d3d_device_sync_rendertarget(struct d3d_device *device) { - struct wined3d_rendertarget_view *rtv; + struct wined3d_rendertarget_view *rtv, *dsv; + + rtv = device->target ? ddraw_surface_get_rendertarget_view(device->target) : NULL; + if (rtv) + { + if (FAILED(wined3d_device_context_set_rendertarget_views(device->immediate_context, 0, 1, &rtv, FALSE))) + ERR("wined3d_device_context_set_rendertarget_views failed.\n"); + } + else if (!device->target) + { + /* NULL device->target may appear when the game was setting invalid render target which in some cases + * still keeps the invalid render target in the device even while returning an error. + * + * TODO: make render go nowhere instead of lefover render target (like it seems to work on Windows on HW devices + * while may just crash on software devices. */ + FIXME("Keeping leftover render target.\n"); + } + + dsv = device->target_ds ? ddraw_surface_get_rendertarget_view(device->target_ds) : NULL; + if (FAILED(wined3d_device_context_set_depth_stencil_view(device->immediate_context, dsv))) + ERR("wined3d_device_context_set_depth_stencil_view failed.\n");
if (device->hardware_device) return;
- if ((rtv = wined3d_device_context_get_rendertarget_view(device->immediate_context, 0))) + if (rtv) ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(rtv), DDRAW_SURFACE_RW);
- if ((rtv = wined3d_device_context_get_depth_stencil_view(device->immediate_context))) - ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(rtv), DDRAW_SURFACE_RW); + if (dsv) + ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(dsv), DDRAW_SURFACE_RW); }
void d3d_device_sync_surfaces(struct d3d_device *device) @@ -5171,7 +5204,8 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi return DDERR_INVALIDPARAMS;
wined3d_mutex_lock(); - if (!(rtv = wined3d_device_context_get_rendertarget_view(device->immediate_context, 0))) + rtv = device->target ? ddraw_surface_get_rendertarget_view(device->target) : NULL; + if (!rtv) { wined3d_mutex_unlock(); return DDERR_INVALIDCAPS; @@ -6756,7 +6790,6 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device IDirectDrawSurface7 *depthStencil = NULL; IDirectDrawSurface7 *render_target; static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, {0} }; - struct ddraw_surface *dsi;
if (device->rt_iface && SUCCEEDED(IUnknown_QueryInterface(device->rt_iface, &IID_IDirectDrawSurface7, (void **)&render_target))) @@ -6768,12 +6801,13 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device { TRACE("Setting wined3d depth stencil to NULL\n"); wined3d_device_context_set_depth_stencil_view(device->immediate_context, NULL); + device->target_ds = NULL; return WINED3D_ZB_FALSE; }
- dsi = impl_from_IDirectDrawSurface7(depthStencil); + device->target_ds = impl_from_IDirectDrawSurface7(depthStencil); wined3d_device_context_set_depth_stencil_view(device->immediate_context, - ddraw_surface_get_rendertarget_view(dsi)); + ddraw_surface_get_rendertarget_view(device->target_ds));
IDirectDrawSurface7_Release(depthStencil); return WINED3D_ZB_TRUE; @@ -6869,6 +6903,7 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c }
device->rt_iface = rt_iface; + device->target = target; if (version != 1) IUnknown_AddRef(device->rt_iface);
diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c index 98b03c60d72..707b0f5498c 100644 --- a/dlls/ddraw/viewport.c +++ b/dlls/ddraw/viewport.c @@ -405,7 +405,8 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE
if (device->version > 1) { - if (!(rtv = wined3d_device_context_get_rendertarget_view(device->immediate_context, 0))) + rtv = device->target ? ddraw_surface_get_rendertarget_view(device->target) : NULL; + if (!rtv) { wined3d_mutex_unlock(); return DDERR_INVALIDCAPS; @@ -1034,7 +1035,8 @@ static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVI
if (device->version > 1) { - if (!(rtv = wined3d_device_context_get_rendertarget_view(device->immediate_context, 0))) + rtv = device->target ? ddraw_surface_get_rendertarget_view(device->target) : NULL; + if (!rtv) { wined3d_mutex_unlock(); return DDERR_INVALIDCAPS;
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ddraw/ddraw.c | 40 +++++++++++++++++++++++++++----------- dlls/ddraw/ddraw_private.h | 6 +++++- dlls/ddraw/device.c | 10 ++-------- dlls/ddraw/main.c | 4 ++-- dlls/ddraw/surface.c | 16 ++++++++++----- dlls/ddraw/tests/d3d.c | 9 ++------- dlls/ddraw/vertexbuffer.c | 2 +- 7 files changed, 52 insertions(+), 35 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 121944b1000..5cea4677439 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -420,6 +420,7 @@ static void ddraw_destroy_swapchain(struct ddraw *ddraw) *****************************************************************************/ static void ddraw_destroy(struct ddraw *This) { + struct d3d_device *device; IDirectDraw7_SetCooperativeLevel(&This->IDirectDraw7_iface, NULL, DDSCL_NORMAL); IDirectDraw7_RestoreDisplayMode(&This->IDirectDraw7_iface);
@@ -440,8 +441,10 @@ static void ddraw_destroy(struct ddraw *This) wined3d_device_decref(This->wined3d_device); wined3d_decref(This->wined3d);
- if (This->d3ddevice) - This->d3ddevice->ddraw = NULL; + LIST_FOR_EACH_ENTRY(device, &This->d3ddevice_list, struct d3d_device, ddraw_entry) + { + device->ddraw = NULL; + }
/* Now free the object */ free(This); @@ -793,7 +796,6 @@ static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface) static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, DWORD cooplevel, BOOL restore_mode_on_normal) { - struct wined3d_stateblock *stateblock; BOOL restore_state = FALSE; struct d3d_device *device; RECT clip_rect; @@ -923,18 +925,29 @@ 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) && device) + if (!(ddraw->flags & DDRAW_NO3D)) { restore_state = TRUE;
- if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device, - device->state, WINED3D_SBT_ALL, &stateblock))) + LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry) { - ERR("Failed to create stateblock, hr %#lx.\n", hr); - goto done; + if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device, + device->state, WINED3D_SBT_ALL, &device->saved_state))) + { + struct list *entry; + + ERR("Failed to create stateblock, hr %#lx.\n", hr); + entry = &device->ddraw_entry; + while ((entry = list_prev(&ddraw->d3ddevice_list, entry))) + { + device = LIST_ENTRY(entry, struct d3d_device, ddraw_entry); + wined3d_stateblock_decref(device->saved_state); + device->saved_state = NULL; + } + goto done; + } } }
@@ -946,8 +959,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (restore_state) { - wined3d_stateblock_apply(stateblock, device->state); - wined3d_stateblock_decref(stateblock); + LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry) + { + wined3d_stateblock_apply(device->saved_state, device->state); + wined3d_stateblock_decref(device->saved_state); + device->saved_state = NULL; + } }
if (!(cooplevel & DDSCL_EXCLUSIVE) && (ddraw->cooperative_level & DDSCL_EXCLUSIVE)) @@ -5105,5 +5122,6 @@ 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); + list_init(&ddraw->d3ddevice_list); return DD_OK; } diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index e5a8327204c..1f0c94a9c6e 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -113,7 +113,7 @@ struct ddraw
/* D3D things */ HWND d3d_window; - struct d3d_device *d3ddevice; + struct list d3ddevice_list; int d3dversion;
/* Various HWNDs */ @@ -326,6 +326,7 @@ struct d3d_device struct wined3d_device *wined3d_device; struct wined3d_device_context *immediate_context; struct ddraw *ddraw; + struct list ddraw_entry; IUnknown *rt_iface; struct ddraw_surface *target, *target_ds;
@@ -362,6 +363,9 @@ struct d3d_device
struct wined3d_stateblock *recording, *state, *update_state; const struct wined3d_stateblock_state *stateblock_state; + + /* For temporary saving state during reset. */ + struct wined3d_stateblock *saved_state; };
HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface, diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index cdcc332f235..f64db3aa633 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -329,7 +329,7 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) * 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; + list_remove(&This->ddraw_entry); This->ddraw = NULL; }
@@ -6907,7 +6907,7 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c if (version != 1) IUnknown_AddRef(device->rt_iface);
- ddraw->d3ddevice = device; + list_add_head(&ddraw->d3ddevice_list, &device->ddraw_entry);
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE, d3d_device_update_depth_stencil(device)); @@ -6955,12 +6955,6 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su return DDERR_OUTOFMEMORY; }
- if (ddraw->d3ddevice) - { - FIXME("Only one Direct3D device per DirectDraw object supported.\n"); - return DDERR_INVALIDPARAMS; - } - if (!(object = calloc(1, sizeof(*object)))) { ERR("Failed to allocate device memory.\n"); diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c index 1b03f950cef..034a7b6e406 100644 --- a/dlls/ddraw/main.c +++ b/dlls/ddraw/main.c @@ -892,8 +892,8 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) WARN("DirectDraw object %p has reference counts {%lu, %lu, %lu, %lu, %lu}.\n", ddraw, ddraw->ref7, ddraw->ref4, ddraw->ref3, ddraw->ref2, ddraw->ref1);
- if (ddraw->d3ddevice) - WARN("DirectDraw object %p has Direct3D device %p attached.\n", ddraw, ddraw->d3ddevice); + if (!list_empty(&ddraw->d3ddevice_list)) + WARN("DirectDraw object %p has Direct3D device(s) attached.\n", ddraw);
LIST_FOR_EACH_ENTRY(surface, &ddraw->surface_list, struct ddraw_surface, surface_list_entry) { diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 8073bcd4d48..813d19832c2 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -2013,6 +2013,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Blt(IDirectDrawSurface2 * *****************************************************************************/ static HRESULT ddraw_surface_attach_surface(struct ddraw_surface *This, struct ddraw_surface *Surf) { + struct d3d_device *device; + TRACE("surface %p, attachment %p.\n", This, Surf);
if(Surf == This) @@ -2039,8 +2041,10 @@ static HRESULT ddraw_surface_attach_surface(struct ddraw_surface *This, struct d This->next_attached = Surf;
/* Check if the WineD3D depth stencil needs updating */ - if (This->ddraw->d3ddevice) - d3d_device_update_depth_stencil(This->ddraw->d3ddevice); + LIST_FOR_EACH_ENTRY(device, &This->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry) + { + d3d_device_update_depth_stencil(device); + }
wined3d_mutex_unlock();
@@ -4361,7 +4365,7 @@ static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD Ma if (surface->draw_texture) wined3d_texture_set_lod(surface->draw_texture, MaxLOD);
- if ((device = surface->ddraw->d3ddevice)) + LIST_FOR_EACH_ENTRY(device, &surface->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry) { wined3d_stateblock_texture_changed(device->state, surface->wined3d_texture); if (surface->draw_texture) @@ -6774,7 +6778,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ swapchain_desc.backbuffer_height = mode.height; swapchain_desc.backbuffer_format = mode.format_id;
- if ((device = ddraw->d3ddevice)) + LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry) { if (device->recording) wined3d_stateblock_decref(device->recording); @@ -6791,9 +6795,11 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ return hr_ddraw_from_wined3d(hr); }
- if (device) + LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry) + { wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE, !!swapchain_desc.enable_auto_depth_stencil); + } } }
diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c index 5958df59df9..ec536a83729 100644 --- a/dlls/ddraw/tests/d3d.c +++ b/dlls/ddraw/tests/d3d.c @@ -1523,13 +1523,8 @@ static void BackBuffer3DCreateSurfaceTest(void) "GetSurfaceDesc returned caps %#lx.\n", created_ddsd.ddsCaps.dwCaps);
hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal); - /* Currently Wine only supports the creation of one Direct3D device - for a given DirectDraw instance. It has been created already - in D3D1_createObjects() - IID_IDirect3DRGBDevice */ - todo_wine ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr); - - if (SUCCEEDED(hr)) - IDirect3DDevice_Release(d3dhal); + ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr); + IDirect3DDevice_Release(d3dhal);
IDirectDrawSurface_Release(surf); } diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c index 14f3c8a3ef2..73cf0a37991 100644 --- a/dlls/ddraw/vertexbuffer.c +++ b/dlls/ddraw/vertexbuffer.c @@ -87,7 +87,7 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface) * they are destroyed. */ wined3d_mutex_lock();
- if ((device = buffer->ddraw->d3ddevice)) + LIST_FOR_EACH_ENTRY(device, &buffer->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry) { if (device->stateblock_state->streams[0].buffer == buffer->wined3d_buffer) wined3d_stateblock_set_stream_source(device->state, 0, NULL, 0, 0);
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ddraw/tests/ddraw1.c | 104 +++++++++++++++++++++++++ dlls/ddraw/tests/ddraw2.c | 160 ++++++++++++++++++++++++++++++++++++-- dlls/ddraw/tests/ddraw4.c | 125 +++++++++++++++++++++++++++-- dlls/ddraw/tests/ddraw7.c | 88 +++++++++++++++++++-- 4 files changed, 454 insertions(+), 23 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index d8fcb188c40..0940aa8d78a 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -15530,6 +15530,109 @@ static void test_pinned_sysmem(void) DestroyWindow(window); }
+static void test_multiple_devices(void) +{ + static D3DMATRIX test_matrix = + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 3.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 4.0f, + }; + + D3DTEXTUREHANDLE texture_handle, texture_handle2; + D3DMATERIALHANDLE mat_handle, mat_handle2; + IDirect3DViewport *viewport, *viewport2; + IDirect3DDevice *device, *device2; + IDirectDrawSurface *texture_surf; + D3DMATRIXHANDLE matrix_handle; + IDirectDraw *ddraw, *ddraw2; + IDirect3DMaterial *material; + DDSURFACEDESC surface_desc; + IDirect3DTexture *texture; + D3DMATRIX matrix; + ULONG refcount; + HWND window; + HRESULT hr; + + window = create_window(); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, &IID_IDirect3DHALDevice))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + + ddraw2 = create_ddraw(); + ok(!!ddraw2, "Failed to create a ddraw object.\n"); + + device2 = create_device_ex(ddraw2, window, DDSCL_NORMAL, &IID_IDirect3DHALDevice); + ok(!!device2, "got NULL.\n"); + + viewport = create_viewport(device, 0, 0, 640, 480); + viewport2 = create_viewport(device2, 0, 0, 640, 480); + + material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f); + hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(mat_handle == mat_handle2, "got different handles.\n"); + + hr = IDirect3DMaterial_GetHandle(material, device2, &mat_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + todo_wine ok(mat_handle != mat_handle2, "got same handles.\n"); + + hr = IDirect3DViewport_SetBackground(viewport, mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DViewport_SetBackground(viewport2, mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + surface_desc.dwWidth = 256; + surface_desc.dwHeight = 256; + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &texture_surf, NULL); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirectDrawSurface_QueryInterface(texture_surf, &IID_IDirect3DTexture2, (void **)&texture); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DTexture_GetHandle(texture, device, &texture_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DTexture_GetHandle(texture, device2, &texture_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(texture_handle != texture_handle2, "got same handles.\n"); + + hr = IDirect3DDevice_CreateMatrix(device, &matrix_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice_SetMatrix(device, matrix_handle, &test_matrix); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + memset(&matrix, 0xcc, sizeof(matrix)); + hr = IDirect3DDevice_GetMatrix(device2, matrix_handle, &matrix); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(!memcmp(&matrix, &test_matrix, sizeof(matrix)), "matrix does not match.\n"); + + IDirect3DTexture_Release(texture); + IDirectDrawSurface_Release(texture_surf); + IDirect3DMaterial_Release(material); + IDirect3DViewport_Release(viewport); + IDirect3DViewport_Release(viewport2); + + refcount = IDirect3DDevice_Release(device); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3DDevice_Release(device2); + ok(!refcount, "Device has %lu references left.\n", refcount); + + IDirectDraw_Release(ddraw); + IDirectDraw_Release(ddraw2); + DestroyWindow(window); +} + START_TEST(ddraw1) { DDDEVICEIDENTIFIER identifier; @@ -15650,4 +15753,5 @@ START_TEST(ddraw1) test_filling_convention(); test_enum_devices(); test_pinned_sysmem(); + test_multiple_devices(); } diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index f4cc5df0558..1a95d4e66f1 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -462,7 +462,8 @@ static IDirectDraw2 *create_ddraw(void) return ddraw2; }
-static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWORD coop_level, const GUID *device_guid) +static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWORD coop_level, const GUID *device_guid, + IDirectDrawSurface **ret_surface) { /* Prefer 16 bit depth buffers because Nvidia gives us an unpadded D24 buffer if we ask * for 24 bit and handles such buffers incorrectly in DDBLT_DEPTHFILL. AMD only supports @@ -541,13 +542,17 @@ static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWOR }
IDirect3D2_Release(d3d); - IDirectDrawSurface_Release(surface); + if (ret_surface) + *ret_surface = surface; + else + IDirectDrawSurface_Release(surface); + return device; }
static IDirect3DDevice2 *create_device(IDirectDraw2 *ddraw, HWND window, DWORD coop_level) { - return create_device_ex(ddraw, window, coop_level, &IID_IDirect3DHALDevice); + return create_device_ex(ddraw, window, coop_level, &IID_IDirect3DHALDevice, NULL); }
static IDirect3DViewport2 *create_viewport(IDirect3DDevice2 *device, UINT x, UINT y, UINT w, UINT h) @@ -1330,7 +1335,7 @@ static void test_depth_blit(const GUID *device_guid) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw2_Release(ddraw); @@ -1856,7 +1861,7 @@ static void test_zenable(const GUID *device_guid) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw2_Release(ddraw); @@ -1971,7 +1976,7 @@ static void test_ck_rgba(const GUID *device_guid) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw2_Release(ddraw); @@ -5204,7 +5209,7 @@ static void test_rt_caps(const GUID *device_guid) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw2_Release(ddraw); @@ -15692,7 +15697,7 @@ static void test_texture_wrong_caps(const GUID *device_guid) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -16442,6 +16447,144 @@ static void run_for_each_device_type(void (*test_func)(const GUID *)) test_func(&IID_IDirect3DRGBDevice); }
+static void test_multiple_devices(void) +{ + D3DTEXTUREHANDLE texture_handle, texture_handle2; + IDirect3DDevice2 *device, *device2, *device3; + IDirectDrawSurface *surface, *texture_surf; + D3DMATERIALHANDLE mat_handle, mat_handle2; + IDirect3DViewport2 *viewport, *viewport2; + IDirectDraw2 *ddraw, *ddraw2; + IDirect3DMaterial2 *material; + DDSURFACEDESC surface_desc; + IDirect3DTexture2 *texture; + IDirect3D2 *d3d; + ULONG refcount; + DWORD value; + HWND window; + HRESULT hr; + + window = create_window(); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, &IID_IDirect3DHALDevice, &surface))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice2_GetDirect3D(device, &d3d); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3D2_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + ddraw2 = create_ddraw(); + ok(!!ddraw2, "Failed to create a ddraw object.\n"); + device3 = create_device(ddraw2, window, DDSCL_NORMAL); + ok(!!device3, "got NULL.\n"); + + viewport = create_viewport(device, 0, 0, 640, 480); + viewport2 = create_viewport(device2, 0, 0, 640, 480); + hr = IDirect3DDevice2_SetCurrentViewport(device, viewport); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice2_SetCurrentViewport(device2, viewport); + ok(hr == DDERR_INVALIDPARAMS, "got %#lx.\n", hr); + hr = IDirect3DDevice2_SetCurrentViewport(device2, viewport2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f); + hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(mat_handle == mat_handle2, "got different handles.\n"); + + hr = IDirect3DMaterial2_GetHandle(material, device2, &mat_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + todo_wine ok(mat_handle != mat_handle2, "got same handles.\n"); + + hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice2_SetLightState(device2, D3DLIGHTSTATE_MATERIAL, mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice2_SetLightState(device3, D3DLIGHTSTATE_MATERIAL, mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle2); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IDirect3DViewport2_SetBackground(viewport, mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DViewport2_SetBackground(viewport2, mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice2_SetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice2_SetRenderState(device3, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + value = 0xdeadbeef; + hr = IDirect3DDevice2_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(value == TRUE, "got %#lx.\n", value); + hr = IDirect3DDevice2_GetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(!value, "got %#lx.\n", value); + hr = IDirect3DDevice2_GetRenderState(device3, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(!value, "got %#lx.\n", value); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + surface_desc.dwWidth = 256; + surface_desc.dwHeight = 256; + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &texture_surf, NULL); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirectDrawSurface_QueryInterface(texture_surf, &IID_IDirect3DTexture2, (void **)&texture); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DTexture2_GetHandle(texture, device, &texture_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DTexture2_GetHandle(texture, device2, &texture_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(texture_handle == texture_handle2, "got different handles.\n"); + hr = IDirect3DTexture2_GetHandle(texture, device3, &texture_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(texture_handle == texture_handle2, "got different handles.\n"); + hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice2_SetRenderState(device2, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice2_SetRenderState(device3, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + IDirect3DTexture2_Release(texture); + IDirectDrawSurface_Release(texture_surf); + IDirect3DMaterial2_Release(material); + IDirect3DViewport2_Release(viewport); + IDirect3DViewport2_Release(viewport2); + + refcount = IDirect3DDevice2_Release(device); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3DDevice2_Release(device2); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3DDevice2_Release(device3); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirectDrawSurface_Release(surface); + ok(!refcount, "Surface has %lu references left.\n", refcount); + + IDirectDraw2_Release(ddraw); + IDirectDraw_Release(ddraw2); + IDirect3D2_Release(d3d); + DestroyWindow(window); +} + START_TEST(ddraw2) { DDDEVICEIDENTIFIER identifier; @@ -16567,4 +16710,5 @@ START_TEST(ddraw2) run_for_each_device_type(test_texture_wrong_caps); test_filling_convention(); test_enum_devices(); + test_multiple_devices(); } diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 4811053a231..69dc0f13704 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -450,7 +450,8 @@ static IDirectDraw4 *create_ddraw(void) return ddraw4; }
-static IDirect3DDevice3 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid) +static IDirect3DDevice3 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid, + IDirectDrawSurface4 **ret_surface) { IDirectDrawSurface4 *surface, *ds; IDirect3DDevice3 *device = NULL; @@ -539,16 +540,22 @@ static IDirect3DDevice3 *create_device_ex(HWND window, DWORD coop_level, const G
hr = IDirect3D3_CreateDevice(d3d3, device_guid, surface, &device, NULL); IDirect3D3_Release(d3d3); - IDirectDrawSurface4_Release(surface); if (FAILED(hr)) + { + IDirectDrawSurface4_Release(surface); return NULL; + } + if (ret_surface) + *ret_surface = surface; + else + IDirectDrawSurface4_Release(surface);
return device; }
static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level) { - return create_device_ex(window, coop_level, &IID_IDirect3DHALDevice); + return create_device_ex(window, coop_level, &IID_IDirect3DHALDevice, NULL); }
static IDirect3DViewport3 *create_viewport(IDirect3DDevice3 *device, UINT x, UINT y, UINT w, UINT h) @@ -1506,7 +1513,7 @@ static void test_depth_blit(const GUID *device_guid) D3DRECT d3drect;
window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -2101,7 +2108,7 @@ static void test_zenable(const GUID *device_guid) HRESULT hr;
window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -2213,7 +2220,7 @@ static void test_ck_rgba(const GUID *device_guid) HRESULT hr;
window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -18750,7 +18757,7 @@ static void test_texture_wrong_caps(const GUID *device_guid) HRESULT hr;
window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -19506,6 +19513,109 @@ static void test_enum_devices(void) ok(!refcount, "Device has %lu references left.\n", refcount); }
+static void test_multiple_devices(void) +{ + IDirect3DDevice3 *device, *device2, *device3; + D3DMATERIALHANDLE mat_handle, mat_handle2; + IDirect3DViewport3 *viewport, *viewport2; + IDirect3DMaterial3 *material; + IDirectDrawSurface4 *surface; + IDirectDraw4 *ddraw; + IDirect3D3 *d3d; + ULONG refcount; + DWORD value; + HWND window; + HRESULT hr; + + window = create_window(); + if (!(device = create_device_ex(window, DDSCL_NORMAL, &IID_IDirect3DHALDevice, &surface))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice3_GetDirect3D(device, &d3d); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3D3_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device2, NULL); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + device3 = create_device(window, DDSCL_NORMAL); + ok(!!device3, "got NULL.\n"); + + viewport = create_viewport(device, 0, 0, 640, 480); + viewport2 = create_viewport(device2, 0, 0, 640, 480); + hr = IDirect3DDevice3_SetCurrentViewport(device, viewport); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice3_SetCurrentViewport(device2, viewport); + ok(hr == DDERR_INVALIDPARAMS, "got %#lx.\n", hr); + hr = IDirect3DDevice3_SetCurrentViewport(device2, viewport2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f); + hr = IDirect3DMaterial3_GetHandle(material, device, &mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DMaterial3_GetHandle(material, device, &mat_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + ok(mat_handle == mat_handle2, "got different handles.\n"); + + hr = IDirect3DMaterial3_GetHandle(material, device2, &mat_handle2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + todo_wine ok(mat_handle != mat_handle2, "got same handles.\n"); + + hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice3_SetLightState(device2, D3DLIGHTSTATE_MATERIAL, mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice3_SetLightState(device3, D3DLIGHTSTATE_MATERIAL, mat_handle); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle2); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IDirect3DViewport3_SetBackground(viewport, mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DViewport3_SetBackground(viewport2, mat_handle); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice3_SetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice3_SetRenderState(device3, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + value = 0xdeadbeef; + hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(value == TRUE, "got %#lx.\n", value); + hr = IDirect3DDevice3_GetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(!value, "got %#lx.\n", value); + hr = IDirect3DDevice3_GetRenderState(device3, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(!value, "got %#lx.\n", value); + + IDirect3DMaterial3_Release(material); + IDirect3DViewport3_Release(viewport); + IDirect3DViewport3_Release(viewport2); + + refcount = IDirect3DDevice3_Release(device); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3DDevice3_Release(device2); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3DDevice3_Release(device3); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirectDrawSurface4_Release(surface); + ok(!refcount, "Surface has %lu references left.\n", refcount); + IDirectDraw4_Release(ddraw); + IDirect3D3_Release(d3d); + DestroyWindow(window); +} + START_TEST(ddraw4) { DDDEVICEIDENTIFIER identifier; @@ -19647,4 +19757,5 @@ START_TEST(ddraw4) run_for_each_device_type(test_texture_wrong_caps); test_filling_convention(); test_enum_devices(); + test_multiple_devices(); } diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 2771a4ed368..8bd93c77b32 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -498,7 +498,8 @@ static HRESULT WINAPI enum_devtype_cb(char *desc_str, char *name, D3DDEVICEDESC7 return DDENUMRET_OK; }
-static IDirect3DDevice7 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid) +static IDirect3DDevice7 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid, + IDirectDrawSurface7 **ret_surface) { IDirectDrawSurface7 *surface, *ds; IDirect3DDevice7 *device = NULL; @@ -586,9 +587,16 @@ static IDirect3DDevice7 *create_device_ex(HWND window, DWORD coop_level, const G
hr = IDirect3D7_CreateDevice(d3d7, device_guid, surface, &device); IDirect3D7_Release(d3d7); - IDirectDrawSurface7_Release(surface); if (FAILED(hr)) + { + IDirectDrawSurface7_Release(surface); return NULL; + } + + if (ret_surface) + *ret_surface = surface; + else + IDirectDrawSurface7_Release(surface);
return device; } @@ -615,7 +623,7 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level)
IDirect3D7_Release(d3d7);
- return create_device_ex(window, coop_level, device_guid); + return create_device_ex(window, coop_level, device_guid, NULL); }
static bool init_3d_test_context_guid(struct ddraw_test_context *context, const GUID *device_guid) @@ -625,7 +633,7 @@ static bool init_3d_test_context_guid(struct ddraw_test_context *context, const memset(context, 0, sizeof(*context));
context->window = create_window(); - if (!(context->device = create_device_ex(context->window, DDSCL_NORMAL, device_guid))) + if (!(context->device = create_device_ex(context->window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a D3D device.\n"); DestroyWindow(context->window); @@ -1586,7 +1594,7 @@ static void test_depth_blit(const GUID *device_guid) HWND window;
window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -1844,7 +1852,7 @@ static void test_zenable(const GUID *device_guid) HRESULT hr;
window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -1948,7 +1956,7 @@ static void test_ck_rgba(const GUID *device_guid) HRESULT hr;
window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -19134,7 +19142,7 @@ static void test_texture_wrong_caps(const GUID *device_guid) HRESULT hr;
window = create_window(); - if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -20001,6 +20009,69 @@ static void run_for_each_device_type(void (*test_func)(const GUID *)) winetest_pop_context(); }
+static void test_multiple_devices(void) +{ + IDirect3DDevice7 *device, *device2; + IDirectDrawSurface7 *surface; + IDirectDraw7 *ddraw; + IDirect3D7 *d3d; + ULONG refcount; + DWORD stateblock; + DWORD value; + HWND window; + HRESULT hr; + + window = create_window(); + if (!(device = create_device_ex(window, DDSCL_NORMAL, &IID_IDirect3DTnLHalDevice, &surface))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice7_GetDirect3D(device, &d3d); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + hr = IDirect3D7_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device2); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + hr = IDirect3DDevice7_CreateStateBlock(device, D3DSBT_ALL, &stateblock); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice7_CaptureStateBlock(device2, stateblock); + ok(hr == D3DERR_INVALIDSTATEBLOCK, "got %#lx.\n", hr); + hr = IDirect3DDevice7_CaptureStateBlock(device, stateblock); + ok(hr == D3D_OK, "got %#lx.\n", hr); + hr = IDirect3DDevice7_DeleteStateBlock(device, stateblock); + ok(hr == D3D_OK, "got %#lx.\n", hr); + + hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice3_SetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + value = 0xdeadbeef; + hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(value == TRUE, "got %#lx.\n", value); + hr = IDirect3DDevice3_GetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, &value); + ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); + ok(!value, "got %#lx.\n", value); + + refcount = IDirect3DDevice3_Release(device); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3DDevice3_Release(device2); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirectDrawSurface4_Release(surface); + ok(!refcount, "Surface has %lu references left.\n", refcount); + IDirectDraw4_Release(ddraw); + IDirect3D3_Release(d3d); + DestroyWindow(window); +} + START_TEST(ddraw7) { DDDEVICEIDENTIFIER2 identifier; @@ -20176,4 +20247,5 @@ START_TEST(ddraw7) test_enum_devices(); run_for_each_device_type(test_user_memory); test_flip_3d(); + test_multiple_devices(); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=144327
Your paranoid android.
=== w11pro64_amd (64 bit report) ===
ddraw: ddraw2.c:3268: Test failed: Got unexpected screen size 800x600. ddraw2.c:3357: Test failed: Expected surface width 1024, got 640. ddraw2.c:3359: Test failed: Expected surface height 768, got 480. ddraw2.c:3377: Test failed: Expected surface width 1024, got 640. ddraw2.c:3379: Test failed: Expected surface height 768, got 480. ddraw2.c:3392: Test failed: Expected surface width 1024, got 640. ddraw2.c:3394: Test failed: Expected surface height 768, got 480. ddraw2.c:3458: Test failed: Expected surface width 1024, got 640. ddraw2.c:3460: Test failed: Expected surface height 768, got 480. ddraw2.c:3514: Test failed: Expected resolution 1024x768, got 640x480. ddraw2.c:3531: Test failed: Expected surface width 1024, got 640. ddraw2.c:3533: Test failed: Expected surface height 768, got 480. ddraw2.c:3554: Test failed: Expected surface width 1024, got 640. ddraw2.c:3556: Test failed: Expected surface height 768, got 480. ddraw2.c:3569: Test failed: Expected surface width 1024, got 640. ddraw2.c:3571: Test failed: Expected surface height 768, got 480. ddraw2.c:3628: Test failed: Expected surface width 1024, got 640. ddraw2.c:3630: Test failed: Expected surface height 768, got 480. ddraw2.c:3684: Test failed: Expected resolution 1024x768, got 640x480. ddraw2.c:3701: Test failed: Expected surface width 1024, got 640. ddraw2.c:3703: Test failed: Expected surface height 768, got 480. ddraw2.c:3728: Test failed: Expected screen size 1024x768, got 0x0. ddraw2.c:3735: Test failed: Expected (0,0)-(1024,768), got (0,0)-(640,480). ddraw2.c:3747: Test failed: Expected surface width 1024, got 640. ddraw2.c:3749: Test failed: Expected surface height 768, got 480. ddraw2.c:3800: Test failed: Expected screen size 2 1024x768, got 0x0. ddraw2.c:3808: Test failed: Expected (0,0)-(1024,768), got (0,0)-(136,100). ddraw2.c:3820: Test failed: Expected surface width 1024, got 640. ddraw2.c:3822: Test failed: Expected surface height 768, got 480. ddraw2.c:3979: Test failed: Got unexpected screen width 800. ddraw2.c:3981: Test failed: Got unexpected screen height 600. ddraw2.c:4124: Test failed: Got unexpected screen width 800. ddraw2.c:4126: Test failed: Got unexpected screen height 600. ddraw2.c:4131: Test failed: Got unexpected screen width 800. ddraw2.c:4133: Test failed: Got unexpected screen height 600.
=== w11pro64_amd (64 bit report) ===
ddraw: ddraw4.c:3600: Test failed: Expected surface width 1024, got 640. ddraw4.c:3602: Test failed: Expected surface height 768, got 480. ddraw4.c:3620: Test failed: Expected surface width 1024, got 640. ddraw4.c:3622: Test failed: Expected surface height 768, got 480. ddraw4.c:3635: Test failed: Expected surface width 1024, got 640. ddraw4.c:3637: Test failed: Expected surface height 768, got 480. ddraw4.c:3694: Test failed: Expected surface width 1024, got 640. ddraw4.c:3696: Test failed: Expected surface height 768, got 480. ddraw4.c:3750: Test failed: Expected resolution 1024x768, got 640x480. ddraw4.c:3767: Test failed: Expected surface width 1024, got 640. ddraw4.c:3769: Test failed: Expected surface height 768, got 480. ddraw4.c:3790: Test failed: Expected surface width 1024, got 640. ddraw4.c:3792: Test failed: Expected surface height 768, got 480. ddraw4.c:3805: Test failed: Expected surface width 1024, got 640. ddraw4.c:3807: Test failed: Expected surface height 768, got 480. ddraw4.c:3864: Test failed: Expected surface width 1024, got 640. ddraw4.c:3866: Test failed: Expected surface height 768, got 480. ddraw4.c:3920: Test failed: Expected resolution 1024x768, got 640x480. ddraw4.c:3937: Test failed: Expected surface width 1024, got 640. ddraw4.c:3939: Test failed: Expected surface height 768, got 480. ddraw4.c:3964: Test failed: Expected screen size 1024x768, got 0x0. ddraw4.c:3971: Test failed: Expected (0,0)-(1024,768), got (0,0)-(640,480). ddraw4.c:3983: Test failed: Expected surface width 1024, got 640. ddraw4.c:3985: Test failed: Expected surface height 768, got 480. ddraw4.c:4036: Test failed: Expected screen size 2 1024x768, got 0x0. ddraw4.c:4044: Test failed: Expected (0,0)-(1024,768), got (0,0)-(136,100). ddraw4.c:4056: Test failed: Expected surface width 1024, got 640. ddraw4.c:4058: Test failed: Expected surface height 768, got 480. ddraw4.c:4232: Test failed: Got unexpected screen width 640. ddraw4.c:4234: Test failed: Got unexpected screen height 480. ddraw4.c:4239: Test failed: Got unexpected screen width 640. ddraw4.c:4241: Test failed: Got unexpected screen height 480. ddraw4.c:4263: Test failed: Got unexpected screen width 640. ddraw4.c:4265: Test failed: Got unexpected screen height 480. ddraw4.c:4270: Test failed: Got unexpected screen width 640. ddraw4.c:4272: Test failed: Got unexpected screen height 480. ddraw4.c:4294: Test failed: Got unexpected screen width 640. ddraw4.c:4296: Test failed: Got unexpected screen height 480. ddraw4.c:4329: Test failed: Got unexpected screen width 640. ddraw4.c:4331: Test failed: Got unexpected screen height 480. ddraw4.c:8551: Test failed: Failed to create surface, hr 0x80070057. ddraw4.c:8560: Test failed: Failed to create surface, hr 0x80070057. ddraw4.c:8573: Test failed: Failed to attach surface, hr 0x80070057.
v5: - remove extra locking around global handle table.
This merge request was approved by Zebediah Figura.
This merge request was approved by Jan Sikorski.