diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 5f6d792b239..73fa17a62f7 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -2872,10 +2872,6 @@ static HRESULT CreateSurface(struct ddraw *ddraw, DDSURFACEDESC2 *DDSD, /* Modify some flags */ copy_to_surfacedesc2(&desc2, DDSD); - /* The first surface is a front buffer, the back buffer is created afterwards */ - if (desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - desc2.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER; - if (FAILED(hr = ddraw_surface_create_texture(ddraw, &desc2, version, &object))) { WARN("Failed to create texture, hr %#x.\n", hr); @@ -2885,48 +2881,6 @@ static HRESULT CreateSurface(struct ddraw *ddraw, DDSURFACEDESC2 *DDSD, *surface = object; - /* Create Additional surfaces if necessary - * This applies to Primary surfaces which have a back buffer count - * set, but not to mipmap textures. In case of Mipmap textures, - * wineD3D takes care of the creation of additional surfaces - */ - if(DDSD->dwFlags & DDSD_BACKBUFFERCOUNT) - { - struct ddraw_surface *last = object; - UINT i; - - desc2.ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER; /* It's not a front buffer */ - desc2.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; - desc2.dwBackBufferCount = 0; - - for (i = 0; i < DDSD->dwBackBufferCount; ++i) - { - struct ddraw_surface *object2 = NULL; - - if (FAILED(hr = ddraw_surface_create_texture(ddraw, &desc2, version, &object2))) - { - if (version == 7) - IDirectDrawSurface7_Release(&object->IDirectDrawSurface7_iface); - else if (version == 4) - IDirectDrawSurface4_Release(&object->IDirectDrawSurface4_iface); - else - IDirectDrawSurface_Release(&object->IDirectDrawSurface_iface); - - return hr; - } - - /* Add the new surface to the complex attachment array. */ - last->complex_array[0] = object2; - last = object2; - - /* Remove the (possible) back buffer cap from the new surface - * description, because only one surface in the flipping chain is a - * back buffer, one is a front buffer, the others are just primary - * surfaces. */ - desc2.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; - } - } - if (desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) ddraw->primary = object; diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index e127f72f613..e9f0d42563d 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -5687,22 +5687,26 @@ HRESULT ddraw_surface_create_texture(struct ddraw *ddraw, DDSURFACEDESC2 *desc, if (!desc->dwWidth || !desc->dwHeight) return DDERR_INVALIDPARAMS; - if ((desc->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER)) - == (DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER) - && (ddraw->cooperative_level & DDSCL_EXCLUSIVE)) + if (desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { - struct wined3d_swapchain_desc swapchain_desc; - - wined3d_swapchain_get_desc(ddraw->wined3d_swapchain, &swapchain_desc); - swapchain_desc.backbuffer_width = mode.width; - swapchain_desc.backbuffer_height = mode.height; - swapchain_desc.backbuffer_format = mode.format_id; - - if (FAILED(hr = wined3d_device_reset(ddraw->wined3d_device, - &swapchain_desc, NULL, ddraw_reset_enum_callback, TRUE))) + /* The first surface is a front buffer, the back buffers are created + * afterwards. */ + desc->ddsCaps.dwCaps |= DDSCAPS_VISIBLE | DDSCAPS_FRONTBUFFER; + if (ddraw->cooperative_level & DDSCL_EXCLUSIVE) { - ERR("Failed to reset device.\n"); - return hr; + struct wined3d_swapchain_desc swapchain_desc; + + wined3d_swapchain_get_desc(ddraw->wined3d_swapchain, &swapchain_desc); + swapchain_desc.backbuffer_width = mode.width; + swapchain_desc.backbuffer_height = mode.height; + swapchain_desc.backbuffer_format = mode.format_id; + + if (FAILED(hr = wined3d_device_reset(ddraw->wined3d_device, + &swapchain_desc, NULL, ddraw_reset_enum_callback, TRUE))) + { + ERR("Failed to reset device.\n"); + return hr; + } } } @@ -5792,9 +5796,6 @@ HRESULT ddraw_surface_create_texture(struct ddraw *ddraw, DDSURFACEDESC2 *desc, } } - if (desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - desc->ddsCaps.dwCaps |= DDSCAPS_VISIBLE; - if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) { wined3d_desc.pool = WINED3D_POOL_SYSTEM_MEM; @@ -5926,9 +5927,61 @@ HRESULT ddraw_surface_create_texture(struct ddraw *ddraw, DDSURFACEDESC2 *desc, } } + if (desc->dwFlags & DDSD_BACKBUFFERCOUNT) + { + unsigned int count = desc->dwBackBufferCount; + struct ddraw_surface *last = root; + + attach = &last->complex_array[0]; + for (i = 0; i < count; ++i) + { + if (!(texture = HeapAlloc(GetProcessHeap(), 0, sizeof(*texture)))) + { + hr = E_OUTOFMEMORY; + goto fail; + } + + texture->version = version; + texture->surface_desc = root->surface_desc; + desc = &texture->surface_desc; + + /* Only one surface in the flipping chain is a back buffer, one is + * a front buffer, the others are just primary surfaces. */ + desc->ddsCaps.dwCaps &= ~(DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER); + if (!i) + desc->ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; + desc->dwBackBufferCount = 0; + + if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, 1, + WINED3D_SURFACE_PIN_SYSMEM, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) + { + HeapFree(GetProcessHeap(), 0, texture); + goto fail; + } + + resource = wined3d_texture_get_sub_resource(wined3d_texture, 0); + last = wined3d_resource_get_parent(resource); + last->wined3d_texture = wined3d_texture; + texture->root = last; + + *attach = last; + attach = &last->complex_array[0]; + } + } + *surface = root; return DD_OK; + +fail: + if (version == 7) + IDirectDrawSurface7_Release(&root->IDirectDrawSurface7_iface); + else if (version == 4) + IDirectDrawSurface4_Release(&root->IDirectDrawSurface4_iface); + else + IDirectDrawSurface_Release(&root->IDirectDrawSurface_iface); + + return hr; } HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture,