This concludes the series.
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ddraw/tests/ddraw7.c | 303 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index d875afcfa16..80d7ff0a82d 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -20,6 +20,7 @@
#define COBJMACROS
+#include <stdbool.h> #include "wine/test.h" #include "wine/heap.h" #include <limits.h> @@ -50,6 +51,15 @@ struct vec4 float x, y, z, w; };
+struct ddraw_test_context +{ + HWND window; + IDirectDraw7 *ddraw; + IDirect3D7 *d3d; + IDirect3DDevice7 *device; + IDirectDrawSurface7 *backbuffer; +}; + struct create_window_thread_param { HWND window; @@ -112,6 +122,16 @@ static BOOL compare_mode_rect(const DEVMODEW *mode1, const DEVMODEW *mode2) && mode1->dmPelsHeight == mode2->dmPelsHeight; }
+static void init_format_b8g8r8x8(DDPIXELFORMAT *format) +{ + format->dwSize = sizeof(*format); + format->dwFlags = DDPF_RGB; + U1(*format).dwRGBBitCount = 32; + U2(*format).dwRBitMask = 0x00ff0000; + U3(*format).dwGBitMask = 0x0000ff00; + U4(*format).dwBBitMask = 0x000000ff; +} + static ULONG get_refcount(IUnknown *iface) { IUnknown_AddRef(iface); @@ -602,6 +622,53 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) return create_device_ex(window, coop_level, device_guid); }
+static bool init_3d_test_context_guid(struct ddraw_test_context *context, const GUID *device_guid) +{ + HRESULT hr; + + memset(context, 0, sizeof(*context)); + + context->window = create_window(); + if (!(context->device = create_device_ex(context->window, DDSCL_NORMAL, device_guid))) + { + skip("Failed to create a D3D device.\n"); + DestroyWindow(context->window); + return false; + } + + hr = IDirect3DDevice7_GetDirect3D(context->device, &context->d3d); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IDirect3D7_QueryInterface(context->d3d, &IID_IDirectDraw7, (void **)&context->ddraw); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IDirect3DDevice7_GetRenderTarget(context->device, &context->backbuffer); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + return true; +} + +#define release_test_context(a) release_test_context_(__LINE__, a) +static void release_test_context_(unsigned int line, struct ddraw_test_context *context) +{ + ULONG refcount; + + IDirectDrawSurface7_Release(context->backbuffer); + refcount = IDirect3DDevice7_Release(context->device); + ok_(__FILE__, line)(!refcount, "Device has %lu references left.\n", refcount); + IDirect3D7_Release(context->d3d); + refcount = IDirectDraw7_Release(context->ddraw); + ok_(__FILE__, line)(!refcount, "D3D object has %lu references left.\n", refcount); + DestroyWindow(context->window); +} + +static void clear_surface(IDirectDrawSurface7 *surface, unsigned int colour) +{ + DDBLTFX fx = {.dwSize = sizeof(fx)}; + HRESULT hr; + + U5(fx).dwFillColor = colour; + hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == S_OK, "Got hr %#lx.\n", hr); +} + struct message { UINT message; @@ -19549,10 +19616,245 @@ static void test_enum_devices(void) ok(!refcount, "Device has %lu references left.\n", refcount); }
+static void test_user_memory(const GUID *device_guid) +{ + IDirectDrawSurface7 *surfaces[6], *dst_surface; + struct ddraw_test_context context; + unsigned int i, color; + DDSURFACEDESC2 desc; + HRESULT hr; + void *mem; + RECT rect; + + static const struct + { + DWORD flags; + DWORD caps; + DWORD caps2; + HRESULT hr; + } + create_tests[] = + { + {0, DDSCAPS_MIPMAP, 0, S_OK}, + {0, DDSCAPS_MIPMAP | DDSCAPS_COMPLEX, 0, DDERR_INVALIDCAPS}, + {DDSD_MIPMAPCOUNT, DDSCAPS_MIPMAP | DDSCAPS_COMPLEX, 0, DDERR_INVALIDCAPS}, + {0, DDSCAPS_COMPLEX, DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES, DDERR_INVALIDCAPS}, + }; + + if (!init_3d_test_context_guid(&context, device_guid)) + { + winetest_pop_context(); + return; + } + + mem = malloc(16 * 16 * 5 * 4); + + reset_ddsd(&desc); + desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + desc.dwWidth = 16; + desc.dwHeight = 16; + desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE; + init_format_b8g8r8x8(&U4(desc).ddpfPixelFormat); + hr = IDirectDraw7_CreateSurface(context.ddraw, &desc, &dst_surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + /* Test creating and using a normal user memory surface. */ + + reset_ddsd(&desc); + desc.dwFlags = DDSD_WIDTH | DDSD_PITCH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LPSURFACE; + desc.dwWidth = 16; + U1(desc).lPitch = 16 * 4; + desc.dwHeight = 16; + desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY; + init_format_b8g8r8x8(&U4(desc).ddpfPixelFormat); + desc.lpSurface = mem; + hr = IDirectDraw7_CreateSurface(context.ddraw, &desc, &surfaces[0], NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + reset_ddsd(&desc); + hr = IDirectDrawSurface7_Lock(surfaces[0], NULL, &desc, DDLOCK_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(desc.lpSurface == mem, "Surface pointers didn't match.\n"); + memset(desc.lpSurface, 0x55, desc.dwHeight * U1(desc).lPitch); + hr = IDirectDrawSurface7_Unlock(surfaces[0], NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + /* Drawing from the user memory surface doesn't seem to work. + * Windows 10 WARP succeeds, but Windows 10 on real NVidia hardware fails in + * EndScene() with an undocumented error code 0x887602fb. */ + + clear_surface(dst_surface, 0x00999999); + SetRect(&rect, 0, 0, 16, 16); + hr = IDirectDrawSurface7_Blt(dst_surface, &rect, surfaces[0], &rect, DDBLT_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + color = get_surface_color(dst_surface, 1, 1); + ok(color == 0x00555555, "Got unexpected color 0x%08x.\n", color); + + IDirectDrawSurface7_Release(surfaces[0]); + + /* Creating a texture with DDSCAPS_MIPMAP and DDSD_LPSURFACE is legal, but + * such a texture isn't really mipmapped and only has one level. + * Trying to create a mipmapped texture with DDSD_COMPLEX, or a + * cubemap texture, fails if user memory is specified, even with a mipmap + * count of 1. */ + + for (i = 0; i < ARRAY_SIZE(create_tests); ++i) + { + reset_ddsd(&desc); + desc.dwFlags = DDSD_WIDTH | DDSD_PITCH | DDSD_HEIGHT | DDSD_CAPS + | DDSD_PIXELFORMAT | DDSD_LPSURFACE | create_tests[i].flags; + desc.dwWidth = 16; + U1(desc).lPitch = 16 * 4; + desc.dwHeight = 16; + desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | create_tests[i].caps; + desc.ddsCaps.dwCaps2 = create_tests[i].caps2; + init_format_b8g8r8x8(&U4(desc).ddpfPixelFormat); + U2(desc).dwMipMapCount = 1; + desc.lpSurface = mem; + hr = IDirectDraw7_CreateSurface(context.ddraw, &desc, &surfaces[0], NULL); + todo_wine_if (create_tests[i].caps & DDSCAPS_COMPLEX) + ok(hr == create_tests[i].hr, "Flags %#lx, caps %#lx: got hr %#lx.\n", + create_tests[i].flags, create_tests[i].caps, hr); + + if (hr == S_OK) + IDirectDrawSurface7_Release(surfaces[0]); + } + + /* Mipmap surfaces. */ + + reset_ddsd(&desc); + desc.dwFlags = DDSD_WIDTH | DDSD_PITCH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; + desc.dwWidth = 16; + U1(desc).lPitch = 16 * 4; + desc.dwHeight = 16; + desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX; + init_format_b8g8r8x8(&U4(desc).ddpfPixelFormat); + U2(desc).dwMipMapCount = 5; + hr = IDirectDraw7_CreateSurface(context.ddraw, &desc, &surfaces[0], NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + for (i = 0; i < 4; ++i) + { + DDSCAPS2 mip_caps = {.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL}; + + hr = IDirectDrawSurface7_GetAttachedSurface(surfaces[i], &mip_caps, &surfaces[i + 1]); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + + reset_ddsd(&desc); + desc.dwFlags = DDSD_LPSURFACE; + desc.lpSurface = mem; + hr = IDirectDrawSurface7_SetSurfaceDesc(surfaces[2], &desc, 0); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + for (i = 0; i < 5; ++i) + { + reset_ddsd(&desc); + hr = IDirectDrawSurface7_GetSurfaceDesc(surfaces[i], &desc); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(desc.dwWidth == (16u >> i), "Got width %lu.\n", desc.dwWidth); + + reset_ddsd(&desc); + hr = IDirectDrawSurface7_Lock(surfaces[i], NULL, &desc, DDLOCK_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (i == 2) + ok(desc.lpSurface == mem, "Got surface pointer %p.\n", desc.lpSurface); + memset(desc.lpSurface, 0x11 * (i + 1), desc.dwHeight * U1(desc).lPitch); + hr = IDirectDrawSurface7_Unlock(surfaces[i], NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + + for (i = 0; i < 5; ++i) + { + winetest_push_context("level %u", i); + + clear_surface(dst_surface, 0x00999999); + SetRect(&rect, 0, 0, (16u >> i), (16u >> i)); + hr = IDirectDrawSurface7_Blt(dst_surface, &rect, surfaces[i], &rect, DDBLT_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + color = get_surface_color(dst_surface, 0, 0); + ok(color == 0x00111111 * (i + 1), "Got unexpected color 0x%08x.\n", color); + + winetest_pop_context(); + } + + for (i = 0; i < 5; ++i) + IDirectDrawSurface7_Release(surfaces[4 - i]); + + /* Cube maps. */ + + reset_ddsd(&desc); + desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; + desc.dwWidth = 16; + U1(desc).lPitch = 16 * 4; + desc.dwHeight = 16; + desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX; + desc.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES; + init_format_b8g8r8x8(&U4(desc).ddpfPixelFormat); + hr = IDirectDraw7_CreateSurface(context.ddraw, &desc, &surfaces[0], NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + for (i = 0; i < 5; ++i) + { + DDSCAPS2 face_caps = {.dwCaps2 = DDSCAPS2_CUBEMAP | (DDSCAPS2_CUBEMAP_POSITIVEX << (i + 1))}; + + hr = IDirectDrawSurface7_GetAttachedSurface(surfaces[0], &face_caps, &surfaces[i + 1]); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + + reset_ddsd(&desc); + desc.dwFlags = DDSD_LPSURFACE; + desc.lpSurface = mem; + hr = IDirectDrawSurface7_SetSurfaceDesc(surfaces[2], &desc, 0); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + for (i = 0; i < 6; ++i) + { + reset_ddsd(&desc); + hr = IDirectDrawSurface7_GetSurfaceDesc(surfaces[i], &desc); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + reset_ddsd(&desc); + hr = IDirectDrawSurface7_Lock(surfaces[i], NULL, &desc, DDLOCK_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (i == 2) + ok(desc.lpSurface == mem, "Got surface pointer %p.\n", desc.lpSurface); + memset(desc.lpSurface, 0x11 * (i + 1), desc.dwHeight * U1(desc).lPitch); + hr = IDirectDrawSurface7_Unlock(surfaces[i], NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + + for (i = 0; i < 6; ++i) + { + winetest_push_context("face %u", i); + + clear_surface(dst_surface, 0x00999999); + SetRect(&rect, 0, 0, 16, 16); + hr = IDirectDrawSurface7_Blt(dst_surface, &rect, surfaces[i], &rect, DDBLT_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + color = get_surface_color(dst_surface, 0, 0); + ok(color == 0x00111111 * (i + 1), "Got unexpected color 0x%08x.\n", color); + + winetest_pop_context(); + } + + for (i = 0; i < 6; ++i) + IDirectDrawSurface7_Release(surfaces[5 - i]); + + free(mem); + + IDirectDrawSurface7_Release(dst_surface); + release_test_context(&context); +} + static void run_for_each_device_type(void (*test_func)(const GUID *)) { + winetest_push_context("Hardware device"); test_func(hw_device_guid); + winetest_pop_context(); + winetest_push_context("Software device"); test_func(&IID_IDirect3DRGBDevice); + winetest_pop_context(); }
START_TEST(ddraw7) @@ -19728,4 +20030,5 @@ START_TEST(ddraw7) run_for_each_device_type(test_texture_wrong_caps); test_filling_convention(); test_enum_devices(); + run_for_each_device_type(test_user_memory); }
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ddraw/surface.c | 2 +- dlls/wined3d/view.c | 6 ++++-- dlls/wined3d/wined3d.spec | 2 +- include/wine/wined3d.h | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index b75775cf252..9e283ac081f 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -1340,7 +1340,7 @@ static void ddraw_texture_rename_to(struct ddraw_texture *dst_texture, struct wi current_rtv = wined3d_device_context_get_rendertarget_view(dst_surface->ddraw->immediate_context, 0); if (current_rtv == dst_surface->wined3d_rtv) wined3d_device_context_set_rendertarget_views(dst_surface->ddraw->immediate_context, 0, 1, &rtv, FALSE); - wined3d_rendertarget_view_set_parent(rtv, dst_surface); + wined3d_rendertarget_view_set_parent(rtv, dst_surface, &ddraw_view_wined3d_parent_ops); dst_surface->wined3d_rtv = rtv;
if (dst_surface->sub_resource_idx) diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index 11f099b7ec5..9d62c4a5089 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -414,11 +414,13 @@ void * CDECL wined3d_rendertarget_view_get_sub_resource_parent(const struct wine return texture->sub_resources[view->sub_resource_idx].parent; }
-void CDECL wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, void *parent) +void CDECL wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, + void *parent, const struct wined3d_parent_ops *parent_ops) { - TRACE("view %p, parent %p.\n", view, parent); + TRACE("view %p, parent %p, parent_ops %p.\n", view, parent, parent_ops);
view->parent = parent; + view->parent_ops = parent_ops; }
struct wined3d_resource * CDECL wined3d_rendertarget_view_get_resource(const struct wined3d_rendertarget_view *view) diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 300fc2978da..8560c1a1bb6 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -188,7 +188,7 @@ @ cdecl wined3d_rendertarget_view_get_resource(ptr) @ cdecl wined3d_rendertarget_view_get_sub_resource_parent(ptr) @ cdecl wined3d_rendertarget_view_incref(ptr) -@ cdecl wined3d_rendertarget_view_set_parent(ptr ptr) +@ cdecl wined3d_rendertarget_view_set_parent(ptr ptr ptr)
@ cdecl wined3d_resource_get_desc(ptr ptr) @ cdecl wined3d_resource_get_parent(ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index ea4be6100f2..12f532b3ac2 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2695,7 +2695,8 @@ void * __cdecl wined3d_rendertarget_view_get_parent(const struct wined3d_rendert struct wined3d_resource * __cdecl wined3d_rendertarget_view_get_resource(const struct wined3d_rendertarget_view *view); void * __cdecl wined3d_rendertarget_view_get_sub_resource_parent(const struct wined3d_rendertarget_view *view); ULONG __cdecl wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view); -void __cdecl wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, void *parent); +void __cdecl wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, + void *parent, const struct wined3d_parent_ops *parent_ops);
HRESULT __cdecl wined3d_sampler_create(struct wined3d_device *device, const struct wined3d_sampler_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_sampler **sampler);
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ddraw/surface.c | 211 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 173 insertions(+), 38 deletions(-)
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 9e283ac081f..8a3f4224509 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -31,6 +31,7 @@ static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSur
static const struct wined3d_parent_ops ddraw_surface_wined3d_parent_ops; static const struct wined3d_parent_ops ddraw_texture_wined3d_parent_ops; +static const struct wined3d_parent_ops ddraw_view_wined3d_parent_ops;
static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDrawGammaControl *iface) { @@ -4665,13 +4666,43 @@ static HRESULT WINAPI ddraw_surface1_SetClipper(IDirectDrawSurface *iface, IDire return ddraw_surface7_SetClipper(&surface->IDirectDrawSurface7_iface, clipper); }
+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 void ddraw_surface_sync_color_keys(struct ddraw_surface *surface) +{ + const DDSURFACEDESC2 *desc = &surface->surface_desc; + + if (desc->dwFlags & DDSD_CKDESTOVERLAY) + ddraw_surface_set_wined3d_textures_colour_key(surface, DDCKEY_DESTOVERLAY, + (struct wined3d_color_key *)&desc->u3.ddckCKDestOverlay); + if (desc->dwFlags & DDSD_CKDESTBLT) + ddraw_surface_set_wined3d_textures_colour_key(surface, DDCKEY_DESTBLT, + (struct wined3d_color_key *)&desc->ddckCKDestBlt); + if (desc->dwFlags & DDSD_CKSRCOVERLAY) + ddraw_surface_set_wined3d_textures_colour_key(surface, DDCKEY_SRCOVERLAY, + (struct wined3d_color_key *)&desc->ddckCKSrcOverlay); + if (desc->dwFlags & DDSD_CKSRCBLT) + ddraw_surface_set_wined3d_textures_colour_key(surface, DDCKEY_SRCBLT, + (struct wined3d_color_key *)&desc->ddckCKSrcBlt); +} + static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, DDSURFACEDESC2 *DDSD, DWORD Flags) { struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface); + enum wined3d_format_id current_format_id, format_id; HRESULT hr; const DWORD allowed_flags = DDSD_LPSURFACE | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_CAPS; - enum wined3d_format_id format_id; UINT pitch, width, height;
TRACE("iface %p, surface_desc %p, flags %#lx.\n", iface, DDSD, Flags); @@ -4759,7 +4790,6 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, wined3d_mutex_lock(); if (DDSD->dwFlags & DDSD_PIXELFORMAT) { - enum wined3d_format_id current_format_id; format_id = wined3dformat_from_ddrawformat(&DDSD->u4.ddpfPixelFormat);
if (format_id == WINED3DFMT_UNKNOWN) @@ -4774,23 +4804,151 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, } else { - format_id = wined3dformat_from_ddrawformat(&surface->surface_desc.u4.ddpfPixelFormat); + current_format_id = format_id = wined3dformat_from_ddrawformat(&surface->surface_desc.u4.ddpfPixelFormat); }
- if (FAILED(hr = wined3d_texture_update_desc(surface->wined3d_texture, surface->sub_resource_idx, - width, height, format_id, WINED3D_MULTISAMPLE_NONE, 0, DDSD->lpSurface, pitch))) + if (width == surface->surface_desc.dwWidth && height == surface->surface_desc.dwHeight + && format_id == current_format_id) { - WARN("Failed to update surface desc, hr %#lx.\n", hr); - wined3d_mutex_unlock(); - return hr_ddraw_from_wined3d(hr); - } + /* Updating memory only. */
- 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))) + if (FAILED(hr = wined3d_texture_update_desc(surface->wined3d_texture, surface->sub_resource_idx, + width, height, format_id, WINED3D_MULTISAMPLE_NONE, 0, DDSD->lpSurface, pitch))) + { + WARN("Failed to update surface desc, hr %#lx.\n", hr); + wined3d_mutex_unlock(); + return hr_ddraw_from_wined3d(hr); + } + } + else { - ERR("Failed to update surface desc for draw_texture, hr %#lx.\n", hr); - wined3d_mutex_unlock(); - return hr_ddraw_from_wined3d(hr); + struct ddraw_texture *ddraw_texture = wined3d_texture_get_parent(surface->wined3d_texture); + struct wined3d_rendertarget_view *old_rtv = surface->wined3d_rtv; + struct wined3d_texture *old_draw_texture = surface->draw_texture; + struct wined3d_texture *old_texture = surface->wined3d_texture; + struct wined3d_texture *new_texture, *new_draw_texture = NULL; + struct wined3d_resource_desc wined3d_desc; + struct ddraw *ddraw = surface->ddraw; + + /* Updating surface attributes; recreate the texture. */ + + if (wined3d_texture_get_level_count(old_texture) > 1 + || (surface->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES)) + { + FIXME("Texture has multiple sub-resources, not supported.\n"); + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; + } + + /* Create the new textures. */ + + wined3d_resource_get_desc(wined3d_texture_get_resource(old_texture), &wined3d_desc); + + wined3d_desc.width = width; + wined3d_desc.width = height; + wined3d_desc.format = format_id; + + if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, 1, 1, + WINED3D_TEXTURE_CREATE_GET_DC_LENIENT, NULL, NULL, &ddraw_null_wined3d_parent_ops, &new_texture))) + { + ERR("Failed to create texture, hr %#lx.\n", hr); + wined3d_mutex_unlock(); + return hr_ddraw_from_wined3d(hr); + } + + if (FAILED(hr = wined3d_texture_update_desc(new_texture, 0, width, height, + format_id, WINED3D_MULTISAMPLE_NONE, 0, DDSD->lpSurface, pitch))) + { + ERR("Failed to set user memory, hr %#lx.\n", hr); + wined3d_texture_decref(new_texture); + wined3d_mutex_unlock(); + return hr_ddraw_from_wined3d(hr); + } + + if (old_draw_texture) + { + wined3d_resource_get_desc(wined3d_texture_get_resource(old_draw_texture), &wined3d_desc); + + wined3d_desc.width = width; + wined3d_desc.width = height; + wined3d_desc.format = format_id; + + if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, 1, 1, + 0, NULL, NULL, &ddraw_null_wined3d_parent_ops, &new_draw_texture))) + { + ERR("Failed to create draw texture, hr %#lx.\n", hr); + wined3d_texture_decref(new_texture); + wined3d_mutex_unlock(); + return hr_ddraw_from_wined3d(hr); + } + } + + wined3d_resource_set_parent(wined3d_texture_get_resource(old_texture), + NULL, &ddraw_null_wined3d_parent_ops); + wined3d_texture_set_sub_resource_parent(old_texture, 0, NULL, &ddraw_null_wined3d_parent_ops); + + if (surface->draw_texture) + { + wined3d_resource_set_parent(wined3d_texture_get_resource(old_draw_texture), + NULL, &ddraw_null_wined3d_parent_ops); + wined3d_texture_set_sub_resource_parent(old_draw_texture, 0, NULL, &ddraw_null_wined3d_parent_ops); + + wined3d_resource_set_parent(wined3d_texture_get_resource(new_draw_texture), + ddraw_texture, &ddraw_texture_wined3d_parent_ops); + wined3d_resource_set_parent(wined3d_texture_get_resource(new_texture), + ddraw_texture, &ddraw_null_wined3d_parent_ops); + + wined3d_texture_set_sub_resource_parent(new_draw_texture, 0, surface, &ddraw_surface_wined3d_parent_ops); + wined3d_texture_set_sub_resource_parent(new_texture, 0, surface, &ddraw_null_wined3d_parent_ops); + + wined3d_texture_decref(old_draw_texture); + } + else + { + wined3d_resource_set_parent(wined3d_texture_get_resource(new_texture), + ddraw_texture, &ddraw_texture_wined3d_parent_ops); + + wined3d_texture_set_sub_resource_parent(new_texture, 0, surface, &ddraw_surface_wined3d_parent_ops); + } + + surface->wined3d_texture = new_texture; + surface->draw_texture = new_draw_texture; + + wined3d_texture_decref(old_texture); + + /* Don't try to replace existing bound textures. Testing implies that + * SetSurfaceDesc() doesn't quite work with texture surfaces anyway: + * it succeeds, and mapping the surface does return the new user memory, + * but drawing from the surface doesn't actually sample from that + * memory. */ + + /* Destroy the existing RTV. */ + + if (old_rtv) + { + struct wined3d_rendertarget_view *current_rtv, *new_rtv; + + surface->wined3d_rtv = NULL; + + current_rtv = wined3d_device_context_get_rendertarget_view(ddraw->immediate_context, 0); + if (old_rtv == current_rtv) + { + new_rtv = ddraw_surface_get_rendertarget_view(surface); + wined3d_device_context_set_rendertarget_views(ddraw->immediate_context, 0, 1, &new_rtv, FALSE); + } + + wined3d_rendertarget_view_set_parent(old_rtv, NULL, &ddraw_null_wined3d_parent_ops); + wined3d_rendertarget_view_decref(old_rtv); + } + + ddraw_surface_sync_color_keys(surface); + + /* No need to sync the LOD or overlays; neither can be set on sysmem + * surfaces, and SetSurfaceDesc() can only be used on sysmem surfaces. + * + * No need to sync the palette either, since wined3d doesn't track it + * except on primary surfaces, and SetSurfaceDesc() is illegal on those + * too. */ }
if (DDSD->dwFlags & DDSD_WIDTH) @@ -4899,18 +5057,6 @@ 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; @@ -6330,18 +6476,7 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d
wined3d_device_incref(texture->wined3d_device = ddraw->wined3d_device);
- if (desc->dwFlags & DDSD_CKDESTOVERLAY) - ddraw_surface_set_wined3d_textures_colour_key(root, DDCKEY_DESTOVERLAY, - (struct wined3d_color_key *)&desc->u3.ddckCKDestOverlay); - if (desc->dwFlags & DDSD_CKDESTBLT) - ddraw_surface_set_wined3d_textures_colour_key(root, DDCKEY_DESTBLT, - (struct wined3d_color_key *)&desc->ddckCKDestBlt); - if (desc->dwFlags & DDSD_CKSRCOVERLAY) - ddraw_surface_set_wined3d_textures_colour_key(root, DDCKEY_SRCOVERLAY, - (struct wined3d_color_key *)&desc->ddckCKSrcOverlay); - if (desc->dwFlags & DDSD_CKSRCBLT) - ddraw_surface_set_wined3d_textures_colour_key(root, DDCKEY_SRCBLT, - (struct wined3d_color_key *)&desc->ddckCKSrcBlt); + ddraw_surface_sync_color_keys(root);
wined3d_texture_decref(wined3d_texture); if (draw_texture)
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=130949
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ddraw: ddraw7.c:19659: Test failed: Software device: Got hr 0x88760233. 02c4:ddraw7: unhandled exception c0000005 at 0053A418
=== w7u_adm (32 bit report) ===
ddraw: ddraw7.c:19659: Test failed: Software device: Got hr 0x88760233. 0874:ddraw7: unhandled exception c0000005 at 0053A418
=== w7u_el (32 bit report) ===
ddraw: ddraw7.c:19659: Test failed: Software device: Got hr 0x88760233. 0a74:ddraw7: unhandled exception c0000005 at 0053A418
=== w8 (32 bit report) ===
ddraw: ddraw7.c:19101: Test failed: Hardware device: Got unexpected color 0x00000040.
=== w864 (32 bit report) ===
ddraw: ddraw7.c:19101: Test failed: Hardware device: Got unexpected color 0x0000ff00.
=== w1064v1809 (32 bit report) ===
ddraw: ddraw7.c:19101: Test failed: Hardware device: Got unexpected color 0x00000040.
=== w11pro64 (32 bit report) ===
ddraw: ddraw7.c:19101: Test failed: Hardware device: Got unexpected color 0x00000040.