[PATCH 1/5] ddraw: Implement width and height changes in ddraw_surface7_SetSurfaceDesc().

Henri Verbeet hverbeet at codeweavers.com
Thu Jan 12 14:43:08 CST 2012


---
 dlls/ddraw/surface.c        |   66 +++++++++++++++++++++++++++++--------
 dlls/ddraw/tests/dsurface.c |    8 ++--
 dlls/wined3d/device.c       |   75 +++++-------------------------------------
 dlls/wined3d/surface.c      |   64 ++++++++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d.spec   |    1 +
 include/wine/wined3d.h      |    3 ++
 6 files changed, 133 insertions(+), 84 deletions(-)

diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 0d6e398..dec5612 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -4122,10 +4122,12 @@ static HRESULT WINAPI ddraw_surface1_SetClipper(IDirectDrawSurface *iface, IDire
 static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, DDSURFACEDESC2 *DDSD, DWORD Flags)
 {
     IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface);
-    enum wined3d_format_id newFormat = WINED3DFMT_UNKNOWN;
     HRESULT hr;
     const DWORD allowed_flags = DDSD_LPSURFACE | DDSD_PIXELFORMAT | DDSD_WIDTH
             | DDSD_HEIGHT | DDSD_PITCH | DDSD_CAPS;
+    enum wined3d_format_id format_id;
+    BOOL update_wined3d = FALSE;
+    UINT width, height;
 
     TRACE("iface %p, surface_desc %p, flags %#x.\n", iface, DDSD, Flags);
 
@@ -4177,18 +4179,26 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface,
         }
         if (DDSD->dwWidth != This->surface_desc.dwWidth)
         {
-            FIXME("Surface width changed from %u to %u.\n", This->surface_desc.dwWidth, DDSD->dwWidth);
+            TRACE("Surface width changed from %u to %u.\n", This->surface_desc.dwWidth, DDSD->dwWidth);
+            update_wined3d = TRUE;
         }
         if (DDSD->u1.lPitch != This->surface_desc.u1.lPitch)
         {
-            FIXME("Surface pitch changed from %u to %u.\n", This->surface_desc.u1.lPitch, DDSD->u1.lPitch);
+            TRACE("Surface pitch changed from %u to %u.\n", This->surface_desc.u1.lPitch, DDSD->u1.lPitch);
+            update_wined3d = TRUE;
         }
+        width = DDSD->dwWidth;
     }
     else if (DDSD->dwFlags & DDSD_PITCH)
     {
         WARN("DDSD_PITCH is set, but DDSD_WIDTH is not, returning DDERR_INVALIDPARAMS.\n");
         return DDERR_INVALIDPARAMS;
     }
+    else
+    {
+        width = This->surface_desc.dwWidth;
+    }
+
     if (DDSD->dwFlags & DDSD_HEIGHT)
     {
         if (!DDSD->dwHeight)
@@ -4198,32 +4208,60 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface,
         }
         if (DDSD->dwHeight != This->surface_desc.dwHeight)
         {
-            FIXME("Surface height changed from %u to %u.\n", This->surface_desc.dwHeight, DDSD->dwHeight);
+            TRACE("Surface height changed from %u to %u.\n", This->surface_desc.dwHeight, DDSD->dwHeight);
+            update_wined3d = TRUE;
         }
+        height = DDSD->dwHeight;
+    }
+    else
+    {
+        height = This->surface_desc.dwHeight;
     }
 
     wined3d_mutex_lock();
     if (DDSD->dwFlags & DDSD_PIXELFORMAT)
     {
-        newFormat = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat);
+        enum wined3d_format_id current_format_id;
+        format_id = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat);
 
-        if(newFormat == WINED3DFMT_UNKNOWN)
+        if (format_id == WINED3DFMT_UNKNOWN)
         {
             ERR("Requested to set an unknown pixelformat\n");
             wined3d_mutex_unlock();
             return DDERR_INVALIDPARAMS;
         }
-        if(newFormat != PixelFormat_DD2WineD3D(&This->surface_desc.u4.ddpfPixelFormat) )
+        current_format_id = PixelFormat_DD2WineD3D(&This->surface_desc.u4.ddpfPixelFormat);
+        if (format_id != current_format_id)
         {
-            hr = wined3d_surface_set_format(This->wined3d_surface, newFormat);
-            if (FAILED(hr))
-            {
-                wined3d_mutex_unlock();
-                return hr;
-            }
-            This->surface_desc.u4.ddpfPixelFormat = DDSD->u4.ddpfPixelFormat;
+            TRACE("Surface format changed from %#x to %#x.\n", current_format_id, format_id);
+            update_wined3d = TRUE;
         }
     }
+    else
+    {
+        format_id = PixelFormat_DD2WineD3D(&This->surface_desc.u4.ddpfPixelFormat);
+    }
+
+    if (update_wined3d)
+    {
+        if (FAILED(hr = wined3d_surface_update_desc(This->wined3d_surface, width, height,
+                format_id, WINED3D_MULTISAMPLE_NONE, 0)))
+        {
+            WARN("Failed to update surface desc, hr %#x.\n", hr);
+            wined3d_mutex_unlock();
+            return hr;
+        }
+
+        if (DDSD->dwFlags & DDSD_WIDTH)
+            This->surface_desc.dwWidth = width;
+        if (DDSD->dwFlags & DDSD_PITCH)
+            This->surface_desc.u1.lPitch = DDSD->u1.lPitch;
+        if (DDSD->dwFlags & DDSD_HEIGHT)
+            This->surface_desc.dwHeight = height;
+        if (DDSD->dwFlags & DDSD_PIXELFORMAT)
+            This->surface_desc.u4.ddpfPixelFormat = DDSD->u4.ddpfPixelFormat;
+    }
+
     if (DDSD->dwFlags & DDSD_LPSURFACE && DDSD->lpSurface)
     {
         hr = wined3d_surface_set_mem(This->wined3d_surface, DDSD->lpSurface);
diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c
index 32af27e..85a5d7a 100644
--- a/dlls/ddraw/tests/dsurface.c
+++ b/dlls/ddraw/tests/dsurface.c
@@ -4580,7 +4580,7 @@ static void set_surface_desc_test(void)
     hr = IDirectDrawSurface3_GetSurfaceDesc(surface3, &ddsd);
     ok(SUCCEEDED(hr), "GetSurfaceDesc failed, hr %#x.\n", hr);
     ok(ddsd.dwWidth == 8, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd.dwWidth);
-    todo_wine ok(ddsd.dwHeight == 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd.dwHeight);
+    ok(ddsd.dwHeight == 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd.dwHeight);
 
     /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0 */
     reset_ddsd(&ddsd);
@@ -4612,9 +4612,9 @@ static void set_surface_desc_test(void)
     reset_ddsd(&ddsd);
     hr = IDirectDrawSurface3_GetSurfaceDesc(surface3, &ddsd);
     ok(SUCCEEDED(hr), "GetSurfaceDesc failed, hr %#x.\n", hr);
-    todo_wine ok(ddsd.dwWidth == 16, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd.dwWidth);
-    todo_wine ok(ddsd.dwHeight == 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd.dwHeight);
-    todo_wine ok(U1(ddsd).lPitch == 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %u.\n", U1(ddsd).lPitch);
+    ok(ddsd.dwWidth == 16, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd.dwWidth);
+    ok(ddsd.dwHeight == 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd.dwHeight);
+    ok(U1(ddsd).lPitch == 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %u.\n", U1(ddsd).lPitch);
 
     /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise
      *
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 1e60439..c0dcd7b 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5198,69 +5198,6 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device)
     device_invalidate_state(device, STATE_STREAMSRC);
 }
 
-static HRESULT updateSurfaceDesc(struct wined3d_surface *surface,
-        const struct wined3d_swapchain_desc *swapchain_desc)
-{
-    struct wined3d_device *device = surface->resource.device;
-    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
-
-    /* Reallocate proper memory for the front and back buffer and adjust their sizes */
-    if (surface->flags & SFLAG_DIBSECTION)
-    {
-        DeleteDC(surface->hDC);
-        DeleteObject(surface->dib.DIBsection);
-        surface->dib.bitmap_data = NULL;
-        surface->resource.allocatedMemory = NULL;
-        surface->flags &= ~SFLAG_DIBSECTION;
-    }
-    surface->resource.width = swapchain_desc->backbuffer_width;
-    surface->resource.height = swapchain_desc->backbuffer_height;
-    if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] || gl_info->supported[ARB_TEXTURE_RECTANGLE]
-            || gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
-    {
-        surface->pow2Width = swapchain_desc->backbuffer_width;
-        surface->pow2Height = swapchain_desc->backbuffer_height;
-    }
-    else
-    {
-        surface->pow2Width = surface->pow2Height = 1;
-        while (surface->pow2Width < swapchain_desc->backbuffer_width)
-            surface->pow2Width <<= 1;
-        while (surface->pow2Height < swapchain_desc->backbuffer_height)
-            surface->pow2Height <<= 1;
-    }
-
-    if (!(surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
-        surface->resource.format = wined3d_get_format(gl_info, swapchain_desc->backbuffer_format);
-    surface->resource.multisample_type = swapchain_desc->multisample_type;
-    surface->resource.multisample_quality = swapchain_desc->multisample_quality;
-
-    if (device->d3d_initialized)
-        surface->resource.resource_ops->resource_unload(&surface->resource);
-
-    if (surface->pow2Width != swapchain_desc->backbuffer_width
-            || surface->pow2Height != swapchain_desc->backbuffer_height)
-    {
-        surface->flags |= SFLAG_NONPOW2;
-    }
-    else
-    {
-        surface->flags &= ~SFLAG_NONPOW2;
-    }
-    HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
-    surface->resource.allocatedMemory = NULL;
-    surface->resource.heapMemory = NULL;
-    surface->resource.size = wined3d_surface_get_pitch(surface) * surface->pow2Width;
-
-    /* Put all surfaces into sysmem - the drawable might disappear if the backbuffer was rendered
-     * to a FBO */
-    if (!surface_init_sysmem(surface))
-    {
-        return E_OUTOFMEMORY;
-    }
-    return WINED3D_OK;
-}
-
 static BOOL is_display_mode_supported(const struct wined3d_device *device,
         const struct wined3d_swapchain_desc *swapchain_desc)
 {
@@ -5578,7 +5515,9 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
     {
         UINT i;
 
-        hr = updateSurfaceDesc(swapchain->front_buffer, &swapchain->desc);
+        hr = wined3d_surface_update_desc(swapchain->front_buffer, swapchain->desc.backbuffer_width,
+                swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
+                swapchain->desc.multisample_type, swapchain->desc.multisample_quality);
         if (FAILED(hr))
         {
             wined3d_swapchain_decref(swapchain);
@@ -5587,7 +5526,9 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
 
         for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
         {
-            hr = updateSurfaceDesc(swapchain->back_buffers[i], &swapchain->desc);
+            hr = wined3d_surface_update_desc(swapchain->back_buffers[i], swapchain->desc.backbuffer_width,
+                    swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
+                    swapchain->desc.multisample_type, swapchain->desc.multisample_quality);
             if (FAILED(hr))
             {
                 wined3d_swapchain_decref(swapchain);
@@ -5596,7 +5537,9 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         }
         if (device->auto_depth_stencil)
         {
-            hr = updateSurfaceDesc(device->auto_depth_stencil, &swapchain->desc);
+            hr = wined3d_surface_update_desc(device->auto_depth_stencil, swapchain->desc.backbuffer_width,
+                    swapchain->desc.backbuffer_height, device->auto_depth_stencil->resource.format->id,
+                    swapchain->desc.multisample_type, swapchain->desc.multisample_quality);
             if (FAILED(hr))
             {
                 wined3d_swapchain_decref(swapchain);
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index bf379f1..63f49fb 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -3313,6 +3313,70 @@ HRESULT CDECL wined3d_surface_update_overlay(struct wined3d_surface *surface, co
     return WINED3D_OK;
 }
 
+HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface,
+        UINT width, UINT height, enum wined3d_format_id format_id,
+        enum wined3d_multisample_type multisample_type, UINT multisample_quality)
+{
+    struct wined3d_device *device = surface->resource.device;
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
+    UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height);
+
+    TRACE("surface %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u.\n",
+            surface, width, height, debug_d3dformat(format_id), multisample_type, multisample_type);
+
+    if (!resource_size)
+        return WINED3DERR_INVALIDCALL;
+
+    if (device->d3d_initialized)
+        surface->resource.resource_ops->resource_unload(&surface->resource);
+
+    if (surface->flags & SFLAG_DIBSECTION)
+    {
+        DeleteDC(surface->hDC);
+        DeleteObject(surface->dib.DIBsection);
+        surface->dib.bitmap_data = NULL;
+        surface->flags &= ~SFLAG_DIBSECTION;
+    }
+
+    surface->flags &= ~(SFLAG_LOCATIONS | SFLAG_USERPTR);
+    surface->resource.allocatedMemory = NULL;
+    HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
+    surface->resource.heapMemory = NULL;
+
+    surface->resource.width = width;
+    surface->resource.height = height;
+    if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] || gl_info->supported[ARB_TEXTURE_RECTANGLE]
+            || gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
+    {
+        surface->pow2Width = width;
+        surface->pow2Height = height;
+    }
+    else
+    {
+        surface->pow2Width = surface->pow2Height = 1;
+        while (surface->pow2Width < width)
+            surface->pow2Width <<= 1;
+        while (surface->pow2Height < height)
+            surface->pow2Height <<= 1;
+    }
+
+    if (surface->pow2Width != width || surface->pow2Height != height)
+        surface->flags |= SFLAG_NONPOW2;
+    else
+        surface->flags &= ~SFLAG_NONPOW2;
+
+    surface->resource.format = format;
+    surface->resource.multisample_type = multisample_type;
+    surface->resource.multisample_quality = multisample_quality;
+    surface->resource.size = resource_size;
+
+    if (!surface_init_sysmem(surface))
+        return E_OUTOFMEMORY;
+
+    return WINED3D_OK;
+}
+
 HRESULT CDECL wined3d_surface_set_format(struct wined3d_surface *surface, enum wined3d_format_id format_id)
 {
     const struct wined3d_format *format = wined3d_get_format(&surface->resource.device->adapter->gl_info, format_id);
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 0b25f7c..8279aa6 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -217,6 +217,7 @@
 @ cdecl wined3d_surface_set_palette(ptr ptr)
 @ cdecl wined3d_surface_set_priority(ptr long)
 @ cdecl wined3d_surface_unmap(ptr)
+@ cdecl wined3d_surface_update_desc(ptr long long long long long)
 @ cdecl wined3d_surface_update_overlay(ptr ptr ptr ptr long ptr)
 @ cdecl wined3d_surface_update_overlay_z_order(ptr long ptr)
 
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 5366c18..b423dd8 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2334,6 +2334,9 @@ HRESULT __cdecl wined3d_surface_set_overlay_position(struct wined3d_surface *sur
 HRESULT __cdecl wined3d_surface_set_palette(struct wined3d_surface *surface, struct wined3d_palette *palette);
 DWORD __cdecl wined3d_surface_set_priority(struct wined3d_surface *surface, DWORD new_priority);
 HRESULT __cdecl wined3d_surface_unmap(struct wined3d_surface *surface);
+HRESULT __cdecl wined3d_surface_update_desc(struct wined3d_surface *surface,
+        UINT width, UINT height, enum wined3d_format_id format_id,
+        enum wined3d_multisample_type multisample_type, UINT multisample_quality);
 HRESULT __cdecl wined3d_surface_update_overlay(struct wined3d_surface *surface, const RECT *src_rect,
         struct wined3d_surface *dst_surface, const RECT *dst_rect, DWORD flags, const WINEDDOVERLAYFX *fx);
 HRESULT __cdecl wined3d_surface_update_overlay_z_order(struct wined3d_surface *surface,
-- 
1.7.3.4




More information about the wine-patches mailing list