From d255223474c491edc24efad314e6f56328589604 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sun, 21 Jan 2018 22:15:58 +0100 Subject: [PATCH] [DDRAW] Sync with Wine 3.0. CORE-14225 --- dll/directx/wine/ddraw/ddraw.c | 221 ++++++------------------- dll/directx/wine/ddraw/ddraw_private.h | 10 +- dll/directx/wine/ddraw/device.c | 50 ++++-- dll/directx/wine/ddraw/executebuffer.c | 5 +- dll/directx/wine/ddraw/surface.c | 182 +++++++++----------- dll/directx/wine/ddraw/vertexbuffer.c | 5 +- dll/directx/wine/ddraw/viewport.c | 4 +- media/doc/README.WINE | 2 +- 8 files changed, 175 insertions(+), 304 deletions(-) diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c index 9712bb53aeb..2ab9edd015d 100644 --- a/dll/directx/wine/ddraw/ddraw.c +++ b/dll/directx/wine/ddraw/ddraw.c @@ -45,7 +45,6 @@ static struct enum_device_entry char interface_name[100]; char device_name[100]; const GUID *device_guid; - DWORD remove_caps; } device_list7[] = { /* T&L HAL device */ @@ -53,7 +52,6 @@ static struct enum_device_entry "WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D", "Wine D3D7 T&L HAL", &IID_IDirect3DTnLHalDevice, - 0, }, /* HAL device */ @@ -61,7 +59,6 @@ static struct enum_device_entry "WINE Direct3D7 Hardware acceleration using WineD3D", "Direct3D HAL", &IID_IDirect3DHALDevice, - 0, }, /* RGB device */ @@ -69,7 +66,6 @@ static struct enum_device_entry "WINE Direct3D7 RGB Software Emulation using WineD3D", "Wine D3D7 RGB", &IID_IDirect3DRGBDevice, - D3DDEVCAPS_HWTRANSFORMANDLIGHT, }, }; @@ -1419,23 +1415,10 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) caps->dwMinTextureHeight = 1; /* Convert DWORDs safely to WORDs */ - if (wined3d_caps.MaxTextureBlendStages > 0xffff) - caps->wMaxTextureBlendStages = 0xffff; - else - caps->wMaxTextureBlendStages = (WORD)wined3d_caps.MaxTextureBlendStages; - if (wined3d_caps.MaxSimultaneousTextures > 0xffff) - caps->wMaxSimultaneousTextures = 0xffff; - else - caps->wMaxSimultaneousTextures = (WORD)wined3d_caps.MaxSimultaneousTextures; - - if (wined3d_caps.MaxUserClipPlanes > 0xffff) - caps->wMaxUserClipPlanes = 0xffff; - else - caps->wMaxUserClipPlanes = (WORD)wined3d_caps.MaxUserClipPlanes; - if (wined3d_caps.MaxVertexBlendMatrices > 0xffff) - caps->wMaxVertexBlendMatrices = 0xffff; - else - caps->wMaxVertexBlendMatrices = (WORD)wined3d_caps.MaxVertexBlendMatrices; + caps->wMaxTextureBlendStages = min(wined3d_caps.MaxTextureBlendStages, 0xffff); + caps->wMaxSimultaneousTextures = min(wined3d_caps.MaxSimultaneousTextures, 0xffff); + caps->wMaxUserClipPlanes = min(wined3d_caps.MaxUserClipPlanes, D3DMAXUSERCLIPPLANES); + caps->wMaxVertexBlendMatrices = min(wined3d_caps.MaxVertexBlendMatrices, 0xffff); caps->deviceGUID = IID_IDirect3DTnLHalDevice; @@ -1447,28 +1430,6 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) return DD_OK; } -HRESULT CALLBACK enum_zbuffer(DDPIXELFORMAT *format, void *ctx) -{ - DDCAPS *caps = ctx; - - switch (format->u1.dwZBufferBitDepth) - { - case 8: - caps->dwZBufferBitDepths |= DDBD_8; - break; - case 16: - caps->dwZBufferBitDepths |= DDBD_16; - break; - case 24: - caps->dwZBufferBitDepths |= DDBD_24; - break; - case 32: - caps->dwZBufferBitDepths |= DDBD_32; - break; - } - return D3DENUMRET_OK; -} - /***************************************************************************** * IDirectDraw7::GetCaps * @@ -1549,10 +1510,6 @@ static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DD caps.dwCaps |= DDCAPS_ALIGNSTRIDE; caps.dwAlignStrideAlign = DDRAW_STRIDE_ALIGNMENT; - caps.ddsOldCaps.dwCaps = caps.ddsCaps.dwCaps; - - IDirect3D7_EnumZBufferFormats(&ddraw->IDirect3D7_iface, &IID_IDirect3DHALDevice, enum_zbuffer, &caps); - if(DriverCaps) { DD_STRUCT_COPY_BYSIZE(DriverCaps, &caps); @@ -1665,17 +1622,14 @@ static HRESULT WINAPI ddraw7_GetDisplayMode(IDirectDraw7 *iface, DDSURFACEDESC2 struct ddraw *ddraw = impl_from_IDirectDraw7(iface); struct wined3d_display_mode mode; HRESULT hr; - DWORD Size; TRACE("iface %p, surface_desc %p.\n", iface, DDSD); - wined3d_mutex_lock(); /* This seems sane */ - if (!DDSD) - { - wined3d_mutex_unlock(); + if (!DDSD || (DDSD->dwSize != sizeof(DDSURFACEDESC) && DDSD->dwSize != sizeof(DDSURFACEDESC2))) return DDERR_INVALIDPARAMS; - } + + wined3d_mutex_lock(); if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL))) { @@ -1684,10 +1638,8 @@ static HRESULT WINAPI ddraw7_GetDisplayMode(IDirectDraw7 *iface, DDSURFACEDESC2 return hr; } - Size = DDSD->dwSize; - memset(DDSD, 0, Size); - - DDSD->dwSize = Size; + memset(DDSD, 0, DDSD->dwSize); + DDSD->dwSize = sizeof(*DDSD); DDSD->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE; DDSD->dwWidth = mode.width; DDSD->dwHeight = mode.height; @@ -1720,21 +1672,25 @@ static HRESULT WINAPI ddraw4_GetDisplayMode(IDirectDraw4 *iface, DDSURFACEDESC2 static HRESULT WINAPI ddraw2_GetDisplayMode(IDirectDraw2 *iface, DDSURFACEDESC *surface_desc) { struct ddraw *ddraw = impl_from_IDirectDraw2(iface); + HRESULT hr; TRACE("iface %p, surface_desc %p.\n", iface, surface_desc); - /* FIXME: Test sizes, properly convert surface_desc */ - return ddraw7_GetDisplayMode(&ddraw->IDirectDraw7_iface, (DDSURFACEDESC2 *)surface_desc); + hr = ddraw7_GetDisplayMode(&ddraw->IDirectDraw7_iface, (DDSURFACEDESC2 *)surface_desc); + if (SUCCEEDED(hr)) surface_desc->dwSize = sizeof(*surface_desc); + return hr; } static HRESULT WINAPI ddraw1_GetDisplayMode(IDirectDraw *iface, DDSURFACEDESC *surface_desc) { struct ddraw *ddraw = impl_from_IDirectDraw(iface); + HRESULT hr; TRACE("iface %p, surface_desc %p.\n", iface, surface_desc); - /* FIXME: Test sizes, properly convert surface_desc */ - return ddraw7_GetDisplayMode(&ddraw->IDirectDraw7_iface, (DDSURFACEDESC2 *)surface_desc); + hr = ddraw7_GetDisplayMode(&ddraw->IDirectDraw7_iface, (DDSURFACEDESC2 *)surface_desc); + if (SUCCEEDED(hr)) surface_desc->dwSize = sizeof(*surface_desc); + return hr; } /***************************************************************************** @@ -2101,14 +2057,7 @@ static HRESULT WINAPI d3d1_Initialize(IDirect3D *iface, REFIID riid) *****************************************************************************/ static HRESULT WINAPI ddraw7_FlipToGDISurface(IDirectDraw7 *iface) { - struct ddraw *ddraw = impl_from_IDirectDraw7(iface); - - TRACE("iface %p.\n", iface); - - ddraw->flags |= DDRAW_GDI_FLIP; - - if (ddraw->primary) - ddraw_surface_update_frontbuffer(ddraw->primary, NULL, FALSE); + FIXME("iface %p stub!\n", iface); return DD_OK; } @@ -3240,97 +3189,46 @@ static HRESULT WINAPI ddraw7_EnumSurfaces(IDirectDraw7 *iface, DWORD Flags, { struct ddraw *ddraw = impl_from_IDirectDraw7(iface); struct ddraw_surface *surf; - DWORD match_flags = Flags & (DDENUMSURFACES_ALL | DDENUMSURFACES_NOMATCH | DDENUMSURFACES_MATCH); + BOOL all, nomatch; + DDSURFACEDESC2 desc; + struct list *entry, *entry2; TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n", iface, Flags, DDSD, Context, Callback); + all = Flags & DDENUMSURFACES_ALL; + nomatch = Flags & DDENUMSURFACES_NOMATCH; + if (!Callback) return DDERR_INVALIDPARAMS; - if (Flags & DDENUMSURFACES_CANBECREATED) - { - IDirectDrawSurface7 *surface; - DDSURFACEDESC2 testdesc; - HRESULT hr; - - if (match_flags != DDENUMSURFACES_MATCH) - return DDERR_INVALIDPARAMS; - - if (!DDSD) - return DDERR_INVALIDPARAMS; + wined3d_mutex_lock(); - memcpy(&testdesc, DDSD, sizeof(testdesc)); - if (!(testdesc.dwFlags & DDSD_WIDTH)) - { - testdesc.dwFlags |= DDSD_WIDTH; - testdesc.dwWidth = 512; - } - if (!(testdesc.dwFlags & DDSD_HEIGHT)) - { - testdesc.dwFlags |= DDSD_HEIGHT; - testdesc.dwHeight = 512; - } + /* Use the _SAFE enumeration, the app may destroy enumerated surfaces */ + LIST_FOR_EACH_SAFE(entry, entry2, &ddraw->surface_list) + { + surf = LIST_ENTRY(entry, struct ddraw_surface, surface_list_entry); - hr = IDirectDraw7_CreateSurface(iface, &testdesc, &surface, NULL); - if (SUCCEEDED(hr)) + if (!surf->iface_count) { - surf = unsafe_impl_from_IDirectDrawSurface7(surface); - Callback(NULL, &surf->surface_desc, Context); - IDirectDrawSurface7_Release(surface); + WARN("Not enumerating surface %p because it doesn't have any references.\n", surf); + continue; } - else - ERR("Failed to create surface, hr %#x.\n", hr); - } - else if (Flags & DDENUMSURFACES_DOESEXIST) - { - BOOL all, nomatch; - DDSURFACEDESC2 desc; - struct list *entry, *entry2; - - /* a combination of match flags is not allowed */ - if (match_flags != 0 && - match_flags != DDENUMSURFACES_ALL && - match_flags != DDENUMSURFACES_MATCH && - match_flags != DDENUMSURFACES_NOMATCH) - return DDERR_INVALIDPARAMS; - - all = (Flags & DDENUMSURFACES_ALL) != 0; - nomatch = (Flags & DDENUMSURFACES_NOMATCH) != 0; - if (!all && !DDSD) - return DDERR_INVALIDPARAMS; - - wined3d_mutex_lock(); - - /* Use the _SAFE enumeration, the app may destroy enumerated surfaces */ - LIST_FOR_EACH_SAFE(entry, entry2, &ddraw->surface_list) + if (all || (nomatch != ddraw_match_surface_desc(DDSD, &surf->surface_desc))) { - surf = LIST_ENTRY(entry, struct ddraw_surface, surface_list_entry); - - if (!surf->iface_count) + TRACE("Enumerating surface %p.\n", surf); + desc = surf->surface_desc; + IDirectDrawSurface7_AddRef(&surf->IDirectDrawSurface7_iface); + if (Callback(&surf->IDirectDrawSurface7_iface, &desc, Context) != DDENUMRET_OK) { - WARN("Not enumerating surface %p because it doesn't have any references.\n", surf); - continue; - } - - if (all || (nomatch != ddraw_match_surface_desc(DDSD, &surf->surface_desc))) - { - TRACE("Enumerating surface %p.\n", surf); - desc = surf->surface_desc; - IDirectDrawSurface7_AddRef(&surf->IDirectDrawSurface7_iface); - if (Callback(&surf->IDirectDrawSurface7_iface, &desc, Context) != DDENUMRET_OK) - { - wined3d_mutex_unlock(); - return DD_OK; - } + wined3d_mutex_unlock(); + return DD_OK; } } - - wined3d_mutex_unlock(); } - else - return DDERR_INVALIDPARAMS; + + wined3d_mutex_unlock(); return DD_OK; } @@ -3728,7 +3626,6 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA { struct ddraw *ddraw = impl_from_IDirect3D7(iface); D3DDEVICEDESC7 device_desc7; - DWORD dev_caps; HRESULT hr; size_t i; @@ -3745,15 +3642,11 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA return hr; } - dev_caps = device_desc7.dwDevCaps; - for (i = 0; i < sizeof(device_list7)/sizeof(device_list7[0]); i++) { HRESULT ret; device_desc7.deviceGUID = *device_list7[i].device_guid; - device_desc7.dwDevCaps = dev_caps & ~device_list7[i].remove_caps; - ret = callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context); if (ret != DDENUMRET_OK) { @@ -4151,8 +4044,8 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd if (!fds || !fdr) return DDERR_INVALIDPARAMS; - if (fds->dwSize != sizeof(D3DFINDDEVICESEARCH) || (fdr->dwSize != sizeof(D3DFINDDEVICERESULT1) && - fdr->dwSize != sizeof(D3DFINDDEVICERESULT2) && fdr->dwSize != sizeof(D3DFINDDEVICERESULT))) + if (fds->dwSize != sizeof(D3DFINDDEVICESEARCH) + || fdr->dwSize != sizeof(D3DFINDDEVICERESULT)) return DDERR_INVALIDPARAMS; if ((fds->dwFlags & D3DFDS_COLORMODEL) @@ -4181,24 +4074,8 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd /* Now return our own GUID */ ddraw_d3dcaps1_from_7(&desc1, &desc7); fdr->guid = IID_D3DDEVICE_WineD3D; - - if (fdr->dwSize == sizeof(D3DFINDDEVICERESULT1)) - { - D3DFINDDEVICERESULT1 *fdr1 = (D3DFINDDEVICERESULT1 *)fdr; - memcpy(&fdr1->ddHwDesc, &desc1, sizeof(fdr1->ddHwDesc)); - memcpy(&fdr1->ddSwDesc, &desc1, sizeof(fdr1->ddSwDesc)); - } - else if (fdr->dwSize == sizeof(D3DFINDDEVICERESULT2)) - { - D3DFINDDEVICERESULT2 *fdr2 = (D3DFINDDEVICERESULT2 *)fdr; - memcpy(&fdr2->ddHwDesc, &desc1, sizeof(fdr2->ddHwDesc)); - memcpy(&fdr2->ddSwDesc, &desc1, sizeof(fdr2->ddSwDesc)); - } - else - { - fdr->ddHwDesc = desc1; - fdr->ddSwDesc = desc1; - } + fdr->ddHwDesc = desc1; + fdr->ddSwDesc = desc1; TRACE("Returning Wine's wined3d device with (undumped) capabilities.\n"); @@ -4255,7 +4132,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, riid, target, (IUnknown *)surface, 7, &object, NULL))) + if (SUCCEEDED(hr = d3d_device_create(ddraw, target, (IUnknown *)surface, 7, &object, NULL))) { *device = &object->IDirect3DDevice7_iface; } @@ -4284,7 +4161,7 @@ static HRESULT WINAPI d3d3_CreateDevice(IDirect3D3 *iface, REFCLSID riid, return CLASS_E_NOAGGREGATION; wined3d_mutex_lock(); - if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL))) + if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL))) { *device = &device_impl->IDirect3DDevice3_iface; } @@ -4310,7 +4187,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, riid, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL))) + if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL))) { *device = &device_impl->IDirect3DDevice2_iface; } @@ -4682,7 +4559,7 @@ static const struct IDirectDraw2Vtbl ddraw2_vtbl = ddraw2_GetAvailableVidMem, }; -static struct IDirectDrawVtbl ddraw1_vtbl = +static const struct IDirectDrawVtbl ddraw1_vtbl = { /* IUnknown */ ddraw1_QueryInterface, diff --git a/dll/directx/wine/ddraw/ddraw_private.h b/dll/directx/wine/ddraw/ddraw_private.h index a7d19d32f6f..04ee59c05f4 100644 --- a/dll/directx/wine/ddraw/ddraw_private.h +++ b/dll/directx/wine/ddraw/ddraw_private.h @@ -44,6 +44,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw); +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + extern const struct wined3d_parent_ops ddraw_null_wined3d_parent_ops DECLSPEC_HIDDEN; extern DWORD force_refresh_rate DECLSPEC_HIDDEN; @@ -62,14 +64,13 @@ struct FvfToDecl #define DDRAW_NO3D 0x00000008 #define DDRAW_SCL_DDRAW1 0x00000010 #define DDRAW_SCL_RECURSIVE 0x00000020 -#define DDRAW_GDI_FLIP 0x00000040 #define DDRAW_STRIDE_ALIGNMENT 8 #define DDRAW_WINED3D_FLAGS (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \ | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER \ | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \ - | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT) + | WINED3D_LEGACY_CUBEMAP_FILTERING) enum ddraw_device_state { @@ -308,7 +309,6 @@ struct d3d_device IUnknown IUnknown_inner; LONG ref; UINT version; - BOOL hw; IUnknown *outer_unknown; struct wined3d_device *wined3d_device; @@ -349,9 +349,11 @@ struct d3d_device /* Handle management */ struct ddraw_handle_table handle_table; D3DMATRIXHANDLE world, proj, view; + + struct wined3d_vec4 user_clip_planes[D3DMAXUSERCLIPPLANES]; }; -HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface, +HRESULT d3d_device_create(struct ddraw *ddraw, 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/dll/directx/wine/ddraw/device.c b/dll/directx/wine/ddraw/device.c index 6b93266467e..fe48ad3b36b 100644 --- a/dll/directx/wine/ddraw/device.c +++ b/dll/directx/wine/ddraw/device.c @@ -1166,7 +1166,7 @@ static HRESULT WINAPI d3d_device3_EnumTextureFormats(IDirect3DDevice3 *iface, * IDirect3DDevice2::EnumTextureformats * * EnumTextureFormats for Version 1 and 2, see - * IDirect3DDevice7::EnumTexureFormats for a more detailed description. + * IDirect3DDevice7::EnumTextureFormats for a more detailed description. * * This version has a different callback and does not enumerate FourCC * formats @@ -1852,7 +1852,7 @@ static HRESULT d3d_device7_SetRenderTarget(IDirect3DDevice7 *iface, return DDERR_INVALIDCAPS; } - if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) { WARN("Surface %p is not in video memory.\n", target_impl); wined3d_mutex_unlock(); @@ -1928,7 +1928,7 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface, return DDERR_INVALIDPIXELFORMAT; } - if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) { WARN("Surface %p is not in video memory.\n", target_impl); IDirectDrawSurface4_AddRef(target); @@ -1977,7 +1977,7 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface, return DDERR_INVALIDPIXELFORMAT; } - if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) { WARN("Surface %p is not in video memory.\n", target_impl); IDirectDrawSurface_AddRef(target); @@ -6453,6 +6453,7 @@ static HRESULT WINAPI d3d_device7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *i static HRESULT d3d_device7_SetClipPlane(IDirect3DDevice7 *iface, DWORD idx, D3DVALUE *plane) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + const struct wined3d_vec4 *wined3d_plane; HRESULT hr; TRACE("iface %p, idx %u, plane %p.\n", iface, idx, plane); @@ -6460,8 +6461,19 @@ static HRESULT d3d_device7_SetClipPlane(IDirect3DDevice7 *iface, DWORD idx, D3DV if (!plane) return DDERR_INVALIDPARAMS; + wined3d_plane = (struct wined3d_vec4 *)plane; + wined3d_mutex_lock(); - hr = wined3d_device_set_clip_plane(device->wined3d_device, idx, (struct wined3d_vec4 *)plane); + hr = wined3d_device_set_clip_plane(device->wined3d_device, idx, wined3d_plane); + if (idx < ARRAY_SIZE(device->user_clip_planes)) + { + device->user_clip_planes[idx] = *wined3d_plane; + if (hr == WINED3DERR_INVALIDCALL) + { + WARN("Clip plane %u is not supported.\n", idx); + hr = D3D_OK; + } + } wined3d_mutex_unlock(); return hr; @@ -6501,6 +6513,7 @@ static HRESULT WINAPI d3d_device7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *ifa static HRESULT d3d_device7_GetClipPlane(IDirect3DDevice7 *iface, DWORD idx, D3DVALUE *plane) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + struct wined3d_vec4 *wined3d_plane; HRESULT hr; TRACE("iface %p, idx %u, plane %p.\n", iface, idx, plane); @@ -6508,8 +6521,16 @@ static HRESULT d3d_device7_GetClipPlane(IDirect3DDevice7 *iface, DWORD idx, D3DV if (!plane) return DDERR_INVALIDPARAMS; + wined3d_plane = (struct wined3d_vec4 *)plane; + wined3d_mutex_lock(); - hr = wined3d_device_get_clip_plane(device->wined3d_device, idx, (struct wined3d_vec4 *)plane); + hr = wined3d_device_get_clip_plane(device->wined3d_device, idx, wined3d_plane); + if (hr == WINED3DERR_INVALIDCALL && idx < ARRAY_SIZE(device->user_clip_planes)) + { + WARN("Clip plane %u is not supported.\n", idx); + *wined3d_plane = device->user_clip_planes[idx]; + hr = D3D_OK; + } wined3d_mutex_unlock(); return hr; @@ -6866,7 +6887,7 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device return WINED3D_ZB_TRUE; } -static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, BOOL hw, +static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface, UINT version, IUnknown *outer_unknown) { static const D3DMATRIX ident = @@ -6889,7 +6910,6 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, B device->IUnknown_inner.lpVtbl = &d3d_device_inner_vtbl; device->ref = 1; device->version = version; - device->hw = hw; if (outer_unknown) device->outer_unknown = outer_unknown; @@ -6940,18 +6960,14 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, B return D3D_OK; } -HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface, +HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface, UINT version, struct d3d_device **device, IUnknown *outer_unknown) { struct d3d_device *object; - BOOL hw = TRUE; HRESULT hr; - 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 (IsEqualGUID(guid, &IID_IDirect3DRGBDevice)) - hw = FALSE; + TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n", + ddraw, target, version, device, outer_unknown); if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) || (target->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) @@ -6966,7 +6982,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su return DDERR_NOPALETTEATTACHED; } - if (hw && !(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) { WARN("Surface %p is not in video memory.\n", target); return D3DERR_SURFACENOTINVIDMEM; @@ -6993,7 +7009,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su return DDERR_OUTOFMEMORY; } - if (FAILED(hr = d3d_device_init(object, ddraw, hw, target, rt_iface, version, outer_unknown))) + if (FAILED(hr = d3d_device_init(object, ddraw, target, rt_iface, version, outer_unknown))) { WARN("Failed to initialize device, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); diff --git a/dll/directx/wine/ddraw/executebuffer.c b/dll/directx/wine/ddraw/executebuffer.c index 1bc5b5c5fb9..7b68bd70b56 100644 --- a/dll/directx/wine/ddraw/executebuffer.c +++ b/dll/directx/wine/ddraw/executebuffer.c @@ -297,10 +297,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, ci->wStart, ci->wDest, ci->dwCount, ci->dwFlags); if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS) - { - static int once; - if (!once++) FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n"); - } + FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n"); if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR) FIXME("D3DPROCESSVERTICES_NOCOLOR not implemented.\n"); diff --git a/dll/directx/wine/ddraw/surface.c b/dll/directx/wine/ddraw/surface.c index 74f2d15d271..abae18ba6cb 100644 --- a/dll/directx/wine/ddraw/surface.c +++ b/dll/directx/wine/ddraw/surface.c @@ -37,7 +37,6 @@ static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDra * to support windowless rendering first. */ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read) { - struct ddraw *ddraw = surface->ddraw; HDC surface_dc, screen_dc; int x, y, w, h; HRESULT hr; @@ -58,14 +57,14 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RE if (w <= 0 || h <= 0) return DD_OK; - if (ddraw->swapchain_window && !(ddraw->flags & DDRAW_GDI_FLIP)) + if (surface->ddraw->swapchain_window) { /* Nothing to do, we control the frontbuffer, or at least the parts we * care about. */ if (read) return DD_OK; - return wined3d_texture_blt(ddraw->wined3d_frontbuffer, 0, rect, + return wined3d_texture_blt(surface->ddraw->wined3d_frontbuffer, 0, rect, surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT); } @@ -204,7 +203,7 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface, { HRESULT hr; - if (FAILED(hr = d3d_device_create(This->ddraw, riid, This, (IUnknown *)&This->IDirectDrawSurface_iface, + if (FAILED(hr = d3d_device_create(This->ddraw, This, (IUnknown *)&This->IDirectDrawSurface_iface, 1, &This->device1, (IUnknown *)&This->IDirectDrawSurface_iface))) { This->device1 = NULL; @@ -5181,46 +5180,6 @@ static struct ddraw_surface *get_sub_mimaplevel(struct ddraw_surface *surface) return impl_from_IDirectDrawSurface7(next_level); } -static BOOL compare_format(DDPIXELFORMAT *format1, DDPIXELFORMAT *format2) -{ - if ((format1->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_FOURCC)) != - (format2->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_FOURCC))) - return FALSE; - - if (format1->dwFlags & (DDPF_RGB|DDPF_YUV)) - { - if (!(format1->dwFlags & DDPF_ALPHA)) - { - /* The RGB and YUV bits are stored in the same fields */ - if (format1->u1.dwRGBBitCount != format2->u1.dwRGBBitCount) - return FALSE; - - if (format1->u2.dwRBitMask != format2->u2.dwRBitMask) - return FALSE; - - if (format1->u3.dwGBitMask != format2->u3.dwGBitMask) - return FALSE; - - if (format1->u4.dwBBitMask != format2->u4.dwBBitMask) - return FALSE; - } - - if (format1->dwFlags & (DDPF_ALPHAPIXELS | DDPF_ALPHA)) - { - if (format1->u5.dwRGBAlphaBitMask != format2->u5.dwRGBAlphaBitMask) - return FALSE; - } - } - - if (format1->dwFlags & DDPF_FOURCC) - { - if (format1->dwFourCC != format2->dwFourCC) - return FALSE; - } - - return TRUE; -} - /***************************************************************************** * IDirect3DTexture2::Load * @@ -5242,7 +5201,7 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu { struct ddraw_surface *dst_surface = impl_from_IDirect3DTexture2(iface); struct ddraw_surface *src_surface = unsafe_impl_from_IDirect3DTexture2(src_texture); - RECT src_rect, dst_rect; + struct wined3d_resource *dst_resource, *src_resource; HRESULT hr; TRACE("iface %p, src_texture %p.\n", iface, src_texture); @@ -5255,60 +5214,90 @@ 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); + + if (((src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) + != (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) + || (src_surface->surface_desc.u2.dwMipMapCount != dst_surface->surface_desc.u2.dwMipMapCount)) + { + ERR("Trying to load surfaces with different mip-map counts.\n"); + } + for (;;) { - DDSURFACEDESC *src_desc = (DDSURFACEDESC *)&src_surface->surface_desc; + struct ddraw_palette *dst_pal, *src_pal; + DDSURFACEDESC *src_desc, *dst_desc; TRACE("Copying surface %p to surface %p.\n", src_surface, dst_surface); - if (compare_format(&src_surface->surface_desc.u4.ddpfPixelFormat, - &dst_surface->surface_desc.u4.ddpfPixelFormat)) - { - struct ddraw_palette *dst_pal, *src_pal; + /* Suppress the ALLOCONLOAD flag */ + dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; - /* Get the palettes */ - dst_pal = dst_surface->palette; - src_pal = src_surface->palette; + /* Get the palettes */ + dst_pal = dst_surface->palette; + src_pal = src_surface->palette; - if (src_pal) - { - PALETTEENTRY palent[256]; + if (src_pal) + { + PALETTEENTRY palent[256]; - if (!dst_pal) - { - wined3d_mutex_unlock(); - return DDERR_NOPALETTEATTACHED; - } - IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); - IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); + if (!dst_pal) + { + wined3d_mutex_unlock(); + return DDERR_NOPALETTEATTACHED; } + IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); + IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); + } + /* Copy one surface on the other */ + dst_desc = (DDSURFACEDESC *)&(dst_surface->surface_desc); + src_desc = (DDSURFACEDESC *)&(src_surface->surface_desc); + + if ((src_desc->dwWidth != dst_desc->dwWidth) || (src_desc->dwHeight != dst_desc->dwHeight)) + { + /* Should also check for same pixel format, u1.lPitch, ... */ + ERR("Error in surface sizes.\n"); + wined3d_mutex_unlock(); + return D3DERR_TEXTURE_LOAD_FAILED; + } + else + { + struct wined3d_map_desc src_map_desc, dst_map_desc; + + /* Copy the src blit color key if the source has one, don't erase + * the destination's ckey if the source has none */ if (src_desc->dwFlags & DDSD_CKSRCBLT) { IDirectDrawSurface7_SetColorKey(&dst_surface->IDirectDrawSurface7_iface, DDCKEY_SRCBLT, &src_desc->ddckCKSrcBlt); } - } - else - { - if (src_desc->dwFlags & DDSD_CKSRCBLT) - return E_FAIL; - } - /* Suppress the ALLOCONLOAD flag */ - dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; + if (FAILED(hr = wined3d_resource_map(src_resource, + src_surface->sub_resource_idx, &src_map_desc, NULL, 0))) + { + ERR("Failed to lock source surface, hr %#x.\n", hr); + wined3d_mutex_unlock(); + return D3DERR_TEXTURE_LOAD_FAILED; + } - SetRect(&src_rect, 0, 0, src_surface->surface_desc.dwWidth, src_surface->surface_desc.dwHeight); - SetRect(&dst_rect, 0, 0, dst_surface->surface_desc.dwWidth, dst_surface->surface_desc.dwHeight); + if (FAILED(hr = wined3d_resource_map(dst_resource, + dst_surface->sub_resource_idx, &dst_map_desc, NULL, 0))) + { + ERR("Failed to lock destination surface, hr %#x.\n", hr); + wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx); + wined3d_mutex_unlock(); + return D3DERR_TEXTURE_LOAD_FAILED; + } - hr = 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, - 0, NULL, WINED3D_TEXF_LINEAR); - if (FAILED(hr)) - { - ERR("Failed to blit surface, hr %#x.\n", hr); - wined3d_mutex_unlock(); - return hr; + if (dst_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) + memcpy(dst_map_desc.data, src_map_desc.data, src_surface->surface_desc.u1.dwLinearSize); + else + memcpy(dst_map_desc.data, src_map_desc.data, src_map_desc.row_pitch * src_desc->dwHeight); + + wined3d_resource_unmap(dst_resource, dst_surface->sub_resource_idx); + wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx); } if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) @@ -5321,11 +5310,12 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu else dst_surface = NULL; - if (src_surface && !dst_surface) - return DDERR_NOTFOUND; - if (!src_surface || !dst_surface) + { + if (src_surface != dst_surface) + ERR("Loading surface with different mipmap structure.\n"); break; + } } wined3d_mutex_unlock(); @@ -5555,7 +5545,7 @@ static const struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl = ddraw_surface2_PageUnlock, }; -static struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl = +static const struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl = { /* IUnknown */ ddraw_surface1_QueryInterface, @@ -6007,6 +5997,9 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ HeapFree(GetProcessHeap(), 0, texture); return hr_ddraw_from_wined3d(hr); } + + wined3d_device_set_render_state(ddraw->wined3d_device, WINED3D_RS_ZENABLE, + !!swapchain_desc.enable_auto_depth_stencil); } } @@ -6102,24 +6095,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) { - /* - * The ddraw RGB device allows to use system memory surfaces as rendering target. - * This does not cause problems because the RGB device does software rasterization - * though it will fail with hardware accelerated ddraw. In order to be partially - * compatible with games requesting explicitly the RGB device, we ignore the - * specified location and try to create rendering targets in video memory if - * possible. - */ - if ((desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && - SUCCEEDED(hr = wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, - WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_RENDERTARGET, - WINED3D_RTYPE_TEXTURE_2D, wined3d_desc.format))) - { - FIXME("Application wants to create rendering target in system memory, using video memory instead\n"); - wined3d_desc.usage |= WINED3DUSAGE_RENDERTARGET; - } - else - wined3d_desc.pool = WINED3D_POOL_SYSTEM_MEM; + wined3d_desc.pool = WINED3D_POOL_SYSTEM_MEM; } else { diff --git a/dll/directx/wine/ddraw/vertexbuffer.c b/dll/directx/wine/ddraw/vertexbuffer.c index 04d7adb94a7..155a8dd3ff8 100644 --- a/dll/directx/wine/ddraw/vertexbuffer.c +++ b/dll/directx/wine/ddraw/vertexbuffer.c @@ -159,6 +159,9 @@ static HRESULT WINAPI d3d_vertex_buffer7_Lock(IDirect3DVertexBuffer7 *iface, TRACE("iface %p, flags %#x, data %p, data_size %p.\n", iface, flags, data, data_size); + if (buffer->version != 7) + flags &= ~(DDLOCK_NOOVERWRITE | DDLOCK_DISCARDCONTENTS); + /* Writeonly: Pointless. Event: Unsupported by native according to the sdk * nosyslock: Not applicable */ @@ -246,7 +249,7 @@ static HRESULT WINAPI d3d_vertex_buffer7_Unlock(IDirect3DVertexBuffer7 *iface) * SrcIndex: Index of the first vertex in the src buffer to process * D3DDevice: Device to use for transformation * Flags: 0 for default, D3DPV_DONOTCOPYDATA to prevent copying - * unchaned vertices + * unchanged vertices * * Returns: * D3D_OK on success diff --git a/dll/directx/wine/ddraw/viewport.c b/dll/directx/wine/ddraw/viewport.c index 04eaa4b23a7..a62cc319ec8 100644 --- a/dll/directx/wine/ddraw/viewport.c +++ b/dll/directx/wine/ddraw/viewport.c @@ -1127,7 +1127,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport2(IDirect3DViewport2 *ifa /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */ if (!iface) return NULL; assert(iface->lpVtbl == (IDirect3DViewport2Vtbl *)&d3d_viewport_vtbl); - return CONTAINING_RECORD((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface); + return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface); } struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface) @@ -1135,7 +1135,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */ if (!iface) return NULL; assert(iface->lpVtbl == (IDirect3DViewportVtbl *)&d3d_viewport_vtbl); - return CONTAINING_RECORD((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface); + return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface); } void d3d_viewport_init(struct d3d_viewport *viewport, struct ddraw *ddraw) diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 375b675a93f..fb678a5a5e2 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -28,7 +28,7 @@ reactos/dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-2.16 reactos/dll/directx/wine/d3drm # Synced to WineStaging-2.16 reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-2.16 reactos/dll/directx/wine/d3dxof # Synced to WineStaging-2.9 -reactos/dll/directx/wine/ddraw # Synced to WineStaging-2.16 +reactos/dll/directx/wine/ddraw # Synced to Wine-3.0 reactos/dll/directx/wine/devenum # Synced to WineStaging-2.9 reactos/dll/directx/wine/dinput # Synced to WineStaging-2.16 reactos/dll/directx/wine/dinput8 # Synced to WineStaging-2.9 -- 2.17.1