Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ddraw/ddraw.c | 6 +++--- dlls/ddraw/ddraw_private.h | 3 ++- dlls/ddraw/device.c | 12 +++++++----- dlls/ddraw/surface.c | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index d616330c307..705d0335d95 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -4330,7 +4330,7 @@ static HRESULT WINAPI d3d7_CreateDevice(IDirect3D7 *iface, REFCLSID riid, TRACE("iface %p, riid %s, surface %p, device %p.\n", iface, debugstr_guid(riid), surface, device);
wined3d_mutex_lock(); - if (SUCCEEDED(hr = d3d_device_create(ddraw, target, (IUnknown *)surface, 7, &object, NULL))) + if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, target, (IUnknown *)surface, 7, &object, NULL))) { *device = &object->IDirect3DDevice7_iface; } @@ -4359,7 +4359,7 @@ static HRESULT WINAPI d3d3_CreateDevice(IDirect3D3 *iface, REFCLSID riid, return CLASS_E_NOAGGREGATION;
wined3d_mutex_lock(); - if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL))) + if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL))) { *device = &device_impl->IDirect3DDevice3_iface; } @@ -4385,7 +4385,7 @@ static HRESULT WINAPI d3d2_CreateDevice(IDirect3D2 *iface, REFCLSID riid, iface, debugstr_guid(riid), surface, device);
wined3d_mutex_lock(); - if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL))) + if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL))) { *device = &device_impl->IDirect3DDevice2_iface; } diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 6bbd62949ac..e25ab23c2bc 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -317,6 +317,7 @@ struct d3d_device IUnknown IUnknown_inner; LONG ref; UINT version; + BOOL hardware_device;
IUnknown *outer_unknown; struct wined3d_device *wined3d_device; @@ -364,7 +365,7 @@ struct d3d_device const struct wined3d_stateblock_state *stateblock_state; };
-HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface, +HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface, UINT version, struct d3d_device **device, IUnknown *outer_unknown) DECLSPEC_HIDDEN; enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device *device) DECLSPEC_HIDDEN;
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 4d24c22650e..5e66007213d 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -6925,7 +6925,7 @@ static void ddraw_reset_viewport_state(struct ddraw *ddraw) wined3d_stateblock_set_scissor_rect(ddraw->state, &rect); }
-static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, +static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface, UINT version, IUnknown *outer_unknown) { static const struct wined3d_matrix ident = @@ -6948,6 +6948,8 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, device->IUnknown_inner.lpVtbl = &d3d_device_inner_vtbl; device->ref = 1; device->version = version; + device->hardware_device = IsEqualGUID(&IID_IDirect3DTnLHalDevice, guid) + || IsEqualGUID(&IID_IDirect3DHALDevice, guid);
if (outer_unknown) device->outer_unknown = outer_unknown; @@ -7006,14 +7008,14 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, return D3D_OK; }
-HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface, +HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface, UINT version, struct d3d_device **device, IUnknown *outer_unknown) { struct d3d_device *object; HRESULT hr;
- TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n", - ddraw, target, version, device, outer_unknown); + TRACE("ddraw %p, guid %s, target %p, version %u, device %p, outer_unknown %p.\n", + ddraw, debugstr_guid(guid), target, version, device, outer_unknown);
if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) || (target->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) @@ -7054,7 +7056,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUn return DDERR_OUTOFMEMORY; }
- if (FAILED(hr = d3d_device_init(object, ddraw, target, rt_iface, version, outer_unknown))) + if (FAILED(hr = d3d_device_init(object, ddraw, guid, target, rt_iface, version, outer_unknown))) { WARN("Failed to initialize device, hr %#x.\n", hr); heap_free(object); diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 0ca19d4f8a5..b910fb6817e 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -256,7 +256,7 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface, { HRESULT hr;
- if (FAILED(hr = d3d_device_create(This->ddraw, This, (IUnknown *)&This->IDirectDrawSurface_iface, + if (FAILED(hr = d3d_device_create(This->ddraw, riid, This, (IUnknown *)&This->IDirectDrawSurface_iface, 1, &This->device1, (IUnknown *)&This->IDirectDrawSurface_iface))) { This->device1 = NULL;
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ddraw/ddraw_private.h | 55 ++++++++++++ dlls/ddraw/device.c | 18 ++-- dlls/ddraw/surface.c | 167 +++++++++++++++++++++++++++++++------ dlls/ddraw/tests/ddraw1.c | 1 - dlls/ddraw/tests/ddraw2.c | 1 - dlls/ddraw/tests/ddraw4.c | 1 - dlls/ddraw/tests/ddraw7.c | 7 +- 7 files changed, 207 insertions(+), 43 deletions(-)
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index e25ab23c2bc..c6fb8d5f3a3 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -155,6 +155,9 @@ void DDRAW_Convert_DDSCAPS_1_To_2(const DDSCAPS *pIn, DDSCAPS2 *pOut) DECLSPEC_H void DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(const DDDEVICEIDENTIFIER2 *pIn, DDDEVICEIDENTIFIER *pOut) DECLSPEC_HIDDEN; struct wined3d_vertex_declaration *ddraw_find_decl(struct ddraw *ddraw, DWORD fvf) DECLSPEC_HIDDEN;
+#define DDRAW_SURFACE_LOCATION_DEFAULT 0x00000001 +#define DDRAW_SURFACE_LOCATION_DRAW 0x00000002 + struct ddraw_surface { /* IUnknown fields */ @@ -175,7 +178,9 @@ struct ddraw_surface
/* Connections to other Objects */ struct ddraw *ddraw; + unsigned int texture_location; struct wined3d_texture *wined3d_texture; + struct wined3d_texture *draw_texture; unsigned int sub_resource_idx; struct wined3d_rendertarget_view *wined3d_rtv; struct wined3d_private_store private_store; @@ -653,6 +658,56 @@ static inline BOOL ddraw_surface_can_be_lost(const struct ddraw_surface *surface return surface->sysmem_fallback; }
+#define DDRAW_SURFACE_READ 0x00000001 +#define DDRAW_SURFACE_WRITE 0x00000002 +#define DDRAW_SURFACE_RW (DDRAW_SURFACE_READ | DDRAW_SURFACE_WRITE) + +static inline struct wined3d_texture *ddraw_surface_get_default_texture(struct ddraw_surface *surface, unsigned int flags) +{ + if (surface->draw_texture) + { + if (flags & DDRAW_SURFACE_READ && !(surface->texture_location & DDRAW_SURFACE_LOCATION_DEFAULT)) + { + wined3d_device_copy_sub_resource_region(surface->ddraw->wined3d_device, + wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, 0, 0, 0, + wined3d_texture_get_resource(surface->draw_texture), surface->sub_resource_idx, NULL, 0); + surface->texture_location |= DDRAW_SURFACE_LOCATION_DEFAULT; + } + + if (flags & DDRAW_SURFACE_WRITE) + surface->texture_location = DDRAW_SURFACE_LOCATION_DEFAULT; + } + return surface->wined3d_texture; +} + +static inline struct wined3d_texture *ddraw_surface_get_draw_texture(struct ddraw_surface *surface, unsigned int flags) +{ + if (!surface->draw_texture) + return surface->wined3d_texture; + + if (flags & DDRAW_SURFACE_READ && !(surface->texture_location & DDRAW_SURFACE_LOCATION_DRAW)) + { + wined3d_device_copy_sub_resource_region(surface->ddraw->wined3d_device, + wined3d_texture_get_resource(surface->draw_texture), surface->sub_resource_idx, 0, 0, 0, + wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, NULL, 0); + surface->texture_location |= DDRAW_SURFACE_LOCATION_DRAW; + } + + if (flags & DDRAW_SURFACE_WRITE) + surface->texture_location = DDRAW_SURFACE_LOCATION_DRAW; + + return surface->draw_texture; +} + +static inline struct wined3d_texture *ddraw_surface_get_any_texture(struct ddraw_surface *surface, unsigned int flags) +{ + if (surface->texture_location & DDRAW_SURFACE_LOCATION_DEFAULT) + return ddraw_surface_get_default_texture(surface, flags); + + assert(surface->texture_location & DDRAW_SURFACE_LOCATION_DRAW); + return ddraw_surface_get_draw_texture(surface, flags); +} + /* Used for generic dumping */ struct flag_info { diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 5e66007213d..ea81972064e 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -1898,7 +1898,7 @@ static HRESULT d3d_device7_SetRenderTarget(IDirect3DDevice7 *iface, return DDERR_INVALIDCAPS; }
- if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + if (device->hardware_device && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) { WARN("Surface %p is not in video memory.\n", target_impl); wined3d_mutex_unlock(); @@ -1974,7 +1974,7 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface, return DDERR_INVALIDPIXELFORMAT; }
- if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + if (device->hardware_device && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) { WARN("Surface %p is not in video memory.\n", target_impl); IDirectDrawSurface4_AddRef(target); @@ -2023,7 +2023,7 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface, return DDERR_INVALIDPIXELFORMAT; }
- if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + if (device->hardware_device && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) { WARN("Surface %p is not in video memory.\n", target_impl); IDirectDrawSurface_AddRef(target); @@ -6951,6 +6951,12 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c device->hardware_device = IsEqualGUID(&IID_IDirect3DTnLHalDevice, guid) || IsEqualGUID(&IID_IDirect3DHALDevice, guid);
+ if (device->hardware_device && !(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + WARN("Surface %p is not in video memory.\n", target); + return D3DERR_SURFACENOTINVIDMEM; + } + if (outer_unknown) device->outer_unknown = outer_unknown; else @@ -7038,12 +7044,6 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su return DDERR_OUTOFMEMORY; }
- if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) - { - WARN("Surface %p is not in video memory.\n", target); - return D3DERR_SURFACENOTINVIDMEM; - } - if (ddraw->d3ddevice) { FIXME("Only one Direct3D device per DirectDraw object supported.\n"); diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index b910fb6817e..1e1a1a721c5 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -56,8 +56,8 @@ static BOOL ddraw_gdi_is_front(struct ddraw *ddraw) HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read, unsigned int swap_interval) { + struct wined3d_texture *dst_texture, *src_texture; struct ddraw *ddraw = surface->ddraw; - struct wined3d_texture *dst_texture; HDC surface_dc, screen_dc; int x, y, w, h; HRESULT hr; @@ -112,8 +112,9 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, else dst_texture = ddraw->wined3d_frontbuffer;
- if (SUCCEEDED(hr = wined3d_texture_blt(dst_texture, 0, rect, surface->wined3d_texture, - surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT)) && swap_interval) + if (SUCCEEDED(hr = wined3d_texture_blt(dst_texture, 0, rect, + ddraw_surface_get_any_texture(surface, DDRAW_SURFACE_READ), surface->sub_resource_idx, rect, 0, + NULL, WINED3D_TEXF_POINT)) && swap_interval) { hr = wined3d_swapchain_present(ddraw->wined3d_swapchain, rect, rect, NULL, swap_interval, 0); ddraw->flags |= DDRAW_SWAPPED; @@ -121,7 +122,9 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, return hr; }
- if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, &surface_dc))) + src_texture = ddraw_surface_get_default_texture(surface, DDRAW_SURFACE_READ); + + if (FAILED(hr = wined3d_texture_get_dc(src_texture, surface->sub_resource_idx, &surface_dc))) { ERR("Failed to get surface DC, hr %#x.\n", hr); return hr; @@ -131,7 +134,7 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,
if (!(screen_dc = GetDC(NULL))) { - wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, surface_dc); + wined3d_texture_release_dc(src_texture, surface->sub_resource_idx, surface_dc); ERR("Failed to get screen DC.\n"); return E_FAIL; } @@ -144,7 +147,7 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, surface_dc, x, y, SRCCOPY);
ReleaseDC(NULL, screen_dc); - wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, surface_dc); + wined3d_texture_release_dc(src_texture, surface->sub_resource_idx, surface_dc);
if (!ret) { @@ -1057,9 +1060,9 @@ static HRESULT surface_lock(struct ddraw_surface *surface, if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE, 0); if (SUCCEEDED(hr)) - hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), - surface->sub_resource_idx, &map_desc, rect ? &box : NULL, - wined3dmapflags_from_ddrawmapflags(flags)); + hr = wined3d_resource_map(wined3d_texture_get_resource + (ddraw_surface_get_default_texture(surface, DDRAW_SURFACE_RW)), surface->sub_resource_idx, + &map_desc, rect ? &box : NULL, wined3dmapflags_from_ddrawmapflags(flags)); if (FAILED(hr)) { wined3d_mutex_unlock(); @@ -1235,7 +1238,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Unlock(IDirectDrawSurface TRACE("iface %p, data %p.\n", iface, data);
wined3d_mutex_lock(); - hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); + hr = wined3d_resource_unmap(wined3d_texture_get_resource + (ddraw_surface_get_default_texture(surface, 0)), surface->sub_resource_idx); if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE, 0); wined3d_mutex_unlock(); @@ -1307,7 +1311,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * struct ddraw_texture *dst_ddraw_texture, *src_ddraw_texture; struct wined3d_rendertarget_view *tmp_rtv, *src_rtv, *rtv; DDSCAPS caps = {DDSCAPS_FLIP}; - struct wined3d_texture *texture; + struct wined3d_texture *texture, *draw_texture; IDirectDrawSurface *current; void *texture_memory; HRESULT hr; @@ -1337,6 +1341,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * rtv = wined3d_device_get_rendertarget_view(dst_impl->ddraw->wined3d_device, 0); dst_ddraw_texture = wined3d_texture_get_parent(dst_impl->wined3d_texture); texture_memory = dst_ddraw_texture->texture_memory; + draw_texture = dst_impl->draw_texture;
if (src_impl) { @@ -1363,13 +1368,18 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); dst_impl->wined3d_rtv = src_rtv; wined3d_texture_set_sub_resource_parent(src_impl->wined3d_texture, 0, dst_impl); + if (src_impl->draw_texture) + wined3d_texture_set_sub_resource_parent(src_impl->draw_texture, 0, dst_impl); src_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture); dst_ddraw_texture->texture_memory = src_ddraw_texture->texture_memory; wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_texture), dst_ddraw_texture); + if (src_impl->draw_texture) + wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->draw_texture), dst_ddraw_texture); dst_ddraw_texture = src_ddraw_texture; if (src_impl->sub_resource_idx) ERR("Invalid sub-resource index %u on surface %p.\n", src_impl->sub_resource_idx, src_impl); dst_impl->wined3d_texture = src_impl->wined3d_texture; + dst_impl->draw_texture = src_impl->draw_texture; } else { @@ -1395,13 +1405,18 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); dst_impl->wined3d_rtv = src_rtv; wined3d_texture_set_sub_resource_parent(src_impl->wined3d_texture, 0, dst_impl); + if (src_impl->draw_texture) + wined3d_texture_set_sub_resource_parent(src_impl->draw_texture, 0, dst_impl); src_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture); dst_ddraw_texture->texture_memory = src_ddraw_texture->texture_memory; wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_texture), dst_ddraw_texture); + if (src_impl->draw_texture) + wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->draw_texture), dst_ddraw_texture); dst_ddraw_texture = src_ddraw_texture; if (src_impl->sub_resource_idx) ERR("Invalid sub-resource index %u on surface %p.\n", src_impl->sub_resource_idx, src_impl); dst_impl->wined3d_texture = src_impl->wined3d_texture; + dst_impl->draw_texture = src_impl->draw_texture; dst_impl = src_impl; } } @@ -1413,9 +1428,14 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * wined3d_rendertarget_view_set_parent(tmp_rtv, src_impl); src_impl->wined3d_rtv = tmp_rtv; wined3d_texture_set_sub_resource_parent(texture, 0, src_impl); + if (draw_texture) + wined3d_texture_set_sub_resource_parent(draw_texture, 0, src_impl); dst_ddraw_texture->texture_memory = texture_memory; wined3d_resource_set_parent(wined3d_texture_get_resource(texture), dst_ddraw_texture); + if (draw_texture) + wined3d_resource_set_parent(wined3d_texture_get_resource(draw_texture), dst_ddraw_texture); src_impl->wined3d_texture = texture; + src_impl->draw_texture = draw_texture;
if (flags & ~(DDFLIP_NOVSYNC | DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4)) { @@ -1503,6 +1523,7 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT * return DDERR_INVALIDPARAMS;
wined3d_device_apply_stateblock(wined3d_device, dst_surface->ddraw->state); + ddraw_surface_get_draw_texture(dst_surface, dst_rect ? DDRAW_SURFACE_RW : DDRAW_SURFACE_WRITE); return wined3d_device_clear_rendertarget_view(wined3d_device, ddraw_surface_get_rendertarget_view(dst_surface), dst_rect, wined3d_flags, &colour, 0.0f, 0); @@ -1519,6 +1540,7 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT * return DDERR_INVALIDPARAMS;
wined3d_device_apply_stateblock(wined3d_device, dst_surface->ddraw->state); + ddraw_surface_get_draw_texture(dst_surface, dst_rect ? DDRAW_SURFACE_RW : DDRAW_SURFACE_WRITE); return wined3d_device_clear_rendertarget_view(wined3d_device, ddraw_surface_get_rendertarget_view(dst_surface), dst_rect, wined3d_flags, NULL, colour.r, 0); @@ -1534,8 +1556,9 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT * if (!(flags & DDBLT_ASYNC)) wined3d_flags |= WINED3D_BLT_SYNCHRONOUS;
- return wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, dst_rect, - src_surface->wined3d_texture, src_surface->sub_resource_idx, src_rect, wined3d_flags, fx, filter); + return wined3d_texture_blt(ddraw_surface_get_any_texture(dst_surface, DDRAW_SURFACE_RW), + dst_surface->sub_resource_idx, dst_rect, ddraw_surface_get_any_texture(src_surface, DDRAW_SURFACE_READ), + src_surface->sub_resource_idx, src_rect, wined3d_flags, fx, filter); }
static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, const RECT *dst_rect_in, @@ -2305,7 +2328,7 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *dc) else if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE, 0); if (SUCCEEDED(hr)) - hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, dc); + hr = wined3d_texture_get_dc(ddraw_surface_get_default_texture(surface, DDRAW_SURFACE_RW), surface->sub_resource_idx, dc);
if (SUCCEEDED(hr)) { @@ -2401,7 +2424,8 @@ static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC h { hr = DDERR_NODC; } - else if (SUCCEEDED(hr = wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, hdc))) + else if (SUCCEEDED(hr = wined3d_texture_release_dc(ddraw_surface_get_default_texture(surface, 0), + surface->sub_resource_idx, hdc))) { surface->dc = NULL; if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) @@ -2551,6 +2575,9 @@ static HRESULT WINAPI ddraw_surface7_SetPriority(IDirectDrawSurface7 *iface, DWO { resource = wined3d_texture_get_resource(surface->wined3d_texture); wined3d_resource_set_priority(resource, priority); + if (surface->draw_texture) + wined3d_resource_set_priority(wined3d_texture_get_resource(surface->draw_texture), priority); + hr = DD_OK; } wined3d_mutex_unlock(); @@ -4267,6 +4294,8 @@ static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD Ma }
hr = wined3d_texture_set_lod(surface->wined3d_texture, MaxLOD); + if (SUCCEEDED(hr) && surface->draw_texture) + hr = wined3d_texture_set_lod(surface->draw_texture, MaxLOD); wined3d_mutex_unlock();
return hr; @@ -4376,8 +4405,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_BltFast(IDirectDrawSurfac if (src_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE, 0); if (SUCCEEDED(hr)) - hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect, - src_impl->wined3d_texture, src_impl->sub_resource_idx, src_rect, flags, NULL, WINED3D_TEXF_POINT); + hr = wined3d_texture_blt(ddraw_surface_get_any_texture(dst_impl, DDRAW_SURFACE_RW), + dst_impl->sub_resource_idx, &dst_rect, ddraw_surface_get_any_texture(src_impl,DDRAW_SURFACE_READ), + src_impl->sub_resource_idx, src_rect, flags, NULL, WINED3D_TEXF_POINT); if (SUCCEEDED(hr) && (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE, 0); wined3d_mutex_unlock(); @@ -4736,6 +4766,14 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, return hr_ddraw_from_wined3d(hr); }
+ if (surface->draw_texture && FAILED(hr = wined3d_texture_update_desc(surface->draw_texture, + surface->sub_resource_idx, width, height, format_id, WINED3D_MULTISAMPLE_NONE, 0, NULL, 0))) + { + ERR("Failed to update surface desc for draw_texture, hr %#x.\n", hr); + wined3d_mutex_unlock(); + return hr_ddraw_from_wined3d(hr); + } + if (DDSD->dwFlags & DDSD_WIDTH) surface->surface_desc.dwWidth = width; if (DDSD->dwFlags & DDSD_PITCH) @@ -4842,6 +4880,18 @@ static HRESULT WINAPI ddraw_surface1_GetPalette(IDirectDrawSurface *iface, IDire return ddraw_surface7_GetPalette(&surface->IDirectDrawSurface7_iface, palette); }
+static HRESULT ddraw_surface_set_wined3d_textures_colour_key(struct ddraw_surface *surface, DWORD flags, + struct wined3d_color_key *color_key) +{ + HRESULT hr; + + hr = wined3d_texture_set_color_key(surface->wined3d_texture, flags, color_key); + if (surface->draw_texture && SUCCEEDED(hr)) + hr = wined3d_texture_set_color_key(surface->draw_texture, flags, color_key); + + return hr; +} + static HRESULT ddraw_surface_set_color_key(struct ddraw_surface *surface, DWORD flags, DDCOLORKEY *color_key) { DDCOLORKEY fixed_color_key; @@ -4916,7 +4966,7 @@ static HRESULT ddraw_surface_set_color_key(struct ddraw_surface *surface, DWORD }
if (surface->is_complex_root) - hr = wined3d_texture_set_color_key(surface->wined3d_texture, flags, + hr = ddraw_surface_set_wined3d_textures_colour_key(surface, flags, color_key ? (struct wined3d_color_key *)&fixed_color_key : NULL);
wined3d_mutex_unlock(); @@ -5293,8 +5343,8 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
wined3d_mutex_lock();
- dst_resource = wined3d_texture_get_resource(dst_surface->wined3d_texture); - src_resource = wined3d_texture_get_resource(src_surface->wined3d_texture); + dst_resource = wined3d_texture_get_resource(ddraw_surface_get_default_texture(dst_surface, DDRAW_SURFACE_WRITE)); + src_resource = wined3d_texture_get_resource(ddraw_surface_get_default_texture(src_surface, DDRAW_SURFACE_READ));
if (((src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) @@ -5832,6 +5882,9 @@ static void STDMETHODCALLTYPE ddraw_surface_wined3d_object_destroyed(void *paren
wined3d_private_store_cleanup(&surface->private_store);
+ if (surface->draw_texture) + wined3d_texture_decref(surface->draw_texture); + heap_free(surface); }
@@ -5902,6 +5955,65 @@ static HRESULT ddraw_surface_reserve_memory(struct wined3d_texture *wined3d_text return hr; }
+static void ddraw_surface_create_draw_texture(struct ddraw_surface *surface) +{ + DDSURFACEDESC2 *desc = &surface->surface_desc; + struct wined3d_resource *draw_texture_resource; + struct wined3d_resource_desc wined3d_desc; + unsigned int i, layer_count, level_count; + struct wined3d_texture *draw_texture; + struct ddraw_surface *parent; + unsigned int bind_flags; + HRESULT hr; + + if (!(desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) + return; + + bind_flags = 0; + if ((desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) + || (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE)) + bind_flags |= WINED3D_BIND_SHADER_RESOURCE; + + if (desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) + bind_flags |= WINED3D_BIND_DEPTH_STENCIL; + else if (desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) + bind_flags |= WINED3D_BIND_RENDER_TARGET; + + if (!bind_flags) + return; + + layer_count = surface->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP ? 6 : 1; + level_count = wined3d_texture_get_level_count(surface->wined3d_texture); + + draw_texture_resource = wined3d_texture_get_resource(surface->wined3d_texture); + wined3d_resource_get_desc(draw_texture_resource, &wined3d_desc); + + wined3d_desc.bind_flags = bind_flags; + wined3d_desc.access = WINED3D_RESOURCE_ACCESS_GPU; + + if (FAILED(hr = wined3d_texture_create(surface->ddraw->wined3d_device, &wined3d_desc, layer_count, + level_count, 0, NULL, NULL, + &ddraw_null_wined3d_parent_ops, &draw_texture))) + { + WARN("Failed to create wined3d texture, hr %#x.\n", hr); + return; + } + + wined3d_resource_set_parent(draw_texture_resource, wined3d_texture_get_parent(surface->wined3d_texture)); + + i = 0; + while ((parent = wined3d_texture_get_sub_resource_parent(surface->wined3d_texture, i))) + { + wined3d_texture_set_sub_resource_parent(draw_texture, i, parent); + wined3d_texture_incref(parent->draw_texture = draw_texture); + ++i; + } + assert(surface->draw_texture); + + wined3d_texture_decref(draw_texture); + TRACE("Surface %p, created draw_texture %p.\n", surface, draw_texture); +} + HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc, struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) { @@ -6416,22 +6528,24 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
root = wined3d_texture_get_sub_resource_parent(wined3d_texture, 0); wined3d_texture_decref(wined3d_texture); + ddraw_surface_create_draw_texture(root); + root->is_complex_root = TRUE; root->sysmem_fallback = sysmem_fallback; texture->root = root; wined3d_device_incref(texture->wined3d_device = ddraw->wined3d_device);
if (desc->dwFlags & DDSD_CKDESTOVERLAY) - wined3d_texture_set_color_key(wined3d_texture, DDCKEY_DESTOVERLAY, + ddraw_surface_set_wined3d_textures_colour_key(root, DDCKEY_DESTOVERLAY, (struct wined3d_color_key *)&desc->u3.ddckCKDestOverlay); if (desc->dwFlags & DDSD_CKDESTBLT) - wined3d_texture_set_color_key(wined3d_texture, DDCKEY_DESTBLT, + ddraw_surface_set_wined3d_textures_colour_key(root, DDCKEY_DESTBLT, (struct wined3d_color_key *)&desc->ddckCKDestBlt); if (desc->dwFlags & DDSD_CKSRCOVERLAY) - wined3d_texture_set_color_key(wined3d_texture, DDCKEY_SRCOVERLAY, + ddraw_surface_set_wined3d_textures_colour_key(root, DDCKEY_SRCOVERLAY, (struct wined3d_color_key *)&desc->ddckCKSrcOverlay); if (desc->dwFlags & DDSD_CKSRCBLT) - wined3d_texture_set_color_key(wined3d_texture, DDCKEY_SRCBLT, + ddraw_surface_set_wined3d_textures_colour_key(root, DDCKEY_SRCBLT, (struct wined3d_color_key *)&desc->ddckCKSrcBlt);
for (i = 0; i < layers; ++i) @@ -6573,7 +6687,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ hr = hr_ddraw_from_wined3d(hr); goto fail; } - + ddraw_surface_create_draw_texture(last); *attach = last; attach = &last->complex_array[0]; } @@ -6663,6 +6777,7 @@ void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, wined3d_texture_incref(surface->wined3d_texture = wined3d_texture); surface->sub_resource_idx = sub_resource_idx; *parent_ops = &ddraw_surface_wined3d_parent_ops; + surface->texture_location = DDRAW_SURFACE_LOCATION_DEFAULT;
wined3d_private_store_init(&surface->private_store); } @@ -6695,7 +6810,7 @@ struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddr if (surface->wined3d_rtv) return surface->wined3d_rtv;
- if (FAILED(hr = wined3d_rendertarget_view_create_from_sub_resource(surface->wined3d_texture, + if (FAILED(hr = wined3d_rendertarget_view_create_from_sub_resource(ddraw_surface_get_draw_texture(surface, 0), surface->sub_resource_idx, surface, &ddraw_view_wined3d_parent_ops, &surface->wined3d_rtv))) { ERR("Failed to create rendertarget view, hr %#x.\n", hr); diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 57bc622e48b..e75a9fac0a8 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -4580,7 +4580,6 @@ static void test_rt_caps(const GUID *device_guid) }
hr = IDirectDrawSurface_QueryInterface(surface, device_guid, (void **)&device); - todo_wine_if(software_device && test_data[i].create_device_hr == D3DERR_SURFACENOTINVIDMEM) ok((!software_device && hr == test_data[i].create_device_hr) || (software_device && (hr == (test_data[i].create_device_hr == D3DERR_SURFACENOTINVIDMEM ? DD_OK : test_data[i].create_device_hr))), diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index d2889aa05d7..b882589f2ad 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -5053,7 +5053,6 @@ static void test_rt_caps(const GUID *device_guid)
hr = IDirect3D2_CreateDevice(d3d, device_guid, surface, &device);
- todo_wine_if(software_device && test_data[i].create_device_hr == D3DERR_SURFACENOTINVIDMEM) ok((!software_device && hr == test_data[i].create_device_hr) || (software_device && (hr == (test_data[i].create_device_hr == D3DERR_SURFACENOTINVIDMEM ? DD_OK : test_data[i].create_device_hr))), diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 6e003fbfb7e..42936fd7c74 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -6706,7 +6706,6 @@ static void test_rt_caps(const GUID *device_guid)
hr = IDirect3D3_CreateDevice(d3d, device_guid, surface, &device, NULL);
- todo_wine_if(software_device && test_data[i].create_device_hr == D3DERR_SURFACENOTINVIDMEM) ok((!software_device && hr == test_data[i].create_device_hr) || (software_device && (hr == (test_data[i].create_device_hr == D3DERR_SURFACENOTINVIDMEM ? DD_OK : test_data[i].create_device_hr))), diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 559d13d035c..7e83d26d6db 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -6419,10 +6419,8 @@ static void test_rt_caps(const GUID *device_guid) expected_caps = test_data[i].caps_out[software_device] ? test_data[i].caps_out[software_device] : test_data[i].caps_out[0];
- todo_wine_if(test_data[i].caps_out[software_device] - && surface_desc.ddsCaps.dwCaps == test_data[i].caps_out[0]) ok(surface_desc.ddsCaps.dwCaps == expected_caps - || broken(surface_desc.ddsCaps.dwCaps == test_data[i].caps_out[0]), + || surface_desc.ddsCaps.dwCaps == test_data[i].caps_out[0], "Got unexpected caps %#x, test %u, software_device %u.\n", surface_desc.ddsCaps.dwCaps, i, software_device); } @@ -6437,7 +6435,6 @@ static void test_rt_caps(const GUID *device_guid) surface_desc.ddsCaps.dwCaps2, test_data[i].caps2_out, i, software_device);
hr = IDirect3D7_CreateDevice(d3d, device_guid, surface, &device); - todo_wine_if(software_device && test_data[i].create_device_hr == D3DERR_SURFACENOTINVIDMEM) ok((!software_device && hr == test_data[i].create_device_hr) || (software_device && (hr == (test_data[i].create_device_hr == D3DERR_SURFACENOTINVIDMEM ? DD_OK : test_data[i].create_device_hr))), @@ -6492,7 +6489,7 @@ static void test_rt_caps(const GUID *device_guid)
hr = IDirect3DDevice7_SetRenderTarget(device, rt, 0); ok(hr == test_data[i].set_rt_hr || (software_device && hr == DDERR_NOPALETTEATTACHED) - || broken(hr == test_data[i].alternative_set_rt_hr), + || hr == test_data[i].alternative_set_rt_hr, "Got unexpected hr %#x, test %u, software_device %u.\n", hr, i, software_device); if (SUCCEEDED(hr) || hr == DDERR_INVALIDPIXELFORMAT)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=86128
Your paranoid android.
=== debiant2 (32 bit report) ===
ddraw: visual.c:1326: Test failed: DDSCAPS2_CUBEMAP_POSITIVEX has color 0x00000000, expected 0x00ff0000 visual.c:1328: Test failed: DDSCAPS2_CUBEMAP_NEGATIVEX has color 0x00000000, expected 0x0000ffff visual.c:1330: Test failed: DDSCAPS2_CUBEMAP_POSITIVEY has color 0x00000000, expected 0x00ff00ff visual.c:1332: Test failed: DDSCAPS2_CUBEMAP_POSITIVEZ has color 0x00000000, expected 0x000000ff
=== debiant2 (32 bit Japanese:Japan report) ===
ddraw: ddraw4.c:18177: Test failed: Expect window rect (0,0)-(1024,768), got (7,26)-(1017,761). ddraw4.c:18177: Test failed: Expect window rect (0,0)-(1024,768), got (1031,26)-(2041,728).
On Fri, 26 Feb 2021 at 00:20, Paul Gofman pgofman@codeweavers.com wrote:
dlls/ddraw/ddraw_private.h | 55 ++++++++++++ dlls/ddraw/device.c | 18 ++-- dlls/ddraw/surface.c | 167 +++++++++++++++++++++++++++++++------ dlls/ddraw/tests/ddraw1.c | 1 - dlls/ddraw/tests/ddraw2.c | 1 - dlls/ddraw/tests/ddraw4.c | 1 - dlls/ddraw/tests/ddraw7.c | 7 +- 7 files changed, 207 insertions(+), 43 deletions(-)
Broadly this seems fine. Perhaps this can be split a little though: - Allow creation of system memory textures/RTs/DSs by creating the second texture. At this point you could simply synchronise both surfaces before and after each draw. - Tests - CreateDevice() restrictions. - SetRenderTarget() restrictions. - Better location tracking. And this could possibly be split itself; e.g. ddraw_surface_get_any_texture() is essentially a further optimisation.
@@ -6951,6 +6951,12 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c device->hardware_device = IsEqualGUID(&IID_IDirect3DTnLHalDevice, guid) || IsEqualGUID(&IID_IDirect3DHALDevice, guid);
- if (device->hardware_device && !(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
- {
WARN("Surface %p is not in video memory.\n", target);
return D3DERR_SURFACENOTINVIDMEM;
- }
- if (outer_unknown) device->outer_unknown = outer_unknown; else
@@ -7038,12 +7044,6 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su return DDERR_OUTOFMEMORY; }
- if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
- {
WARN("Surface %p is not in video memory.\n", target);
return D3DERR_SURFACENOTINVIDMEM;
- }
Was there any particular reason to move this? It's fine if there's a reason, but on first sight it seems somewhat arbitrary.
@@ -121,7 +122,9 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, return hr; }
- if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, &surface_dc)))
- src_texture = ddraw_surface_get_default_texture(surface, DDRAW_SURFACE_READ);
- if (FAILED(hr = wined3d_texture_get_dc(src_texture, surface->sub_resource_idx, &surface_dc))) { ERR("Failed to get surface DC, hr %#x.\n", hr); return hr;
I don't think that's quite right in the "read" case.
+static void ddraw_surface_create_draw_texture(struct ddraw_surface *surface) +{
- DDSURFACEDESC2 *desc = &surface->surface_desc;
- struct wined3d_resource *draw_texture_resource;
- struct wined3d_resource_desc wined3d_desc;
- unsigned int i, layer_count, level_count;
- struct wined3d_texture *draw_texture;
- struct ddraw_surface *parent;
- unsigned int bind_flags;
- HRESULT hr;
- if (!(desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY))
return;
Shouldn't we also check whether we have a hardware device or not here?
@@ -6695,7 +6810,7 @@ struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddr if (surface->wined3d_rtv) return surface->wined3d_rtv;
- if (FAILED(hr = wined3d_rendertarget_view_create_from_sub_resource(surface->wined3d_texture,
- if (FAILED(hr = wined3d_rendertarget_view_create_from_sub_resource(ddraw_surface_get_draw_texture(surface, 0), surface->sub_resource_idx, surface, &ddraw_view_wined3d_parent_ops, &surface->wined3d_rtv))) { ERR("Failed to create rendertarget view, hr %#x.\n", hr);
The ddraw_surface_get_draw_texture() here seems a little awkward, since typically that function implies synchronising texture contents, but we don't care about that here. Not wrong though.
On 3/2/21 19:16, Henri Verbeet wrote:
@@ -6951,6 +6951,12 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c device->hardware_device = IsEqualGUID(&IID_IDirect3DTnLHalDevice, guid) || IsEqualGUID(&IID_IDirect3DHALDevice, guid);
- if (device->hardware_device && !(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
- {
WARN("Surface %p is not in video memory.\n", target);
return D3DERR_SURFACENOTINVIDMEM;
- }
- if (outer_unknown) device->outer_unknown = outer_unknown; else
@@ -7038,12 +7044,6 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su return DDERR_OUTOFMEMORY; }
- if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
- {
WARN("Surface %p is not in video memory.\n", target);
return D3DERR_SURFACENOTINVIDMEM;
- }
Was there any particular reason to move this? It's fine if there's a reason, but on first sight it seems somewhat arbitrary.
Checking the guids seemed a bit more reasonable to me in d3d_device_init() which fills all the fields of the struct d3d_device, including hardware_device, so I moved the check after the estimation of that field. Otherwise, I could check guids in d3d_device_create() and pass hardware_device BOOL to d3d_device_init. Should I change that?
@@ -121,7 +122,9 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, return hr; }
- if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, &surface_dc)))
- src_texture = ddraw_surface_get_default_texture(surface, DDRAW_SURFACE_READ);
+the
- if (FAILED(hr = wined3d_texture_get_dc(src_texture, surface->sub_resource_idx, &surface_dc))) { ERR("Failed to get surface DC, hr %#x.\n", hr); return hr;
I don't think that's quite right in the "read" case.
Yes, I will adjust the flags to ddraw_surface_get_default_texture().
+static void ddraw_surface_create_draw_texture(struct ddraw_surface *surface) +{
- DDSURFACEDESC2 *desc = &surface->surface_desc;
- struct wined3d_resource *draw_texture_resource;
- struct wined3d_resource_desc wined3d_desc;
- unsigned int i, layer_count, level_count;
- struct wined3d_texture *draw_texture;
- struct ddraw_surface *parent;
- unsigned int bind_flags;
- HRESULT hr;
- if (!(desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY))
return;
Shouldn't we also check whether we have a hardware device or not here?
Do you mean checking if we have a hardware renderer at all and skip the attempt to create draw_texture if we don't? But wouldn't it be easier to just let it fail without adding an extra check?
@@ -6695,7 +6810,7 @@ struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddr if (surface->wined3d_rtv) return surface->wined3d_rtv;
- if (FAILED(hr = wined3d_rendertarget_view_create_from_sub_resource(surface->wined3d_texture,
- if (FAILED(hr = wined3d_rendertarget_view_create_from_sub_resource(ddraw_surface_get_draw_texture(surface, 0), surface->sub_resource_idx, surface, &ddraw_view_wined3d_parent_ops, &surface->wined3d_rtv))) { ERR("Failed to create rendertarget view, hr %#x.\n", hr);
The ddraw_surface_get_draw_texture() here seems a little awkward, since typically that function implies synchronising texture contents, but we don't care about that here. Not wrong though.
But there are flags which are 0. Do you think it is cleaner to just select the texture with '?' in this case?
On Tue, 2 Mar 2021 at 18:03, Paul Gofman pgofman@codeweavers.com wrote:
On 3/2/21 19:16, Henri Verbeet wrote:
@@ -6951,6 +6951,12 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c device->hardware_device = IsEqualGUID(&IID_IDirect3DTnLHalDevice, guid) || IsEqualGUID(&IID_IDirect3DHALDevice, guid);
- if (device->hardware_device && !(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
- {
WARN("Surface %p is not in video memory.\n", target);
return D3DERR_SURFACENOTINVIDMEM;
- }
- if (outer_unknown) device->outer_unknown = outer_unknown; else
@@ -7038,12 +7044,6 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su return DDERR_OUTOFMEMORY; }
- if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
- {
WARN("Surface %p is not in video memory.\n", target);
return D3DERR_SURFACENOTINVIDMEM;
- }
Was there any particular reason to move this? It's fine if there's a reason, but on first sight it seems somewhat arbitrary.
Checking the guids seemed a bit more reasonable to me in d3d_device_init() which fills all the fields of the struct d3d_device, including hardware_device, so I moved the check after the estimation of that field. Otherwise, I could check guids in d3d_device_create() and pass hardware_device BOOL to d3d_device_init. Should I change that?
Oh, I see, we don't have device->hardware_device yet in d3d_device_create(). That's fine, no need to change it.
+static void ddraw_surface_create_draw_texture(struct ddraw_surface *surface) +{
- DDSURFACEDESC2 *desc = &surface->surface_desc;
- struct wined3d_resource *draw_texture_resource;
- struct wined3d_resource_desc wined3d_desc;
- unsigned int i, layer_count, level_count;
- struct wined3d_texture *draw_texture;
- struct ddraw_surface *parent;
- unsigned int bind_flags;
- HRESULT hr;
- if (!(desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY))
return;
Shouldn't we also check whether we have a hardware device or not here?
Do you mean checking if we have a hardware renderer at all and skip the attempt to create draw_texture if we don't? But wouldn't it be easier to just let it fail without adding an extra check?
No, the other way around, there's no need to create the extra texture if we do have a hardware device. Granted, that only makes a difference if applications create system memory surfaces with the relevant caps on a hardware device, but well, ddraw applications.
@@ -6695,7 +6810,7 @@ struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddr if (surface->wined3d_rtv) return surface->wined3d_rtv;
- if (FAILED(hr = wined3d_rendertarget_view_create_from_sub_resource(surface->wined3d_texture,
- if (FAILED(hr = wined3d_rendertarget_view_create_from_sub_resource(ddraw_surface_get_draw_texture(surface, 0), surface->sub_resource_idx, surface, &ddraw_view_wined3d_parent_ops, &surface->wined3d_rtv))) { ERR("Failed to create rendertarget view, hr %#x.\n", hr);
The ddraw_surface_get_draw_texture() here seems a little awkward, since typically that function implies synchronising texture contents, but we don't care about that here. Not wrong though.
But there are flags which are 0. Do you think it is cleaner to just select the texture with '?' in this case?
Perhaps, I haven't quite made up my mind yet. My first instinct would be to write
if (surface->draw_texture) wined3d_texture = surface->draw_texture; else wined3d_texture = surface->wined3d_texture;
but there's something to be said for always going through ddraw_surface_get_draw_texture() too.
On 3/2/21 20:30, Henri Verbeet wrote:
On Tue, 2 Mar 2021 at 18:03, Paul Gofman pgofman@codeweavers.com wrote:
On 3/2/21 19:16, Henri Verbeet wrote:
@@ -6951,6 +6951,12 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c device->hardware_device = IsEqualGUID(&IID_IDirect3DTnLHalDevice, guid) || IsEqualGUID(&IID_IDirect3DHALDevice, guid);
- if (device->hardware_device && !(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
- {
WARN("Surface %p is not in video memory.\n", target);
return D3DERR_SURFACENOTINVIDMEM;
- }
- if (outer_unknown) device->outer_unknown = outer_unknown; else
@@ -7038,12 +7044,6 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su return DDERR_OUTOFMEMORY; }
- if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
- {
WARN("Surface %p is not in video memory.\n", target);
return D3DERR_SURFACENOTINVIDMEM;
- }
Was there any particular reason to move this? It's fine if there's a reason, but on first sight it seems somewhat arbitrary.
Checking the guids seemed a bit more reasonable to me in d3d_device_init() which fills all the fields of the struct d3d_device, including hardware_device, so I moved the check after the estimation of that field. Otherwise, I could check guids in d3d_device_create() and pass hardware_device BOOL to d3d_device_init. Should I change that?
Oh, I see, we don't have device->hardware_device yet in d3d_device_create(). That's fine, no need to change it.
+static void ddraw_surface_create_draw_texture(struct ddraw_surface *surface) +{
- DDSURFACEDESC2 *desc = &surface->surface_desc;
- struct wined3d_resource *draw_texture_resource;
- struct wined3d_resource_desc wined3d_desc;
- unsigned int i, layer_count, level_count;
- struct wined3d_texture *draw_texture;
- struct ddraw_surface *parent;
- unsigned int bind_flags;
- HRESULT hr;
- if (!(desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY))
return;
Shouldn't we also check whether we have a hardware device or not here?
Do you mean checking if we have a hardware renderer at all and skip the attempt to create draw_texture if we don't? But wouldn't it be easier to just let it fail without adding an extra check?
No, the other way around, there's no need to create the extra texture if we do have a hardware device. Granted, that only makes a difference if applications create system memory surfaces with the relevant caps on a hardware device, but well, ddraw applications.
But the application device might not exist yet at the moment it creates the surface, so it is not clear yet if it will be software or hardware device. Then, if the application will create the sysmem render target and will try to attach it to hardware device, it will fail anyway. Then, while we currently support just one ddraw device as I understand there is no such limitation on Windows and looks a bit undesirable to me to depend on the present limitation. Or am I missing something?
On Tue, 2 Mar 2021 at 18:39, Paul Gofman pgofman@codeweavers.com wrote:
On 3/2/21 20:30, Henri Verbeet wrote:
On Tue, 2 Mar 2021 at 18:03, Paul Gofman pgofman@codeweavers.com wrote:
On 3/2/21 19:16, Henri Verbeet wrote:
Shouldn't we also check whether we have a hardware device or not here?
Do you mean checking if we have a hardware renderer at all and skip the attempt to create draw_texture if we don't? But wouldn't it be easier to just let it fail without adding an extra check?
No, the other way around, there's no need to create the extra texture if we do have a hardware device. Granted, that only makes a difference if applications create system memory surfaces with the relevant caps on a hardware device, but well, ddraw applications.
But the application device might not exist yet at the moment it creates the surface, so it is not clear yet if it will be software or hardware device. Then, if the application will create the sysmem render target and will try to attach it to hardware device, it will fail anyway. Then, while we currently support just one ddraw device as I understand there is no such limitation on Windows and looks a bit undesirable to me to depend on the present limitation. Or am I missing something?
No, you're right, that makes sense.
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ddraw/ddraw_private.h | 2 ++ dlls/ddraw/device.c | 58 +++++++++++++++++++++++++++++++++++--- dlls/ddraw/executebuffer.c | 3 ++ 3 files changed, 59 insertions(+), 4 deletions(-)
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index c6fb8d5f3a3..0c65b9940ba 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -708,6 +708,8 @@ static inline struct wined3d_texture *ddraw_surface_get_any_texture(struct ddraw return ddraw_surface_get_draw_texture(surface, flags); }
+void d3d_device_sync_surfaces(struct d3d_device *device) DECLSPEC_HIDDEN; + /* Used for generic dumping */ struct flag_info { diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index ea81972064e..00ee9bbbfa4 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -3427,6 +3427,47 @@ static HRESULT d3d_device_prepare_vertex_buffer(struct d3d_device *device, UINT return D3D_OK; }
+static void d3d_device_sync_rendertarget(struct d3d_device *device) +{ + struct wined3d_rendertarget_view *rtv; + + if (device->hardware_device) + return; + + if ((rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) + ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(rtv), DDRAW_SURFACE_RW); + + if ((rtv = wined3d_device_get_depth_stencil_view(device->wined3d_device))) + ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(rtv), DDRAW_SURFACE_RW); +} + +void d3d_device_sync_surfaces(struct d3d_device *device) +{ + const struct wined3d_stateblock_state *state = device->stateblock_state; + struct ddraw_surface *surface; + unsigned int i, j; + + if (device->hardware_device) + return; + + d3d_device_sync_rendertarget(device); + + for (i = 0; i < ARRAY_SIZE(state->textures); ++i) + { + if (!state->textures[i]) + continue; + + j = 0; + while ((surface = wined3d_texture_get_sub_resource_parent(state->textures[i], j))) + { + if (!surface->draw_texture) + break; + ddraw_surface_get_draw_texture(surface, DDRAW_SURFACE_READ); + ++j; + } + } +} + static HRESULT d3d_device7_DrawPrimitive(IDirect3DDevice7 *iface, D3DPRIMITIVETYPE primitive_type, DWORD fvf, void *vertices, DWORD vertex_count, DWORD flags) @@ -3481,6 +3522,7 @@ static HRESULT d3d_device7_DrawPrimitive(IDirect3DDevice7 *iface, wined3d_stateblock_set_vertex_declaration(device->state, ddraw_find_decl(device->ddraw, fvf)); wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0); wined3d_device_apply_stateblock(device->wined3d_device, device->state); + d3d_device_sync_surfaces(device); hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vertex_count);
done: @@ -3693,6 +3735,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7 *iface, wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0); wined3d_stateblock_set_base_vertex_index(device->state, vb_pos / stride); wined3d_device_apply_stateblock(device->wined3d_device, device->state); + d3d_device_sync_surfaces(device); hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(*indices), index_count);
done: @@ -4019,6 +4062,7 @@ static HRESULT d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, D3DPRIM
wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0); wined3d_device_apply_stateblock(device->wined3d_device, device->state); + d3d_device_sync_surfaces(device); hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / dst_stride, vertex_count);
done: @@ -4155,6 +4199,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, wined3d_stateblock_set_vertex_declaration(device->state, ddraw_find_decl(device->ddraw, fvf)); wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0); wined3d_device_apply_stateblock(device->wined3d_device, device->state); + d3d_device_sync_surfaces(device); hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), index_count);
done: @@ -4277,6 +4322,7 @@ static HRESULT d3d_device7_DrawPrimitiveVB(IDirect3DDevice7 *iface, D3DPRIMITIVE /* Now draw the primitives */ wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0); wined3d_device_apply_stateblock(device->wined3d_device, device->state); + d3d_device_sync_surfaces(device); hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, vertex_count);
wined3d_mutex_unlock(); @@ -4431,6 +4477,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
wined3d_device_set_primitive_type(device->wined3d_device, wined3d_primitive_type_from_ddraw(primitive_type), 0); wined3d_device_apply_stateblock(device->wined3d_device, device->state); + d3d_device_sync_surfaces(device); hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / sizeof(WORD), index_count);
wined3d_mutex_unlock(); @@ -4778,7 +4825,7 @@ static HRESULT d3d_device7_SetTexture(IDirect3DDevice7 *iface, TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture);
if (surf && (surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE)) - wined3d_texture = surf->wined3d_texture; + wined3d_texture = ddraw_surface_get_draw_texture(surf, 0);
wined3d_mutex_lock(); wined3d_stateblock_set_texture(device->update_state, stage, wined3d_texture); @@ -5270,6 +5317,7 @@ static HRESULT d3d_device7_Clear(IDirect3DDevice7 *iface, DWORD count,
wined3d_mutex_lock(); wined3d_device_apply_stateblock(device->wined3d_device, device->state); + d3d_device_sync_rendertarget(device); hr = wined3d_device_clear(device->wined3d_device, count, (RECT *)rects, flags, &c, z, stencil); wined3d_mutex_unlock();
@@ -5732,7 +5780,7 @@ static HRESULT d3d_device7_PreLoad(IDirect3DDevice7 *iface, IDirectDrawSurface7 return DDERR_INVALIDPARAMS;
wined3d_mutex_lock(); - wined3d_resource_preload(wined3d_texture_get_resource(surface->wined3d_texture)); + wined3d_resource_preload(wined3d_texture_get_resource(ddraw_surface_get_draw_texture(surface, 0))); wined3d_mutex_unlock();
return D3D_OK; @@ -6122,8 +6170,10 @@ static void copy_mipmap_chain(struct d3d_device *device, struct ddraw_surface *d UINT src_h = src_rect.bottom - src_rect.top; RECT dst_rect = {point.x, point.y, point.x + src_w, point.y + src_h};
- if (FAILED(hr = wined3d_texture_blt(dst_level->wined3d_texture, dst_level->sub_resource_idx, &dst_rect, - src_level->wined3d_texture, src_level->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT))) + if (FAILED(hr = wined3d_texture_blt(ddraw_surface_get_any_texture(dst_level, DDRAW_SURFACE_RW), + dst_level->sub_resource_idx, &dst_rect, + ddraw_surface_get_any_texture(src_level, DDRAW_SURFACE_READ), + src_level->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT))) ERR("Blit failed, hr %#x.\n", hr);
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index e0a9445bf71..d87878883c7 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -81,6 +81,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d ddraw_find_decl(device->ddraw, D3DFVF_TLVERTEX));
wined3d_device_apply_stateblock(device->wined3d_device, device->state); + d3d_device_sync_surfaces(device); for (i = 0; i < count; ++i) wined3d_device_draw_primitive(device->wined3d_device, p[i].wFirst, p[i].wCount);
@@ -189,6 +190,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d ddraw_find_decl(device->ddraw, D3DFVF_TLVERTEX)); wined3d_stateblock_set_index_buffer(device->state, buffer->index_buffer, WINED3DFMT_R16_UINT); wined3d_device_apply_stateblock(device->wined3d_device, device->state); + d3d_device_sync_surfaces(device); wined3d_device_draw_indexed_primitive(device->wined3d_device, index_pos, index_count);
buffer->index_pos = index_pos + index_count; @@ -310,6 +312,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d ddraw_find_decl(device->ddraw, op == D3DPROCESSVERTICES_TRANSFORMLIGHT ? D3DFVF_VERTEX : D3DFVF_LVERTEX)); wined3d_device_apply_stateblock(device->wined3d_device, device->state); + d3d_device_sync_surfaces(device); wined3d_device_process_vertices(device->wined3d_device, ci->wStart, ci->wDest, ci->dwCount, buffer->dst_vertex_buffer, NULL, 0, D3DFVF_TLVERTEX); break;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=86129
Your paranoid android.
=== debiant2 (32 bit report) ===
ddraw: ddraw2.c:15119: Test failed: Expect window rect (0,0)-(1024,768), got (1031,26)-(2041,728).
=== debiant2 (32 bit Chinese:China report) ===
ddraw: ddraw1.c:14218: Test failed: Expect window rect (0,0)-(1024,768), got (7,26)-(1031,794). ddraw1.c:14236: Test failed: Expect window rect (0,0)-(1024,768), got (1024,-8)-(2048,760). ddraw1.c:14243: Test failed: Expect window rect (0,0)-(1024,768), got (1024,-8)-(2048,760). ddraw4.c:18177: Test failed: Expect window rect (0,0)-(1024,768), got (-7,-26)-(1003,709).
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ddraw/tests/ddraw2.c | 98 ++++++++++++++++++----------- dlls/ddraw/tests/ddraw4.c | 106 +++++++++++++++++++------------ dlls/ddraw/tests/ddraw7.c | 129 +++++++++++++++++++++++++------------- 3 files changed, 211 insertions(+), 122 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index b882589f2ad..a04b1a2967f 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -360,6 +360,29 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface *surface, UINT x, UINT y) return color; }
+static void fill_surface(IDirectDrawSurface *surface, D3DCOLOR color) +{ + DDSURFACEDESC surface_desc = {sizeof(surface_desc)}; + HRESULT hr; + unsigned int x, y; + DWORD *ptr; + + hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + for (y = 0; y < surface_desc.dwHeight; ++y) + { + ptr = (DWORD *)((BYTE *)surface_desc.lpSurface + y * U1(surface_desc).lPitch); + for (x = 0; x < surface_desc.dwWidth; ++x) + { + ptr[x] = color; + } + } + + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); +} + static void check_rect(IDirectDrawSurface *surface, RECT r, const char *message) { LONG x_coords[2][2] = @@ -461,6 +484,8 @@ static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWOR surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + if (is_software_device_type(device_guid)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; surface_desc.dwWidth = 640; surface_desc.dwHeight = 480;
@@ -496,6 +521,8 @@ static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWOR surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT; surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; + if (is_software_device_type(device_guid)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; U2(surface_desc).dwZBufferBitDepth = z_depths[i]; surface_desc.dwWidth = 640; surface_desc.dwHeight = 480; @@ -1263,7 +1290,7 @@ static void test_coop_level_threaded(void) IDirectDraw2_Release(ddraw); }
-static void test_depth_blit(void) +static void test_depth_blit(const GUID *device_guid) { static D3DLVERTEX quad1[] = { @@ -1283,6 +1310,7 @@ static void test_depth_blit(void)
IDirect3DDevice2 *device; IDirectDrawSurface *ds1, *ds2, *ds3, *rt; + BOOL depth_fill_broken = FALSE; IDirect3DViewport2 *viewport; RECT src_rect, dst_rect; unsigned int i, j; @@ -1297,7 +1325,7 @@ static void test_depth_blit(void) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw2_Release(ddraw); @@ -1312,8 +1340,10 @@ static void test_depth_blit(void) memset(&ddsd_existing, 0, sizeof(ddsd_existing)); ddsd_existing.dwSize = sizeof(ddsd_existing); hr = IDirectDrawSurface_GetSurfaceDesc(ds1, &ddsd_existing); - ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); ddsd_new.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + if (is_software_device_type(device_guid)) + ddsd_new.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; ddsd_new.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; ddsd_new.dwWidth = ddsd_existing.dwWidth; ddsd_new.dwHeight = ddsd_existing.dwHeight; @@ -1393,28 +1423,44 @@ static void test_depth_blit(void) fx.dwSize = sizeof(fx); U5(fx).dwFillDepth = 0; hr = IDirectDrawSurface_Blt(ds2, NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to clear the source z buffer, hr %#x.\n", hr); + ok(hr == DD_OK || broken(is_software_device_type(device_guid) + && hr == 0x8876086c /* D3DERR_INVALIDCALL */), "Got unexpected hr %#x.\n", hr); + if (hr != DD_OK) + depth_fill_broken = TRUE;
/* This clears the Z buffer with 1.0 */ hr = IDirect3DViewport2_Clear(viewport, 1, &d3drect, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET); - ok(SUCCEEDED(hr), "Failed to clear the color and z buffers, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice2_GetRenderTarget(device, &rt); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + color = get_surface_color(rt, 80, 60); + /* For some reason clears and colour fill blits randomly fail with software render target. */ + ok(color == 0x00ff0000 || broken(is_software_device_type(device_guid) && !color), + "Got unexpected colour %#x.\n", color); + if (!color) + { + fill_surface(rt, 0xffff0000); + + color = get_surface_color(rt, 80, 60); + ok(color == 0x00ff0000, "Got unexpected colour %#x.\n", color); + }
SetRect(&dst_rect, 0, 0, 320, 240); hr = IDirectDrawSurface_Blt(ds1, &dst_rect, ds2, NULL, DDBLT_WAIT, NULL); - ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); IDirectDrawSurface_Release(ds3); IDirectDrawSurface_Release(ds2); IDirectDrawSurface_Release(ds1);
hr = IDirect3DDevice2_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to start a scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_LVERTEX, quad1, 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice2_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end a scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
- hr = IDirect3DDevice2_GetRenderTarget(device, &rt); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) @@ -1422,7 +1468,7 @@ static void test_depth_blit(void) unsigned int x = 80 * ((2 * j) + 1); unsigned int y = 60 * ((2 * i) + 1); color = get_surface_color(rt, x, y); - ok(compare_color(color, expected_colors[i][j], 1), + ok(compare_color(color, expected_colors[i][j], 1) || broken(depth_fill_broken && color == 0x0000ff00), "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color); } } @@ -5040,7 +5086,8 @@ static void test_rt_caps(const GUID *device_guid)
todo_wine_if(test_data[i].caps_out[0] == ~0u && surface_desc.ddsCaps.dwCaps != expected_caps) ok(surface_desc.ddsCaps.dwCaps == expected_caps - || surface_desc.ddsCaps.dwCaps == test_data[i].caps_out[0], + || surface_desc.ddsCaps.dwCaps == test_data[i].caps_out[0] + || test_data[i].caps_out[0] == ~0u, "Got unexpected caps %#x, test %u, software_device %u.\n", surface_desc.ddsCaps.dwCaps, i, software_device); } @@ -5515,29 +5562,6 @@ static void test_surface_discard(void) DestroyWindow(window); }
-static void fill_surface(IDirectDrawSurface *surface, D3DCOLOR color) -{ - DDSURFACEDESC surface_desc = {sizeof(surface_desc)}; - HRESULT hr; - unsigned int x, y; - DWORD *ptr; - - hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - - for (y = 0; y < surface_desc.dwHeight; ++y) - { - ptr = (DWORD *)((BYTE *)surface_desc.lpSurface + y * U1(surface_desc).lPitch); - for (x = 0; x < surface_desc.dwWidth; ++x) - { - ptr[x] = color; - } - } - - hr = IDirectDrawSurface_Unlock(surface, NULL); - ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); -} - static void test_flip(void) { const DWORD placement = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY; @@ -15315,7 +15339,7 @@ START_TEST(ddraw2) test_coop_level_d3d_state(); test_surface_interface_mismatch(); test_coop_level_threaded(); - test_depth_blit(); + run_for_each_device_type(test_depth_blit); test_texture_load_ckey(); test_viewport_object(); test_zenable(); diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 42936fd7c74..569af353397 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -361,6 +361,29 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface4 *surface, UINT x, UINT y) return color; }
+static void fill_surface(IDirectDrawSurface4 *surface, D3DCOLOR color) +{ + DDSURFACEDESC2 surface_desc = {sizeof(surface_desc)}; + HRESULT hr; + unsigned int x, y; + DWORD *ptr; + + hr = IDirectDrawSurface4_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + for (y = 0; y < surface_desc.dwHeight; ++y) + { + ptr = (DWORD *)((BYTE *)surface_desc.lpSurface + y * U1(surface_desc).lPitch); + for (x = 0; x < surface_desc.dwWidth; ++x) + { + ptr[x] = color; + } + } + + hr = IDirectDrawSurface4_Unlock(surface, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); +} + static void check_rect(IDirectDrawSurface4 *surface, RECT r, const char *message) { LONG x_coords[2][2] = @@ -427,7 +450,7 @@ static IDirectDraw4 *create_ddraw(void) return ddraw4; }
-static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level) +static IDirect3DDevice3 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid) { IDirectDrawSurface4 *surface, *ds; IDirect3DDevice3 *device = NULL; @@ -447,6 +470,8 @@ static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level) surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + if (is_software_device_type(device_guid)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; surface_desc.dwWidth = 640; surface_desc.dwHeight = 480;
@@ -475,7 +500,7 @@ static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level) }
memset(&z_fmt, 0, sizeof(z_fmt)); - hr = IDirect3D3_EnumZBufferFormats(d3d3, &IID_IDirect3DHALDevice, enum_z_fmt, &z_fmt); + hr = IDirect3D3_EnumZBufferFormats(d3d3, device_guid, enum_z_fmt, &z_fmt); if (FAILED(hr) || !z_fmt.dwSize) { IDirect3D3_Release(d3d3); @@ -487,6 +512,9 @@ static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level) surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT; surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; + if (is_software_device_type(device_guid)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + U4(surface_desc).ddpfPixelFormat = z_fmt; surface_desc.dwWidth = 640; surface_desc.dwHeight = 480; @@ -509,7 +537,7 @@ static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level) return NULL; }
- hr = IDirect3D3_CreateDevice(d3d3, &IID_IDirect3DHALDevice, surface, &device, NULL); + hr = IDirect3D3_CreateDevice(d3d3, device_guid, surface, &device, NULL); IDirect3D3_Release(d3d3); IDirectDrawSurface4_Release(surface); if (FAILED(hr)) @@ -518,6 +546,11 @@ static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level) return device; }
+static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level) +{ + return create_device_ex(window, coop_level, &IID_IDirect3DHALDevice); +} + static IDirect3DViewport3 *create_viewport(IDirect3DDevice3 *device, UINT x, UINT y, UINT w, UINT h) { IDirect3DViewport3 *viewport; @@ -1429,7 +1462,7 @@ static void test_coop_level_threaded(void) IDirectDraw4_Release(ddraw); }
-static void test_depth_blit(void) +static void test_depth_blit(const GUID *device_guid) { static struct { @@ -1466,7 +1499,7 @@ static void test_depth_blit(void) D3DRECT d3drect;
window = create_window(); - if (!(device = create_device(window, DDSCL_NORMAL))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -1474,9 +1507,9 @@ static void test_depth_blit(void) }
hr = IDirect3DDevice3_GetDirect3D(device, &d3d); - ok(SUCCEEDED(hr), "Failed to get Direct3D3 interface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3D3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw); - ok(SUCCEEDED(hr), "Failed to get DirectDraw4 interface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); IDirect3D3_Release(d3d);
ds1 = get_depth_stencil(device); @@ -1486,9 +1519,11 @@ static void test_depth_blit(void) memset(&ddsd_existing, 0, sizeof(ddsd_existing)); ddsd_existing.dwSize = sizeof(ddsd_existing); hr = IDirectDrawSurface4_GetSurfaceDesc(ds1, &ddsd_existing); - ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); ddsd_new.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ddsd_new.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; + if (is_software_device_type(device_guid)) + ddsd_new.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; ddsd_new.dwWidth = ddsd_existing.dwWidth; ddsd_new.dwHeight = ddsd_existing.dwHeight; U4(ddsd_new).ddpfPixelFormat = U4(ddsd_existing).ddpfPixelFormat; @@ -1565,27 +1600,41 @@ static void test_depth_blit(void) memset(&fx, 0, sizeof(fx)); fx.dwSize = sizeof(fx); hr = IDirectDrawSurface4_Blt(ds2, NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to clear the source z buffer, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice3_GetRenderTarget(device, &rt); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport3_Clear2(viewport, 1, &d3drect, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0); - ok(SUCCEEDED(hr), "Failed to clear the color and z buffers, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + color = get_surface_color(rt, 80, 60); + /* For some reason clears and colour fill blits randomly fail with software render target. */ + ok(color == 0x00ff0000 || broken(is_software_device_type(device_guid) && !color), + "Got unexpected colour %#x.\n", color); + if (!color) + { + fill_surface(rt, 0xffff0000); + + color = get_surface_color(rt, 80, 60); + ok(color == 0x00ff0000, "Got unexpected colour %#x.\n", color); + } + SetRect(&dst_rect, 0, 0, 320, 240); hr = IDirectDrawSurface4_Blt(ds1, &dst_rect, ds2, NULL, DDBLT_WAIT, NULL); - ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); IDirectDrawSurface4_Release(ds3); IDirectDrawSurface4_Release(ds2); IDirectDrawSurface4_Release(ds1);
hr = IDirect3DDevice3_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to start a scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end a scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
- hr = IDirect3DDevice3_GetRenderTarget(device, &rt); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) @@ -7199,29 +7248,6 @@ static void test_surface_discard(void) DestroyWindow(window); }
-static void fill_surface(IDirectDrawSurface4 *surface, D3DCOLOR color) -{ - DDSURFACEDESC2 surface_desc = {sizeof(surface_desc)}; - HRESULT hr; - unsigned int x, y; - DWORD *ptr; - - hr = IDirectDrawSurface4_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - - for (y = 0; y < surface_desc.dwHeight; ++y) - { - ptr = (DWORD *)((BYTE *)surface_desc.lpSurface + y * U1(surface_desc).lPitch); - for (x = 0; x < surface_desc.dwWidth; ++x) - { - ptr[x] = color; - } - } - - hr = IDirectDrawSurface4_Unlock(surface, NULL); - ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); -} - static void test_flip(void) { const DWORD placement = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY; @@ -18374,7 +18400,7 @@ START_TEST(ddraw4) test_coop_level_d3d_state(); test_surface_interface_mismatch(); test_coop_level_threaded(); - test_depth_blit(); + run_for_each_device_type(test_depth_blit); test_texture_load_ckey(); test_viewport_object(); test_zenable(); diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 7e83d26d6db..639b3ca6252 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -388,6 +388,29 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface7 *surface, UINT x, UINT y) return color; }
+static void fill_surface(IDirectDrawSurface7 *surface, D3DCOLOR color) +{ + DDSURFACEDESC2 surface_desc = {sizeof(surface_desc)}; + HRESULT hr; + unsigned int x, y; + DWORD *ptr; + + hr = IDirectDrawSurface7_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + for (y = 0; y < surface_desc.dwHeight; ++y) + { + ptr = (DWORD *)((BYTE *)surface_desc.lpSurface + y * U1(surface_desc).lPitch); + for (x = 0; x < surface_desc.dwWidth; ++x) + { + ptr[x] = color; + } + } + + hr = IDirectDrawSurface7_Unlock(surface, NULL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); +} + #define check_rect(a, b, c) check_rect_(__LINE__, a, b, c) static void check_rect_(unsigned int line, IDirectDrawSurface7 *surface, RECT r, const char *message) { @@ -459,7 +482,7 @@ static HRESULT WINAPI enum_devtype_cb(char *desc_str, char *name, D3DDEVICEDESC7 return DDENUMRET_OK; }
-static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) +static IDirect3DDevice7 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid) { IDirectDrawSurface7 *surface, *ds; IDirect3DDevice7 *device = NULL; @@ -468,8 +491,6 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) IDirectDraw7 *ddraw; IDirect3D7 *d3d7; HRESULT hr; - BOOL hal_ok = FALSE; - const GUID *devtype = &IID_IDirect3DHALDevice;
if (!(ddraw = create_ddraw())) return NULL; @@ -481,6 +502,8 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + if (is_software_device_type(device_guid)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; surface_desc.dwWidth = 640; surface_desc.dwHeight = 480;
@@ -508,12 +531,8 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) return NULL; }
- hr = IDirect3D7_EnumDevices(d3d7, enum_devtype_cb, &hal_ok); - ok(SUCCEEDED(hr), "Failed to enumerate devices, hr %#x.\n", hr); - if (hal_ok) devtype = &IID_IDirect3DTnLHalDevice; - memset(&z_fmt, 0, sizeof(z_fmt)); - hr = IDirect3D7_EnumZBufferFormats(d3d7, devtype, enum_z_fmt, &z_fmt); + hr = IDirect3D7_EnumZBufferFormats(d3d7, device_guid, enum_z_fmt, &z_fmt); if (FAILED(hr) || !z_fmt.dwSize) { IDirect3D7_Release(d3d7); @@ -525,6 +544,8 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT; surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; + if (is_software_device_type(device_guid)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; U4(surface_desc).ddpfPixelFormat = z_fmt; surface_desc.dwWidth = 640; surface_desc.dwHeight = 480; @@ -547,7 +568,7 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) return NULL; }
- hr = IDirect3D7_CreateDevice(d3d7, devtype, surface, &device); + hr = IDirect3D7_CreateDevice(d3d7, device_guid, surface, &device); IDirect3D7_Release(d3d7); IDirectDrawSurface7_Release(surface); if (FAILED(hr)) @@ -556,6 +577,31 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) return device; }
+static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) +{ + const GUID *device_guid = &IID_IDirect3DHALDevice; + IDirectDraw7 *ddraw; + BOOL hal_ok = FALSE; + IDirect3D7 *d3d7; + HRESULT hr; + + if (!(ddraw = create_ddraw())) + return NULL; + hr = IDirectDraw7_QueryInterface(ddraw, &IID_IDirect3D7, (void **)&d3d7); + IDirectDraw7_Release(ddraw); + if (FAILED(hr)) + return NULL; + + hr = IDirect3D7_EnumDevices(d3d7, enum_devtype_cb, &hal_ok); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + if (hal_ok) + device_guid = &IID_IDirect3DTnLHalDevice; + + IDirect3D7_Release(d3d7); + + return create_device_ex(window, coop_level, device_guid); +} + struct message { UINT message; @@ -1391,7 +1437,7 @@ static void test_coop_level_threaded(void) IDirectDraw7_Release(ddraw); }
-static void test_depth_blit(void) +static void test_depth_blit(const GUID *device_guid) { IDirect3DDevice7 *device; static struct @@ -1426,7 +1472,7 @@ static void test_depth_blit(void) HWND window;
window = create_window(); - if (!(device = create_device(window, DDSCL_NORMAL))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -1446,9 +1492,11 @@ static void test_depth_blit(void) memset(&ddsd_existing, 0, sizeof(ddsd_existing)); ddsd_existing.dwSize = sizeof(ddsd_existing); hr = IDirectDrawSurface7_GetSurfaceDesc(ds1, &ddsd_existing); - ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); ddsd_new.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ddsd_new.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; + if (is_software_device_type(device_guid)) + ddsd_new.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; ddsd_new.dwWidth = ddsd_existing.dwWidth; ddsd_new.dwHeight = ddsd_existing.dwHeight; U4(ddsd_new).ddpfPixelFormat = U4(ddsd_existing).ddpfPixelFormat; @@ -1521,27 +1569,41 @@ static void test_depth_blit(void) memset(&fx, 0, sizeof(fx)); fx.dwSize = sizeof(fx); hr = IDirectDrawSurface7_Blt(ds2, NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to clear the source z buffer, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0); - ok(SUCCEEDED(hr), "Failed to clear the color and z buffers, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice7_GetRenderTarget(device, &rt); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + color = get_surface_color(rt, 80, 60); + + /* For some reason clears and colour fill blits randomly fail with software render target. */ + ok(color == 0x00ff0000 || broken(is_software_device_type(device_guid) && !color), + "Got unexpected colour %#x.\n", color); + if (!color) + { + fill_surface(rt, 0xffff0000); + + color = get_surface_color(rt, 80, 60); + ok(color == 0x00ff0000, "Got unexpected colour %#x.\n", color); + } + SetRect(&dst_rect, 0, 0, 320, 240); hr = IDirectDrawSurface7_Blt(ds1, &dst_rect, ds2, NULL, DDBLT_WAIT, NULL); - ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); IDirectDrawSurface7_Release(ds3); IDirectDrawSurface7_Release(ds2); IDirectDrawSurface7_Release(ds1);
hr = IDirect3DDevice7_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to start scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, quad1, 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice7_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
- hr = IDirect3DDevice7_GetRenderTarget(device, &rt); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) @@ -1550,7 +1612,7 @@ static void test_depth_blit(void) unsigned int y = 60 * ((2 * i) + 1); color = get_surface_color(rt, x, y); ok(compare_color(color, expected_colors[i][j], 1), - "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color); + "Expected color 0x%08x at %u,%u, got 0x%08x, software device %#x.\n", expected_colors[i][j], x, y, color, is_software_device_type(device_guid)); } }
@@ -7000,29 +7062,6 @@ static void test_surface_discard(void) DestroyWindow(window); }
-static void fill_surface(IDirectDrawSurface7 *surface, D3DCOLOR color) -{ - DDSURFACEDESC2 surface_desc = {sizeof(surface_desc)}; - HRESULT hr; - unsigned int x, y; - DWORD *ptr; - - hr = IDirectDrawSurface7_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - - for (y = 0; y < surface_desc.dwHeight; ++y) - { - ptr = (DWORD *)((BYTE *)surface_desc.lpSurface + y * U1(surface_desc).lPitch); - for (x = 0; x < surface_desc.dwWidth; ++x) - { - ptr[x] = color; - } - } - - hr = IDirectDrawSurface7_Unlock(surface, NULL); - ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); -} - static void test_flip(void) { const DWORD placement = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY; @@ -18648,7 +18687,7 @@ START_TEST(ddraw7) test_coop_level_d3d_state(); test_surface_interface_mismatch(); test_coop_level_threaded(); - test_depth_blit(); + run_for_each_device_type(test_depth_blit); test_texture_load_ckey(); test_zenable(); test_ck_rgba();
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=86130
Your paranoid android.
=== debiant2 (32 bit report) ===
ddraw: ddraw1.c:14236: Test failed: Expect window rect (0,0)-(1024,768), got (0,-8)-(1024,760). ddraw1.c:14243: Test failed: Expect window rect (0,0)-(1024,768), got (0,-8)-(1024,760). ddraw1.c:14218: Test failed: Expect window rect (0,0)-(1024,768), got (7,26)-(1031,794). ddraw2.c:5088: Test succeeded inside todo block: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw2.c:5088: Test succeeded inside todo block: Got unexpected caps 0x10024000, test 17, software_device 1.
=== debiant2 (32 bit French report) ===
ddraw: ddraw2.c:5088: Test succeeded inside todo block: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw2.c:5088: Test succeeded inside todo block: Got unexpected caps 0x10024000, test 17, software_device 1. ddraw2.c:15143: Test failed: Expect window rect (0,0)-(1024,768), got (7,26)-(1031,794). ddraw2.c:15161: Test failed: Expect window rect (0,0)-(1024,768), got (0,-8)-(1024,760). ddraw2.c:15168: Test failed: Expect window rect (0,0)-(1024,768), got (0,-8)-(1024,760).
=== debiant2 (32 bit Japanese:Japan report) ===
ddraw: ddraw2.c:5088: Test succeeded inside todo block: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw2.c:5088: Test succeeded inside todo block: Got unexpected caps 0x10024000, test 17, software_device 1.
=== debiant2 (32 bit Chinese:China report) ===
ddraw: ddraw2.c:5088: Test succeeded inside todo block: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw2.c:5088: Test succeeded inside todo block: Got unexpected caps 0x10024000, test 17, software_device 1.
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ddraw/tests/ddraw1.c | 18 +++++++++--------- dlls/ddraw/tests/ddraw2.c | 36 +++++++++++++++++++++++++----------- dlls/ddraw/tests/ddraw4.c | 36 +++++++++++++++++++++++++----------- dlls/ddraw/tests/ddraw7.c | 34 ++++++++++++++++++++++++---------- 4 files changed, 83 insertions(+), 41 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index e75a9fac0a8..f0c51844e84 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -1610,7 +1610,7 @@ static void test_viewport_object(void) IDirectDraw_Release(ddraw); }
-static void test_zenable(void) +static void test_zenable(const GUID *device_guid) { static D3DRECT clear_rect = {{0}, {0}, {640}, {480}}; static D3DTLVERTEX tquad[] = @@ -1638,7 +1638,7 @@ static void test_zenable(void) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw_Release(ddraw); @@ -1669,20 +1669,20 @@ static void test_zenable(void) inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData; inst_length -= sizeof(tquad); hr = IDirect3DExecuteBuffer_Unlock(execute_buffer); - ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET); - ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); set_execute_data(execute_buffer, 4, sizeof(tquad), inst_length); hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED); - ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&rt); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) @@ -14380,7 +14380,7 @@ START_TEST(ddraw1) test_surface_interface_mismatch(); test_coop_level_threaded(); test_viewport_object(); - test_zenable(); + run_for_each_device_type(test_zenable); test_ck_rgba(); test_ck_default(); test_ck_complex(); diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index a04b1a2967f..56a44ce494a 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -1829,7 +1829,7 @@ static void test_viewport_object(void) IDirectDraw2_Release(ddraw); }
-static void test_zenable(void) +static void test_zenable(const GUID *device_guid) { static D3DRECT clear_rect = {{0}, {0}, {640}, {480}}; static D3DTLVERTEX tquad[] = @@ -1853,7 +1853,7 @@ static void test_zenable(void) window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw2_Release(ddraw); @@ -1865,22 +1865,36 @@ static void test_zenable(void) viewport = create_viewport(device, 0, 0, 640, 480); viewport_set_background(device, viewport, background); hr = IDirect3DDevice2_SetCurrentViewport(device, viewport); - ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); - ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET); - ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice2_GetRenderTarget(device, &rt); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + color = get_surface_color(rt, 80, 60); + /* For some reason clears and colour fill blits randomly fail with software render target. */ + ok(color == 0x00ff0000 || broken(is_software_device_type(device_guid) && !color), + "Got unexpected colour %#x.\n", color); + if (!color) + { + fill_surface(rt, 0xffff0000); + + color = get_surface_color(rt, 80, 60); + ok(color == 0x00ff0000, "Got unexpected colour %#x.\n", color); + } + hr = IDirect3DDevice2_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_TLVERTEX, tquad, 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice2_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
- hr = IDirect3DDevice2_GetRenderTarget(device, &rt); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) @@ -15342,7 +15356,7 @@ START_TEST(ddraw2) run_for_each_device_type(test_depth_blit); test_texture_load_ckey(); test_viewport_object(); - test_zenable(); + run_for_each_device_type(test_zenable); test_ck_rgba(); test_ck_default(); test_ck_complex(); diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 569af353397..23049134f4d 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -2071,7 +2071,7 @@ static void test_viewport_object(void) IDirectDraw4_Release(ddraw); }
-static void test_zenable(void) +static void test_zenable(const GUID *device_guid) { static D3DRECT clear_rect = {{0}, {0}, {640}, {480}}; static struct @@ -2096,7 +2096,7 @@ static void test_zenable(void) UINT i, j;
window = create_window(); - if (!(device = create_device(window, DDSCL_NORMAL))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -2105,22 +2105,36 @@ static void test_zenable(void)
viewport = create_viewport(device, 0, 0, 640, 480); hr = IDirect3DDevice3_SetCurrentViewport(device, viewport); - ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); - ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0); - ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice3_GetRenderTarget(device, &rt); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + color = get_surface_color(rt, 80, 60); + /* For some reason clears and colour fill blits randomly fail with software render target. */ + ok(color == 0x00ff0000 || broken(is_software_device_type(device_guid) && !color), + "Got unexpected colour %#x.\n", color); + if (!color) + { + fill_surface(rt, 0xffff0000); + + color = get_surface_color(rt, 80, 60); + ok(color == 0x00ff0000, "Got unexpected colour %#x.\n", color); + } + hr = IDirect3DDevice3_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, tquad, 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
- hr = IDirect3DDevice3_GetRenderTarget(device, &rt); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) @@ -18403,7 +18417,7 @@ START_TEST(ddraw4) run_for_each_device_type(test_depth_blit); test_texture_load_ckey(); test_viewport_object(); - test_zenable(); + run_for_each_device_type(test_zenable); test_ck_rgba(); test_ck_default(); test_ck_complex(); diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 639b3ca6252..2351a037f23 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -1708,7 +1708,7 @@ static void test_texture_load_ckey(void) DestroyWindow(window); }
-static void test_zenable(void) +static void test_zenable(const GUID *device_guid) { static struct { @@ -1731,7 +1731,7 @@ static void test_zenable(void) UINT i, j;
window = create_window(); - if (!(device = create_device(window, DDSCL_NORMAL))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -1739,19 +1739,33 @@ static void test_zenable(void) }
hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); - ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0); - ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice7_GetRenderTarget(device, &rt); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + color = get_surface_color(rt, 80, 60); + /* For some reason clears and colour fill blits randomly fail with software render target. */ + ok(color == 0x00ff0000 || broken(is_software_device_type(device_guid) && !color), + "Got unexpected colour %#x.\n", color); + if (!color) + { + fill_surface(rt, 0xffff0000); + + color = get_surface_color(rt, 80, 60); + ok(color == 0x00ff0000, "Got unexpected colour %#x.\n", color); + } + hr = IDirect3DDevice7_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, tquad, 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice7_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
- hr = IDirect3DDevice7_GetRenderTarget(device, &rt); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) @@ -18689,7 +18703,7 @@ START_TEST(ddraw7) test_coop_level_threaded(); run_for_each_device_type(test_depth_blit); test_texture_load_ckey(); - test_zenable(); + run_for_each_device_type(test_zenable); test_ck_rgba(); test_ck_default(); test_ck_complex();
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=86131
Your paranoid android.
=== debiant2 (32 bit report) ===
ddraw: ddraw2.c:5102: Test succeeded inside todo block: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw2.c:5102: Test succeeded inside todo block: Got unexpected caps 0x10024000, test 17, software_device 1.
=== debiant2 (32 bit French report) ===
ddraw: ddraw2.c:5102: Test succeeded inside todo block: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw2.c:5102: Test succeeded inside todo block: Got unexpected caps 0x10024000, test 17, software_device 1. ddraw2.c:15157: Test failed: Expect window rect (0,0)-(1024,768), got (7,26)-(1031,794). ddraw2.c:15175: Test failed: Expect window rect (0,0)-(1024,768), got (0,-8)-(1024,760). ddraw2.c:15182: Test failed: Expect window rect (0,0)-(1024,768), got (0,-8)-(1024,760).
=== debiant2 (32 bit Japanese:Japan report) ===
ddraw: ddraw2.c:5102: Test succeeded inside todo block: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw2.c:5102: Test succeeded inside todo block: Got unexpected caps 0x10024000, test 17, software_device 1.
=== debiant2 (32 bit Chinese:China report) ===
ddraw: ddraw2.c:5102: Test succeeded inside todo block: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw2.c:5102: Test succeeded inside todo block: Got unexpected caps 0x10024000, test 17, software_device 1.
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ddraw/tests/ddraw1.c | 110 +++++++++++++++++++++++--------------- dlls/ddraw/tests/ddraw2.c | 59 +++++++++++--------- dlls/ddraw/tests/ddraw4.c | 57 +++++++++++--------- dlls/ddraw/tests/ddraw7.c | 55 +++++++++++-------- 4 files changed, 164 insertions(+), 117 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index f0c51844e84..912ddab0be8 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -363,6 +363,29 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface *surface, UINT x, UINT y) return color; }
+static void fill_surface(IDirectDrawSurface *surface, D3DCOLOR color) +{ + DDSURFACEDESC surface_desc = {sizeof(surface_desc)}; + HRESULT hr; + unsigned int x, y; + DWORD *ptr; + + hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); + + for (y = 0; y < surface_desc.dwHeight; ++y) + { + ptr = (DWORD *)((BYTE *)surface_desc.lpSurface + y * U1(surface_desc).lPitch); + for (x = 0; x < surface_desc.dwWidth; ++x) + { + ptr[x] = color; + } + } + + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); +} + static void check_rect(IDirectDrawSurface *surface, RECT r, const char *message) { LONG x_coords[2][2] = @@ -630,6 +653,8 @@ static IDirect3DDevice *create_device_ex(IDirectDraw *ddraw, HWND window, DWORD surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + if (is_software_device_type(device_guid)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; surface_desc.dwWidth = 640; surface_desc.dwHeight = 480;
@@ -658,6 +683,8 @@ static IDirect3DDevice *create_device_ex(IDirectDraw *ddraw, HWND window, DWORD surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT; surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; + if (is_software_device_type(device_guid)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; U2(surface_desc).dwZBufferBitDepth = z_depths[i]; surface_desc.dwWidth = 640; surface_desc.dwHeight = 480; @@ -1704,7 +1731,7 @@ static void test_zenable(const GUID *device_guid) DestroyWindow(window); }
-static void test_ck_rgba(void) +static void test_ck_rgba(const GUID *device_guid) { static D3DRECT clear_rect = {{0}, {0}, {640}, {480}}; static D3DTLVERTEX tquad[] = @@ -1767,15 +1794,18 @@ static void test_ck_rgba(void) IDirectDrawSurface *rt; IDirectDraw *ddraw; D3DCOLOR color; + BYTE max_diff; HWND window; DDBLTFX fx; HRESULT hr; UINT i;
+ max_diff = is_software_device_type(device_guid) ? 2 : 1; + window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw_Release(ddraw); @@ -1791,6 +1821,8 @@ static void test_ck_rgba(void) surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT; surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + if (is_software_device_type(device_guid)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; surface_desc.dwWidth = 256; surface_desc.dwHeight = 256; surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat); @@ -1803,11 +1835,11 @@ static void test_ck_rgba(void) surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff00; surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff00; hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); - ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirect3DTexture, (void **)&texture); - ok(SUCCEEDED(hr), "Failed to get texture interface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DTexture_GetHandle(texture, device, &texture_handle); - ok(SUCCEEDED(hr), "Failed to get texture handle, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); IDirect3DTexture_Release(texture);
memset(&exec_desc, 0, sizeof(exec_desc)); @@ -1816,10 +1848,10 @@ static void test_ck_rgba(void) exec_desc.dwBufferSize = 1024; exec_desc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY; hr = IDirect3DDevice_CreateExecuteBuffer(device, &exec_desc, &execute_buffer, NULL); - ok(SUCCEEDED(hr), "Failed to create execute buffer, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&rt); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i) { @@ -1827,7 +1859,7 @@ static void test_ck_rgba(void) void *ptr;
hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc); - ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); memcpy(exec_desc.lpData, tquad, sizeof(tquad)); ptr = ((BYTE *)exec_desc.lpData) + sizeof(tquad); emit_process_vertices(&ptr, D3DPROCESSVERTICES_COPY, 0, 4); @@ -1835,6 +1867,15 @@ static void test_ck_rgba(void) emit_set_rs(&ptr, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); emit_set_rs(&ptr, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); emit_set_rs(&ptr, D3DRENDERSTATE_COLORKEYENABLE, tests[i].color_key); + + if (is_software_device_type(device_guid)) + { + /* It looks like D3DRENDERSTATE_COLORKEYENABLE is ignored with software device + * on Windows and the colour key is always enabled if set on surface. */ + IDirectDrawSurface_SetColorKey(surface, DDCKEY_SRCBLT, tests[i].color_key + ? &surface_desc.ddckCKSrcBlt : NULL); + } + emit_set_rs(&ptr, D3DRENDERSTATE_ALPHABLENDENABLE, tests[i].blend); emit_tquad(&ptr, 0); emit_end(&ptr); @@ -1845,46 +1886,50 @@ static void test_ck_rgba(void) emit_end(&ptr); draw2_len = (BYTE *)ptr - (BYTE *)exec_desc.lpData - draw1_len; hr = IDirect3DExecuteBuffer_Unlock(execute_buffer); - ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
memset(&fx, 0, sizeof(fx)); fx.dwSize = sizeof(fx); U5(fx).dwFillColor = tests[i].fill_color; hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER); - ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + /* RT clears are broken on Windows for software render target. */ + if (is_software_device_type(device_guid)) + fill_surface(rt, 0xffff0000); + hr = IDirect3DDevice_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); set_execute_data(execute_buffer, 8, sizeof(tquad), draw1_len); hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED); - ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240); - ok(compare_color(color, tests[i].result1, 1) + ok(compare_color(color, tests[i].result1, max_diff) || broken(compare_color(color, tests[i].result1_r200, 1)) || broken(compare_color(color, tests[i].result1_warp, 1)), "Got unexpected color 0x%08x for test %u.\n", color, i);
U5(fx).dwFillColor = 0xff0000ff; hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); set_execute_data(execute_buffer, 8, sizeof(tquad) + draw1_len, draw2_len); hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED); - ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
/* This tests that fragments that are masked out by the color key are * discarded, instead of just fully transparent. */ color = get_surface_color(rt, 320, 240); - ok(compare_color(color, tests[i].result2, 1) + ok(compare_color(color, tests[i].result2, max_diff) || broken(compare_color(color, tests[i].result2_r200, 1)) || broken(compare_color(color, tests[i].result2_warp, 1)), "Got unexpected color 0x%08x for test %u.\n", color, i); @@ -4975,29 +5020,6 @@ static void test_surface_discard(void) DestroyWindow(window); }
-static void fill_surface(IDirectDrawSurface *surface, D3DCOLOR color) -{ - DDSURFACEDESC surface_desc = {sizeof(surface_desc)}; - HRESULT hr; - unsigned int x, y; - DWORD *ptr; - - hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - - for (y = 0; y < surface_desc.dwHeight; ++y) - { - ptr = (DWORD *)((BYTE *)surface_desc.lpSurface + y * U1(surface_desc).lPitch); - for (x = 0; x < surface_desc.dwWidth; ++x) - { - ptr[x] = color; - } - } - - hr = IDirectDrawSurface_Unlock(surface, NULL); - ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); -} - static void test_flip(void) { const DWORD placement = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY; @@ -14381,7 +14403,7 @@ START_TEST(ddraw1) test_coop_level_threaded(); test_viewport_object(); run_for_each_device_type(test_zenable); - test_ck_rgba(); + run_for_each_device_type(test_ck_rgba); test_ck_default(); test_ck_complex(); test_surface_qi(); diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index 56a44ce494a..58f8006f289 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -1915,7 +1915,7 @@ static void test_zenable(const GUID *device_guid) DestroyWindow(window); }
-static void test_ck_rgba(void) +static void test_ck_rgba(const GUID *device_guid) { static D3DRECT clear_rect = {{0}, {0}, {640}, {480}}; static D3DTLVERTEX tquad[] = @@ -1961,15 +1961,18 @@ static void test_ck_rgba(void) IDirectDrawSurface *rt; IDirectDraw2 *ddraw; D3DCOLOR color; + BYTE max_diff; HWND window; DDBLTFX fx; HRESULT hr; UINT i;
+ max_diff = is_software_device_type(device_guid) ? 2 : 1; + window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) + if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid))) { skip("Failed to create a 3D device, skipping test.\n"); IDirectDraw2_Release(ddraw); @@ -1981,12 +1984,14 @@ static void test_ck_rgba(void) viewport = create_viewport(device, 0, 0, 640, 480); viewport_set_background(device, viewport, background); hr = IDirect3DDevice2_SetCurrentViewport(device, viewport); - ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT; surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + if (is_software_device_type(device_guid)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; surface_desc.dwWidth = 256; surface_desc.dwHeight = 256; surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat); @@ -1999,72 +2004,76 @@ static void test_ck_rgba(void) surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff00; surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff00; hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL); - ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirect3DTexture2, (void **)&texture); - ok(SUCCEEDED(hr), "Failed to get texture interface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DTexture2_GetHandle(texture, device, &texture_handle); - ok(SUCCEEDED(hr), "Failed to get texture handle, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); IDirect3DTexture2_Release(texture);
hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle); - ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); - ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); - ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_GetRenderTarget(device, &rt); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i) { hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, tests[i].color_key); - ok(SUCCEEDED(hr), "Failed to enable color keying, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, tests[i].blend); - ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
memset(&fx, 0, sizeof(fx)); fx.dwSize = sizeof(fx); U5(fx).dwFillColor = tests[i].fill_color; hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER); - ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + /* RT clears are broken on Windows for software render target. */ + if (is_software_device_type(device_guid)) + fill_surface(rt, 0xffff0000); + hr = IDirect3DDevice2_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_TLVERTEX, &tquad[0], 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice2_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240); - ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1), + ok(compare_color(color, tests[i].result1, max_diff) || compare_color(color, tests[i].result1_broken, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n", tests[i].result1, i, color);
U5(fx).dwFillColor = 0xff0000ff; hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice2_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_TLVERTEX, &tquad[4], 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice2_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
/* This tests that fragments that are masked out by the color key are * discarded, instead of just fully transparent. */ color = get_surface_color(rt, 320, 240); - ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1), + ok(compare_color(color, tests[i].result2, max_diff) || compare_color(color, tests[i].result2_broken, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n", tests[i].result2, i, color); }
IDirectDrawSurface_Release(rt); hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_TEXTUREHANDLE, 0); - ok(SUCCEEDED(hr), "Failed to unset texture, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); IDirectDrawSurface_Release(surface); destroy_viewport(device, viewport); destroy_material(background); @@ -15357,7 +15366,7 @@ START_TEST(ddraw2) test_texture_load_ckey(); test_viewport_object(); run_for_each_device_type(test_zenable); - test_ck_rgba(); + run_for_each_device_type(test_ck_rgba); test_ck_default(); test_ck_complex(); test_surface_qi(); diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 23049134f4d..91c993f75df 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -2153,7 +2153,7 @@ static void test_zenable(const GUID *device_guid) DestroyWindow(window); }
-static void test_ck_rgba(void) +static void test_ck_rgba(const GUID *device_guid) { static D3DRECT clear_rect = {{0}, {0}, {640}, {480}}; static struct @@ -2203,13 +2203,16 @@ static void test_ck_rgba(void) IDirectDraw4 *ddraw; IDirect3D3 *d3d; D3DCOLOR color; + BYTE max_diff; HWND window; DDBLTFX fx; HRESULT hr; UINT i;
+ max_diff = is_software_device_type(device_guid) ? 2 : 1; + window = create_window(); - if (!(device = create_device(window, DDSCL_NORMAL))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -2218,18 +2221,20 @@ static void test_ck_rgba(void)
viewport = create_viewport(device, 0, 0, 640, 480); hr = IDirect3DDevice3_SetCurrentViewport(device, viewport); - ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_GetDirect3D(device, &d3d); - ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3D3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw); - ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); IDirect3D3_Release(d3d);
memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT; surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + if (is_software_device_type(device_guid)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; surface_desc.dwWidth = 256; surface_desc.dwHeight = 256; U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat); @@ -2242,63 +2247,65 @@ static void test_ck_rgba(void) surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff00; surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff00; hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL); - ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface4_QueryInterface(surface, &IID_IDirect3DTexture2, (void **)&texture); - ok(SUCCEEDED(hr), "Failed to get texture interface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_SetTexture(device, 0, texture); - ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); - ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); - ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_GetRenderTarget(device, &rt); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i) { hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, tests[i].color_key); - ok(SUCCEEDED(hr), "Failed to enable color keying, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, tests[i].blend); - ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
memset(&fx, 0, sizeof(fx)); fx.dwSize = sizeof(fx); U5(fx).dwFillColor = tests[i].fill_color; hr = IDirectDrawSurface4_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0); - ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + if (is_software_device_type(device_guid)) + fill_surface(rt, 0xffff0000); hr = IDirect3DDevice3_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[0], 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240); - ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1), + ok(compare_color(color, tests[i].result1, max_diff) || compare_color(color, tests[i].result1_broken, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n", tests[i].result1, i, color);
U5(fx).dwFillColor = 0xff0000ff; hr = IDirectDrawSurface4_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[4], 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
/* This tests that fragments that are masked out by the color key are * discarded, instead of just fully transparent. */ color = get_surface_color(rt, 320, 240); - ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1), + ok(compare_color(color, tests[i].result2, max_diff) || compare_color(color, tests[i].result2_broken, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n", tests[i].result2, i, color); } @@ -18418,7 +18425,7 @@ START_TEST(ddraw4) test_texture_load_ckey(); test_viewport_object(); run_for_each_device_type(test_zenable); - test_ck_rgba(); + run_for_each_device_type(test_ck_rgba); test_ck_default(); test_ck_complex(); test_surface_qi(); diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 2351a037f23..349cc38c4e3 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -1783,7 +1783,7 @@ static void test_zenable(const GUID *device_guid) DestroyWindow(window); }
-static void test_ck_rgba(void) +static void test_ck_rgba(const GUID *device_guid) { static struct { @@ -1830,13 +1830,16 @@ static void test_ck_rgba(void) IDirectDraw7 *ddraw; IDirect3D7 *d3d; D3DCOLOR color; + BYTE max_diff; HWND window; DDBLTFX fx; HRESULT hr; UINT i;
+ max_diff = is_software_device_type(device_guid) ? 2 : 1; + window = create_window(); - if (!(device = create_device(window, DDSCL_NORMAL))) + if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid))) { skip("Failed to create a 3D device, skipping test.\n"); DestroyWindow(window); @@ -1844,15 +1847,17 @@ static void test_ck_rgba(void) }
hr = IDirect3DDevice7_GetDirect3D(device, &d3d); - ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw); - ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); IDirect3D7_Release(d3d);
memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT; surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + if (is_software_device_type(device_guid)) + surface_desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; surface_desc.dwWidth = 256; surface_desc.dwHeight = 256; U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat); @@ -1865,60 +1870,64 @@ static void test_ck_rgba(void) surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff00; surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff00; hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &texture, NULL); - ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_SetTexture(device, 0, texture); - ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); - ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); - ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_GetRenderTarget(device, &rt); - ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i) { hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, tests[i].color_key); - ok(SUCCEEDED(hr), "Failed to enable color keying, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, tests[i].blend); - ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
memset(&fx, 0, sizeof(fx)); fx.dwSize = sizeof(fx); U5(fx).dwFillColor = tests[i].fill_color; hr = IDirectDrawSurface7_Blt(texture, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0); - ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + /* RT clears are broken on Windows for software render target. */ + if (is_software_device_type(device_guid)) + fill_surface(rt, 0xffff0000); + hr = IDirect3DDevice7_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[0], 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice7_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240); - ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1), + ok(compare_color(color, tests[i].result1, max_diff) || compare_color(color, tests[i].result1_broken, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n", tests[i].result1, i, color);
U5(fx).dwFillColor = 0xff0000ff; hr = IDirectDrawSurface7_Blt(texture, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice7_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[4], 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice7_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
/* This tests that fragments that are masked out by the color key are * discarded, instead of just fully transparent. */ color = get_surface_color(rt, 320, 240); - ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1), + ok(compare_color(color, tests[i].result2, max_diff) || compare_color(color, tests[i].result2_broken, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n", tests[i].result2, i, color); } @@ -18704,7 +18713,7 @@ START_TEST(ddraw7) run_for_each_device_type(test_depth_blit); test_texture_load_ckey(); run_for_each_device_type(test_zenable); - test_ck_rgba(); + run_for_each_device_type(test_ck_rgba); test_ck_default(); test_ck_complex(); test_surface_qi();
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=86132
Your paranoid android.
=== w8 (32 bit report) ===
ddraw: ddraw1.c:4615: Test failed: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw1.c:4615: Test failed: Got unexpected caps 0x10024000, test 17, software_device 1.
=== w8adm (32 bit report) ===
ddraw: ddraw1.c:4615: Test failed: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw1.c:4615: Test failed: Got unexpected caps 0x10024000, test 17, software_device 1.
=== w864 (32 bit report) ===
ddraw: ddraw1.c:4615: Test failed: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw1.c:4615: Test failed: Got unexpected caps 0x10024000, test 17, software_device 1.
=== w1064v1507 (32 bit report) ===
ddraw: ddraw1.c:4615: Test failed: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw1.c:4615: Test failed: Got unexpected caps 0x10024000, test 17, software_device 1.
=== w1064v1809 (32 bit report) ===
ddraw: ddraw1.c:4615: Test failed: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw1.c:4615: Test failed: Got unexpected caps 0x10024000, test 17, software_device 1.
=== w1064 (32 bit report) ===
ddraw: ddraw1.c:4615: Test failed: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw1.c:4615: Test failed: Got unexpected caps 0x10024000, test 17, software_device 1.
=== w10pro64 (32 bit report) ===
ddraw: ddraw1.c:4615: Test failed: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw1.c:4615: Test failed: Got unexpected caps 0x10024000, test 17, software_device 1.
=== debiant2 (32 bit report) ===
ddraw: ddraw2.c:5111: Test succeeded inside todo block: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw2.c:5111: Test succeeded inside todo block: Got unexpected caps 0x10024000, test 17, software_device 1.
=== debiant2 (32 bit French report) ===
ddraw: ddraw2.c:5111: Test succeeded inside todo block: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw2.c:5111: Test succeeded inside todo block: Got unexpected caps 0x10024000, test 17, software_device 1.
=== debiant2 (32 bit Japanese:Japan report) ===
ddraw: ddraw2.c:5111: Test succeeded inside todo block: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw2.c:5111: Test succeeded inside todo block: Got unexpected caps 0x10024000, test 17, software_device 1. ddraw2.c:15166: Test failed: Expect window rect (0,0)-(1024,768), got (7,26)-(1017,761).
=== debiant2 (32 bit Chinese:China report) ===
ddraw: ddraw2.c:5111: Test succeeded inside todo block: Got unexpected caps 0x10026000, test 16, software_device 1. ddraw2.c:5111: Test succeeded inside todo block: Got unexpected caps 0x10024000, test 17, software_device 1.