Stefan Dösinger : wined3d: Add a function for initializing surface sysmem.

Alexandre Julliard julliard at winehq.org
Mon Dec 7 10:26:18 CST 2009


Module: wine
Branch: master
Commit: 54f0d3f785f4e9390fc3f47ca6e750513225d3a3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=54f0d3f785f4e9390fc3f47ca6e750513225d3a3

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Fri Dec  4 13:07:18 2009 +0100

wined3d: Add a function for initializing surface sysmem.

---

 dlls/wined3d/device.c          |   36 +++++++++++++++++++++++++++---------
 dlls/wined3d/surface.c         |   40 +++++++++++++++++++++++++++++-----------
 dlls/wined3d/wined3d_private.h |    1 +
 3 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index cefabea..6ac60f1 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -6514,7 +6514,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_EvictManagedResources(IWineD3DDevice*
     return WINED3D_OK;
 }
 
-static void updateSurfaceDesc(IWineD3DSurfaceImpl *surface, const WINED3DPRESENT_PARAMETERS* pPresentationParameters)
+static HRESULT updateSurfaceDesc(IWineD3DSurfaceImpl *surface, const WINED3DPRESENT_PARAMETERS* pPresentationParameters)
 {
     IWineD3DDeviceImpl *device = surface->resource.wineD3DDevice;
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
@@ -6567,12 +6567,14 @@ static void updateSurfaceDesc(IWineD3DSurfaceImpl *surface, const WINED3DPRESENT
     surface->resource.allocatedMemory = NULL;
     surface->resource.heapMemory = NULL;
     surface->resource.size = IWineD3DSurface_GetPitch((IWineD3DSurface *) surface) * surface->pow2Width;
-    /* INDRAWABLE is a sane place for implicit targets after the reset, INSYSMEM is more appropriate for depth stencils. */
-    if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) {
-        IWineD3DSurface_ModifyLocation((IWineD3DSurface *) surface, SFLAG_INSYSMEM, TRUE);
-    } else {
-        IWineD3DSurface_ModifyLocation((IWineD3DSurface *) surface, SFLAG_INDRAWABLE, TRUE);
+
+    /* Put all surfaces into sysmem - the drawable might disappear if the backbuffer was rendered
+     * to a FBO */
+    if(!surface_init_sysmem((IWineD3DSurface *) surface))
+    {
+        return E_OUTOFMEMORY;
     }
+    return WINED3D_OK;
 }
 
 static HRESULT WINAPI reset_unload_resources(IWineD3DResource *resource, void *data) {
@@ -6830,12 +6832,28 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
         swapchain->presentParms.BackBufferWidth = pPresentationParameters->BackBufferWidth;
         swapchain->presentParms.BackBufferHeight = pPresentationParameters->BackBufferHeight;
 
-        updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->frontBuffer, pPresentationParameters);
+        hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->frontBuffer, pPresentationParameters);
+        if(FAILED(hr))
+        {
+            IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
+            return hr;
+        }
+
         for(i = 0; i < swapchain->presentParms.BackBufferCount; i++) {
-            updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->backBuffer[i], pPresentationParameters);
+            hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->backBuffer[i], pPresentationParameters);
+            if(FAILED(hr))
+            {
+                IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
+                return hr;
+            }
         }
         if(This->auto_depth_stencil_buffer) {
-            updateSurfaceDesc((IWineD3DSurfaceImpl *)This->auto_depth_stencil_buffer, pPresentationParameters);
+            hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)This->auto_depth_stencil_buffer, pPresentationParameters);
+            if(FAILED(hr))
+            {
+                IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
+                return hr;
+            }
         }
     }
 
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index d75c5e9..1463dd4 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -820,6 +820,30 @@ static void surface_remove_pbo(IWineD3DSurfaceImpl *This) {
     This->Flags &= ~SFLAG_PBO;
 }
 
+BOOL surface_init_sysmem(IWineD3DSurface *iface)
+{
+    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
+
+    if(!This->resource.allocatedMemory)
+    {
+        This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT);
+        if(!This->resource.heapMemory)
+        {
+            ERR("Out of memory\n");
+            return FALSE;
+        }
+        This->resource.allocatedMemory =
+            (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+    }
+    else
+    {
+        memset(This->resource.allocatedMemory, 0, This->resource.size);
+    }
+
+    IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);
+    return TRUE;
+}
+
 static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
     IWineD3DBaseTexture *texture = NULL;
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
@@ -836,18 +860,12 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
          * or depth stencil. The content may be destroyed, but we still have to tear down
          * opengl resources, so we cannot leave early.
          *
-         * Put the most up to date surface location into the drawable. D3D-wise this content
-         * is undefined, so it would be nowhere, but that would make the location management
-         * more complicated. The drawable is a sane location, because if we mark sysmem or
-         * texture up to date, drawPrim will copy the uninitialized texture or sysmem to the
-         * uninitialized drawable. That's pointless and we'd have to allocate the texture /
-         * sysmem copy here.
+         * Put the surfaces into sysmem, and reset the content. The D3D content is undefined,
+         * but we can't set the sysmem INDRAWABLE because when we're rendering the swapchain
+         * or the depth stencil into an FBO the texture or render buffer will be removed
+         * and all flags get lost
          */
-        if (This->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) {
-            IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);
-        } else {
-            IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, TRUE);
-        }
+        surface_init_sysmem(iface);
     } else {
         /* Load the surface into system memory */
         IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 39519a1..bd8e58f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1726,6 +1726,7 @@ typedef struct IWineD3DBaseTextureClass
 } IWineD3DBaseTextureClass;
 
 void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN;
+BOOL surface_init_sysmem(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
 
 typedef struct IWineD3DBaseTextureImpl
 {




More information about the wine-cvs mailing list