[PATCH 3/5] ddraw: Create back buffers in ddraw_surface_create_texture().

Henri Verbeet hverbeet at codeweavers.com
Wed Nov 27 04:04:50 CST 2013


---
 dlls/ddraw/ddraw.c   |   46 ---------------------------
 dlls/ddraw/surface.c |   85 ++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 69 insertions(+), 62 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 5f6d792..73fa17a 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 e127f72..e9f0d42 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;
+        /* 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)
+        {
+            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;
+            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;
+            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,
-- 
1.7.10.4




More information about the wine-patches mailing list