[PATCH 3/5] ddraw: Keep the primary surface mapped at the same address for early ddraw versions.

Henri Verbeet hverbeet at codeweavers.com
Tue Nov 29 23:01:46 CST 2011


---
 dlls/ddraw/surface.c           |   10 +++++++++-
 dlls/wined3d/surface.c         |    4 +++-
 dlls/wined3d/wined3d_private.h |    4 +++-
 include/wine/wined3d.h         |    1 +
 4 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 05d9b2b..9bd6774 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -5254,6 +5254,7 @@ HRESULT ddraw_surface_init(IDirectDrawSurfaceImpl *surface, IDirectDrawImpl *ddr
         DDSURFACEDESC2 *desc, UINT mip_level, UINT version)
 {
     WINED3DPOOL pool = WINED3DPOOL_DEFAULT;
+    DWORD flags = WINED3D_SURFACE_MAPPABLE;
     enum wined3d_format_id format;
     DWORD usage = 0;
     HRESULT hr;
@@ -5269,6 +5270,13 @@ HRESULT ddraw_surface_init(IDirectDrawSurfaceImpl *surface, IDirectDrawImpl *ddr
 
     if (desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
     {
+        /* Some applications assume that the primary surface will always be
+         * mapped at the same address. Some of those also assume that this
+         * address is valid even when the surface isn't mapped, and that
+         * updates done this way will be visible on the screen. The game Nox
+         * is such an application. */
+        if (version == 1)
+            flags |= WINED3D_SURFACE_PIN_SYSMEM;
         usage |= WINED3DUSAGE_RENDERTARGET;
         desc->ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
     }
@@ -5343,7 +5351,7 @@ HRESULT ddraw_surface_init(IDirectDrawSurfaceImpl *surface, IDirectDrawImpl *ddr
     surface->first_attached = surface;
 
     hr = wined3d_surface_create(ddraw->wined3d_device, desc->dwWidth, desc->dwHeight, format, mip_level,
-            usage, pool, WINED3DMULTISAMPLE_NONE, 0, DefaultSurfaceType, WINED3D_SURFACE_MAPPABLE,
+            usage, pool, WINED3DMULTISAMPLE_NONE, 0, DefaultSurfaceType, flags,
             surface, &ddraw_surface_wined3d_parent_ops, &surface->wined3d_surface);
     if (FAILED(hr))
     {
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 4110345..5ec4daa 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -544,7 +544,7 @@ static void surface_prepare_system_memory(struct wined3d_surface *surface)
      * converted or NPOT surfaces. Also don't create a PBO for systemmem
      * surfaces. */
     if (gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] && (surface->flags & SFLAG_DYNLOCK)
-            && !(surface->flags & (SFLAG_PBO | SFLAG_CONVERTED | SFLAG_NONPOW2))
+            && !(surface->flags & (SFLAG_PBO | SFLAG_CONVERTED | SFLAG_NONPOW2 | SFLAG_PIN_SYSMEM))
             && (surface->resource.pool != WINED3DPOOL_SYSTEMMEM))
     {
         struct wined3d_context *context;
@@ -7186,6 +7186,8 @@ static HRESULT surface_init(struct wined3d_surface *surface, WINED3DSURFTYPE sur
     surface->flags = SFLAG_NORMCOORD; /* Default to normalized coords. */
     if (flags & WINED3D_SURFACE_DISCARD)
         surface->flags |= SFLAG_DISCARD;
+    if (flags & WINED3D_SURFACE_PIN_SYSMEM)
+        surface->flags |= SFLAG_PIN_SYSMEM;
     if (lockable || format_id == WINED3DFMT_D16_LOCKABLE)
         surface->flags |= SFLAG_LOCKABLE;
     /* I'm not sure if this qualifies as a hack or as an optimization. It
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e524c3d..41e1388 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2140,6 +2140,7 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D
 #define SFLAG_INRB_RESOLVED     0x00400000 /* The resolved renderbuffer is current. */
 #define SFLAG_DS_ONSCREEN       0x00800000 /* This is a depth / stencil surface, last modified onscreen. */
 #define SFLAG_DS_OFFSCREEN      0x01000000 /* This is a depth / stencil surface, last modified offscreen. */
+#define SFLAG_PIN_SYSMEM        0x02000000 /* Keep the surface in sysmem, at the same address. */
 
 /* In some conditions the surface memory must not be freed:
  * SFLAG_CONVERTED: Converting the data back would take too long
@@ -2155,7 +2156,8 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D
                              SFLAG_CLIENT           | \
                              SFLAG_DIBSECTION       | \
                              SFLAG_USERPTR          | \
-                             SFLAG_PBO)
+                             SFLAG_PBO              | \
+                             SFLAG_PIN_SYSMEM)
 
 #define SFLAG_LOCATIONS     (SFLAG_INSYSMEM         | \
                              SFLAG_INTEXTURE        | \
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 2f68f14..c79137e 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -1511,6 +1511,7 @@ enum wined3d_sysval_semantic
 
 #define WINED3D_SURFACE_MAPPABLE                                0x00000001
 #define WINED3D_SURFACE_DISCARD                                 0x00000002
+#define WINED3D_SURFACE_PIN_SYSMEM                              0x00000004
 
 struct wined3d_display_mode
 {
-- 
1.7.3.4




More information about the wine-patches mailing list