[Mesa-dev] [PATCH 01/11] st/nine: Refactor Resource9 BaseTexture9 Surface9 and Texture9 initialization

David Heidelberg david at ixit.cz
Sun Nov 23 14:40:01 PST 2014


From: Axel Davy <axel.davy at ens.fr>

First change is to pass initResource argument to initialise the resource
field in Resource9 instead of in the parents.

Second change is to pass Usage argument, instead of letting the parent
classes set the usage field of the Resource9 structure.

Third change fixes a bug, preventing Half-Life 2 Lost Coast from working
properly, is to remove the data field from Resource9, put it in Surface9,
which was the only user, and add flag to Surface9 to know if it has created
the data or not. Surface9 dtor frees the data only if it created it.

Cc: "10.4" <mesa-stable at lists.freedesktop.org>
Tested-by: David Heidelberg <david at ixit.cz>
Signed-off-by: Axel Davy <axel.davy at ens.fr>
---
 src/gallium/state_trackers/nine/adapter9.c       |   2 +-
 src/gallium/state_trackers/nine/basetexture9.c   |  23 +++--
 src/gallium/state_trackers/nine/basetexture9.h   |   5 +-
 src/gallium/state_trackers/nine/cubetexture9.c   |   9 +-
 src/gallium/state_trackers/nine/device9.c        |  19 ++--
 src/gallium/state_trackers/nine/device9.h        |   7 +-
 src/gallium/state_trackers/nine/device9ex.c      |   6 +-
 src/gallium/state_trackers/nine/indexbuffer9.c   |   4 +-
 src/gallium/state_trackers/nine/resource9.c      |  13 +--
 src/gallium/state_trackers/nine/resource9.h      |   6 +-
 src/gallium/state_trackers/nine/surface9.c       | 112 ++++++-----------------
 src/gallium/state_trackers/nine/surface9.h       |   7 +-
 src/gallium/state_trackers/nine/swapchain9.c     |   6 +-
 src/gallium/state_trackers/nine/texture9.c       |  51 ++++-------
 src/gallium/state_trackers/nine/vertexbuffer9.c  |   4 +-
 src/gallium/state_trackers/nine/volumetexture9.c |   7 +-
 16 files changed, 106 insertions(+), 175 deletions(-)

diff --git a/src/gallium/state_trackers/nine/adapter9.c b/src/gallium/state_trackers/nine/adapter9.c
index 8d574de..e409d5f 100644
--- a/src/gallium/state_trackers/nine/adapter9.c
+++ b/src/gallium/state_trackers/nine/adapter9.c
@@ -990,7 +990,7 @@ NineAdapter9_CreateDevice( struct NineAdapter9 *This,
     params.BehaviorFlags = BehaviorFlags;
 
     hr = NineDevice9_new(screen, &params, &caps, pPresentationParameters,
-                         pD3D9, pPresentationGroup, This->ctx,
+                         pD3D9, pPresentationGroup, This->ctx, FALSE, NULL,
                          (struct NineDevice9 **)ppReturnedDeviceInterface);
     if (FAILED(hr)) {
         DBG("Failed to create device.\n");
diff --git a/src/gallium/state_trackers/nine/basetexture9.c b/src/gallium/state_trackers/nine/basetexture9.c
index 89f6269..7bf2f56 100644
--- a/src/gallium/state_trackers/nine/basetexture9.c
+++ b/src/gallium/state_trackers/nine/basetexture9.c
@@ -41,25 +41,28 @@
 HRESULT
 NineBaseTexture9_ctor( struct NineBaseTexture9 *This,
                        struct NineUnknownParams *pParams,
+                       struct pipe_resource *initResource,
                        D3DRESOURCETYPE Type,
-                       D3DPOOL Pool )
+                       D3DFORMAT format,
+                       D3DPOOL Pool,
+                       DWORD Usage)
 {
-    BOOL alloc = (Pool == D3DPOOL_DEFAULT) && !This->base.resource &&
-        (This->format != D3DFMT_NULL);
+    BOOL alloc = (Pool == D3DPOOL_DEFAULT) && !initResource &&
+        (format != D3DFMT_NULL);
     HRESULT hr;
-    DWORD usage = This->base.usage;
 
-    user_assert(!(usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) ||
+    user_assert(!(Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) ||
                 Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL);
-    user_assert(!(usage & D3DUSAGE_DYNAMIC) ||
+    user_assert(!(Usage & D3DUSAGE_DYNAMIC) ||
                 Pool != D3DPOOL_MANAGED, D3DERR_INVALIDCALL);
 
-    hr = NineResource9_ctor(&This->base, pParams, alloc, Type, Pool);
+    hr = NineResource9_ctor(&This->base, pParams, initResource, alloc, Type, Pool, Usage);
     if (FAILED(hr))
         return hr;
 
+    This->format = format;
     This->pipe = pParams->device->pipe;
-    This->mipfilter = (This->base.usage & D3DUSAGE_AUTOGENMIPMAP) ?
+    This->mipfilter = (Usage & D3DUSAGE_AUTOGENMIPMAP) ?
         D3DTEXF_LINEAR : D3DTEXF_NONE;
     This->lod = 0;
     This->lod_resident = -1;
@@ -490,9 +493,9 @@ NineBaseTexture9_PreLoad( struct NineBaseTexture9 *This )
 void
 NineBaseTexture9_Dump( struct NineBaseTexture9 *This )
 {
-    DBG("\nNineBaseTexture9(%p->%p/%p): Pool=%s Type=%s Usage=%s\n"
+    DBG("\nNineBaseTexture9(%p->NULL/%p): Pool=%s Type=%s Usage=%s\n"
         "Format=%s Dims=%ux%ux%u/%u LastLevel=%u Lod=%u(%u)\n", This,
-        This->base.resource, This->base.data,
+        This->base.resource,
         nine_D3DPOOL_to_str(This->base.pool),
         nine_D3DRTYPE_to_str(This->base.type),
         nine_D3DUSAGE_to_str(This->base.usage),
diff --git a/src/gallium/state_trackers/nine/basetexture9.h b/src/gallium/state_trackers/nine/basetexture9.h
index d615376..0062771 100644
--- a/src/gallium/state_trackers/nine/basetexture9.h
+++ b/src/gallium/state_trackers/nine/basetexture9.h
@@ -59,8 +59,11 @@ NineBaseTexture9( void *data )
 HRESULT
 NineBaseTexture9_ctor( struct NineBaseTexture9 *This,
                        struct NineUnknownParams *pParams,
+                       struct pipe_resource *initResource,
                        D3DRESOURCETYPE Type,
-                       D3DPOOL Pool );
+                       D3DFORMAT format,
+                       D3DPOOL Pool,
+                       DWORD Usage);
 
 void
 NineBaseTexture9_dtor( struct NineBaseTexture9 *This );
diff --git a/src/gallium/state_trackers/nine/cubetexture9.c b/src/gallium/state_trackers/nine/cubetexture9.c
index 77802e7..5ef09f7 100644
--- a/src/gallium/state_trackers/nine/cubetexture9.c
+++ b/src/gallium/state_trackers/nine/cubetexture9.c
@@ -50,9 +50,6 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This,
     if (Usage & D3DUSAGE_AUTOGENMIPMAP)
         Levels = 0;
 
-    This->base.format = Format;
-    This->base.base.usage = Usage;
-
     info->screen = pParams->device->screen;
     info->target = PIPE_TEXTURE_CUBE;
     info->format = d3d9_to_pipe_format(Format);
@@ -85,8 +82,8 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This,
     if (!This->surfaces)
         return E_OUTOFMEMORY;
 
-    hr = NineBaseTexture9_ctor(&This->base, pParams, D3DRTYPE_CUBETEXTURE,
-                               Pool);
+    hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_CUBETEXTURE,
+                               Format, Pool, Usage);
     if (FAILED(hr))
         return hr;
     This->base.pstype = 2;
@@ -105,7 +102,7 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This,
         sfdesc.Width = sfdesc.Height = u_minify(EdgeLength, i / 6);
 
         hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This),
-                              This->base.base.resource, D3DRTYPE_CUBETEXTURE,
+                              This->base.base.resource, NULL, D3DRTYPE_CUBETEXTURE,
                               i / 6, i % 6,
                               &sfdesc, &This->surfaces[i]);
         if (FAILED(hr))
diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index 7d2142d..5f95b42 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -139,7 +139,9 @@ NineDevice9_ctor( struct NineDevice9 *This,
                   D3DPRESENT_PARAMETERS *pPresentationParameters,
                   IDirect3D9 *pD3D9,
                   ID3DPresentGroup *pPresentationGroup,
-                  struct d3dadapter9_context *pCTX )
+                  struct d3dadapter9_context *pCTX,
+                  boolean ex,
+                  D3DDISPLAYMODEEX *pFullscreenDisplayMode )
 {
     unsigned i;
     HRESULT hr = NineUnknown_ctor(&This->base, pParams);
@@ -151,6 +153,7 @@ NineDevice9_ctor( struct NineDevice9 *This,
     This->caps = *pCaps;
     This->d3d9 = pD3D9;
     This->params = *pCreationParameters;
+    This->ex = ex;
     This->present = pPresentationGroup;
     IDirect3D9_AddRef(This->d3d9);
     ID3DPresentGroup_AddRef(This->present);
@@ -177,12 +180,12 @@ NineDevice9_ctor( struct NineDevice9 *This,
         if (FAILED(hr))
             return hr;
 
-        if (This->ex) {
+        if (ex) {
             D3DDISPLAYMODEEX *mode = NULL;
             struct NineSwapChain9Ex **ret =
                 (struct NineSwapChain9Ex **)&This->swapchains[i];
 
-            if (This->pFullscreenDisplayMode) mode = &(This->pFullscreenDisplayMode[i]);
+            if (pFullscreenDisplayMode) mode = &(pFullscreenDisplayMode[i]);
             /* when this is a Device9Ex, it should create SwapChain9Exs */
             hr = NineSwapChain9Ex_new(This, TRUE, present,
                                       &pPresentationParameters[i], pCTX,
@@ -310,9 +313,6 @@ NineDevice9_ctor( struct NineDevice9 *This,
     This->update = &This->state;
     nine_update_state(This, ~0);
 
-    /* Is just used to pass the parameter from NineDevice9Ex_ctor */
-    This->pFullscreenDisplayMode = NULL;
-
     ID3DPresentGroup_Release(This->present);
 
     return D3D_OK;
@@ -974,7 +974,7 @@ create_zs_or_rt_surface(struct NineDevice9 *This,
     } else {
         resource = NULL;
     }
-    hr = NineSurface9_new(This, NULL, resource, 0, 0, 0, &desc, &surface);
+    hr = NineSurface9_new(This, NULL, resource, NULL, 0, 0, 0, &desc, &surface);
     pipe_resource_reference(&resource, NULL);
 
     if (SUCCEEDED(hr))
@@ -3447,6 +3447,8 @@ NineDevice9_new( struct pipe_screen *pScreen,
                  IDirect3D9 *pD3D9,
                  ID3DPresentGroup *pPresentationGroup,
                  struct d3dadapter9_context *pCTX,
+                 boolean ex,
+                 D3DDISPLAYMODEEX *pFullscreenDisplayMode,
                  struct NineDevice9 **ppOut )
 {
     BOOL lock;
@@ -3454,5 +3456,6 @@ NineDevice9_new( struct pipe_screen *pScreen,
 
     NINE_NEW(Device9, ppOut, lock, /* args */
              pScreen, pCreationParameters, pCaps,
-             pPresentationParameters, pD3D9, pPresentationGroup, pCTX);
+             pPresentationParameters, pD3D9, pPresentationGroup, pCTX,
+             ex, pFullscreenDisplayMode);
 }
diff --git a/src/gallium/state_trackers/nine/device9.h b/src/gallium/state_trackers/nine/device9.h
index 9dc248e..3649e1b 100644
--- a/src/gallium/state_trackers/nine/device9.h
+++ b/src/gallium/state_trackers/nine/device9.h
@@ -48,7 +48,6 @@ struct NineDevice9
 {
     struct NineUnknown base;
     boolean ex;
-    D3DDISPLAYMODEEX *pFullscreenDisplayMode;
 
     /* G3D context */
     struct pipe_screen *screen;
@@ -134,6 +133,8 @@ NineDevice9_new( struct pipe_screen *pScreen,
                  IDirect3D9 *pD3D9,
                  ID3DPresentGroup *pPresentationGroup,
                  struct d3dadapter9_context *pCTX,
+                 boolean ex,
+                 D3DDISPLAYMODEEX *pFullscreenDisplayMode,
                  struct NineDevice9 **ppOut );
 
 HRESULT
@@ -145,7 +146,9 @@ NineDevice9_ctor( struct NineDevice9 *This,
                   D3DPRESENT_PARAMETERS *pPresentationParameters,
                   IDirect3D9 *pD3D9,
                   ID3DPresentGroup *pPresentationGroup,
-                  struct d3dadapter9_context *pCTX );
+                  struct d3dadapter9_context *pCTX,
+                  boolean ex,
+                  D3DDISPLAYMODEEX *pFullscreenDisplayMode );
 
 void
 NineDevice9_dtor( struct NineDevice9 *This );
diff --git a/src/gallium/state_trackers/nine/device9ex.c b/src/gallium/state_trackers/nine/device9ex.c
index 00d460b..d36189d 100644
--- a/src/gallium/state_trackers/nine/device9ex.c
+++ b/src/gallium/state_trackers/nine/device9ex.c
@@ -39,13 +39,11 @@ NineDevice9Ex_ctor( struct NineDevice9Ex *This,
                     ID3DPresentGroup *pPresentationGroup,
                     struct d3dadapter9_context *pCTX )
 {
-    This->base.ex = TRUE;
-    This->base.pFullscreenDisplayMode = pFullscreenDisplayMode;
-
     return NineDevice9_ctor(&This->base, pParams,
                             pScreen, pCreationParameters, pCaps,
                             pPresentationParameters,
-                            (IDirect3D9 *)pD3D9Ex, pPresentationGroup, pCTX);
+                            (IDirect3D9 *)pD3D9Ex, pPresentationGroup, pCTX,
+                            TRUE, pFullscreenDisplayMode);
 }
 
 static void
diff --git a/src/gallium/state_trackers/nine/indexbuffer9.c b/src/gallium/state_trackers/nine/indexbuffer9.c
index c5606f1..48553fd 100644
--- a/src/gallium/state_trackers/nine/indexbuffer9.c
+++ b/src/gallium/state_trackers/nine/indexbuffer9.c
@@ -76,8 +76,8 @@ NineIndexBuffer9_ctor( struct NineIndexBuffer9 *This,
     info->last_level = 0;
     info->nr_samples = 0;
 
-    hr = NineResource9_ctor(&This->base, pParams, TRUE, D3DRTYPE_INDEXBUFFER,
-                            pDesc->Pool);
+    hr = NineResource9_ctor(&This->base, pParams, NULL, TRUE, D3DRTYPE_INDEXBUFFER,
+                            pDesc->Pool, pDesc->Usage);
     if (FAILED(hr))
         return hr;
 
diff --git a/src/gallium/state_trackers/nine/resource9.c b/src/gallium/state_trackers/nine/resource9.c
index 8f53558..6bdc1d0 100644
--- a/src/gallium/state_trackers/nine/resource9.c
+++ b/src/gallium/state_trackers/nine/resource9.c
@@ -38,9 +38,11 @@
 HRESULT
 NineResource9_ctor( struct NineResource9 *This,
                     struct NineUnknownParams *pParams,
+                    struct pipe_resource *initResource,
                     BOOL Allocate,
                     D3DRESOURCETYPE Type,
-                    D3DPOOL Pool )
+                    D3DPOOL Pool,
+                    DWORD Usage)
 {
     struct pipe_screen *screen;
     HRESULT hr;
@@ -50,17 +52,20 @@ NineResource9_ctor( struct NineResource9 *This,
         return hr;
 
     This->info.screen = screen = This->base.device->screen;
+    if (initResource)
+        pipe_resource_reference(&This->resource, initResource);
 
     if (Allocate) {
+        assert(!initResource);
         DBG("(%p) Creating pipe_resource.\n", This);
         This->resource = screen->resource_create(screen, &This->info);
         if (!This->resource)
             return D3DERR_OUTOFVIDEOMEMORY;
     }
 
-    This->data = NULL; /* FIXME remove, rather set it to null in surface9.c*/
     This->type = Type;
     This->pool = Pool;
+    This->usage = Usage;
     This->priority = 0;
 
     This->pdata = util_hash_table_create(ht_guid_hash, ht_guid_compare);
@@ -82,10 +87,6 @@ NineResource9_dtor( struct NineResource9 *This )
      * still hold a reference. */
     pipe_resource_reference(&This->resource, NULL);
 
-    /* release allocated system memory for non-D3DPOOL_DEFAULT resources */
-    if (This->data)
-        FREE(This->data);
-
     NineUnknown_dtor(&This->base);
 }
 
diff --git a/src/gallium/state_trackers/nine/resource9.h b/src/gallium/state_trackers/nine/resource9.h
index 0451498..da1dd63 100644
--- a/src/gallium/state_trackers/nine/resource9.h
+++ b/src/gallium/state_trackers/nine/resource9.h
@@ -36,8 +36,6 @@ struct NineResource9
 
     struct pipe_resource *resource; /* device resource */
 
-    uint8_t *data; /* system memory backing */
-
     D3DRESOURCETYPE type;
     D3DPOOL pool;
     DWORD priority;
@@ -57,9 +55,11 @@ NineResource9( void *data )
 HRESULT
 NineResource9_ctor( struct NineResource9 *This,
                     struct NineUnknownParams *pParams,
+                    struct pipe_resource *initResource,
                     BOOL Allocate,
                     D3DRESOURCETYPE Type,
-                    D3DPOOL Pool );
+                    D3DPOOL Pool,
+                    DWORD Usage);
 
 void
 NineResource9_dtor( struct NineResource9 *This );
diff --git a/src/gallium/state_trackers/nine/surface9.c b/src/gallium/state_trackers/nine/surface9.c
index 42a9e05..aa79112 100644
--- a/src/gallium/state_trackers/nine/surface9.c
+++ b/src/gallium/state_trackers/nine/surface9.c
@@ -43,6 +43,7 @@ NineSurface9_ctor( struct NineSurface9 *This,
                    struct NineUnknownParams *pParams,
                    struct NineUnknown *pContainer,
                    struct pipe_resource *pResource,
+                   void *user_buffer,
                    uint8_t TextureType,
                    unsigned Level,
                    unsigned Layer,
@@ -62,6 +63,8 @@ NineSurface9_ctor( struct NineSurface9 *This,
     assert(pResource ||
            pDesc->Pool != D3DPOOL_DEFAULT || pDesc->Format == D3DFMT_NULL);
 
+    assert(!pResource || !user_buffer);
+
     This->base.info.screen = pParams->device->screen;
     This->base.info.target = PIPE_TEXTURE_2D;
     This->base.info.format = d3d9_to_pipe_format(pDesc->Format);
@@ -82,20 +85,17 @@ NineSurface9_ctor( struct NineSurface9 *This,
 
     if (pDesc->Pool == D3DPOOL_SYSTEMMEM) {
         This->base.info.usage = PIPE_USAGE_STAGING;
-        if (pResource)
-            This->base.data = (uint8_t *)pResource; /* this is *pSharedHandle */
-        pResource = NULL;
+        This->data = (uint8_t *)user_buffer; /* this is *pSharedHandle */
+        assert(!pResource);
     } else {
         if (pResource && (pDesc->Usage & D3DUSAGE_DYNAMIC))
             pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
-        pipe_resource_reference(&This->base.resource, pResource);
     }
 
-    hr = NineResource9_ctor(&This->base, pParams, FALSE, D3DRTYPE_SURFACE,
-                            pDesc->Pool);
+    hr = NineResource9_ctor(&This->base, pParams, pResource, FALSE, D3DRTYPE_SURFACE,
+                            pDesc->Pool, pDesc->Usage);
     if (FAILED(hr))
         return hr;
-    This->base.usage = pDesc->Usage;
 
     This->pipe = This->base.base.device->pipe;
     This->transfer = NULL;
@@ -109,13 +109,20 @@ NineSurface9_ctor( struct NineSurface9 *This,
     This->stride = util_format_get_stride(This->base.info.format, pDesc->Width);
     This->stride = align(This->stride, 4);
 
-    if (!pResource && !This->base.data) {
-        hr = NineSurface9_AllocateData(This);
-        if (FAILED(hr))
-            return hr;
+    if (!pResource && !This->data) {
+        const unsigned size = This->stride *
+            util_format_get_nblocksy(This->base.info.format, This->desc.Height);
+
+        DBG("(%p(This=%p),level=%u) Allocating 0x%x bytes of system memory.\n",
+            This->base.base.container, This, This->level, size);
+
+        This->data = (uint8_t *)MALLOC(size);
+        if (!This->data)
+            return E_OUTOFMEMORY;
+        This->manage_data = TRUE;
     } else {
         if (pResource && NineSurface9_IsOffscreenPlain(This))
-            pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
+            pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; /* why setting this flag there ? too late ? should be before NineResource9_ctor call perhaps ? */
     }
 
     NineSurface9_Dump(This);
@@ -133,6 +140,9 @@ NineSurface9_dtor( struct NineSurface9 *This )
     pipe_surface_reference(&This->surface[0], NULL);
     pipe_surface_reference(&This->surface[1], NULL);
 
+    /* release allocated system memory for non-D3DPOOL_DEFAULT resources */
+    if (This->manage_data && This->data)
+        FREE(This->data);
     NineResource9_dtor(&This->base);
 }
 
@@ -167,7 +177,7 @@ NineSurface9_Dump( struct NineSurface9 *This )
 
     DBG("\nNineSurface9(%p->%p/%p): Pool=%s Type=%s Usage=%s\n"
         "Dims=%ux%u Format=%s Stride=%u Lockable=%i\n"
-        "Level=%u(%u), Layer=%u\n", This, This->base.resource, This->base.data,
+        "Level=%u(%u), Layer=%u\n", This, This->base.resource, This->data,
         nine_D3DPOOL_to_str(This->desc.Pool),
         nine_D3DRTYPE_to_str(This->desc.Type),
         nine_D3DUSAGE_to_str(This->desc.Usage),
@@ -286,8 +296,8 @@ NineSurface9_GetSystemMemPointer(struct NineSurface9 *This, int x, int y)
 
     y = util_format_get_nblocksy(This->base.info.format, y);
 
-    assert(This->base.data);
-    return This->base.data + (y * This->stride + x_offset);
+    assert(This->data);
+    return This->data + (y * This->stride + x_offset);
 }
 
 HRESULT WINAPI
@@ -360,7 +370,7 @@ NineSurface9_LockRect( struct NineSurface9 *This,
 
     user_warn(This->desc.Format == D3DFMT_NULL);
 
-    if (This->base.data) {
+    if (This->data) {
         DBG("returning system memory\n");
 
         pLockedRect->Pitch = This->stride;
@@ -419,73 +429,6 @@ NineSurface9_ReleaseDC( struct NineSurface9 *This,
     STUB(D3DERR_INVALIDCALL);
 }
 
-/* nine private */
-
-HRESULT
-NineSurface9_AllocateData( struct NineSurface9 *This )
-{
-#if 0
-    struct pipe_screen *screen = This->base.info.screen;
-    /* XXX: Can't use staging resource because apparently apps expect
-     * memory offsets to be the same across locks.
-     * NV50 doesn't support direct mapping yet so only enable this if
-     * everything else works.
-     */
-    if (This->base.pool == D3DPOOL_SYSTEMMEM) {
-        /* Allocate a staging resource to save a copy:
-         * user -> staging resource
-         * staging resource -> (blit) -> video memory
-         *
-         * Instead of:
-         * user -> system memory
-         * system memory -> transfer staging area
-         * transfer -> video memory
-         *
-         * Does this work if we "lose" the device ?
-         */
-        struct pipe_resource *resource;
-        struct pipe_resource templ;
-
-        templ.target = PIPE_TEXTURE_2D;
-        templ.format = This->base.info.format;
-        templ.width0 = This->desc.Width;
-        templ.height0 = This->desc.Height;
-        templ.depth0 = 1;
-        templ.array_size = 1;
-        templ.last_level = 0;
-        templ.nr_samples = 0;
-        templ.usage = PIPE_USAGE_STAGING;
-        templ.bind =
-            PIPE_BIND_SAMPLER_VIEW |
-            PIPE_BIND_TRANSFER_WRITE |
-            PIPE_BIND_TRANSFER_READ;
-        templ.flags = 0;
-
-        DBG("(%p(This=%p),level=%u) Allocating staging resource.\n",
-            This->base.base.container, This, This->level);
-
-        resource = screen->resource_create(screen, &templ);
-        if (!resource)
-            DBG("Failed to allocate staging resource.\n");
-
-        /* Also deallocate old staging resource. */
-        pipe_resource_reference(&This->base.resource, resource);
-    }
-#endif
-    if (!This->base.resource) {
-        const unsigned size = This->stride *
-            util_format_get_nblocksy(This->base.info.format, This->desc.Height);
-
-        DBG("(%p(This=%p),level=%u) Allocating 0x%x bytes of system memory.\n",
-            This->base.base.container, This, This->level, size);
-
-        This->base.data = (uint8_t *)MALLOC(size);
-        if (!This->base.data)
-            return E_OUTOFMEMORY;
-    }
-    return D3D_OK;
-}
-
 IDirect3DSurface9Vtbl NineSurface9_vtable = {
     (void *)NineUnknown_QueryInterface,
     (void *)NineUnknown_AddRef,
@@ -699,6 +642,7 @@ HRESULT
 NineSurface9_new( struct NineDevice9 *pDevice,
                   struct NineUnknown *pContainer,
                   struct pipe_resource *pResource,
+                  void *user_buffer,
                   uint8_t TextureType,
                   unsigned Level,
                   unsigned Layer,
@@ -706,6 +650,6 @@ NineSurface9_new( struct NineDevice9 *pDevice,
                   struct NineSurface9 **ppOut )
 {
     NINE_DEVICE_CHILD_NEW(Surface9, ppOut, pDevice, /* args */
-                          pContainer, pResource,
+                          pContainer, pResource, user_buffer,
                           TextureType, Level, Layer, pDesc);
 }
diff --git a/src/gallium/state_trackers/nine/surface9.h b/src/gallium/state_trackers/nine/surface9.h
index 4a9db25..32e1722 100644
--- a/src/gallium/state_trackers/nine/surface9.h
+++ b/src/gallium/state_trackers/nine/surface9.h
@@ -47,6 +47,8 @@ struct NineSurface9
     unsigned layer;
     D3DSURFACE_DESC desc;
 
+    uint8_t *data; /* system memory backing */
+    boolean manage_data;
     unsigned stride; /* for system memory backing */
 
     /* wine doesn't even use these, 2 will be enough */
@@ -62,6 +64,7 @@ HRESULT
 NineSurface9_new( struct NineDevice9 *pDevice,
                   struct NineUnknown *pContainer,
                   struct pipe_resource *pResource,
+                  void *user_buffer,
                   uint8_t TextureType, /* 0 if pContainer isn't BaseTexure9 */
                   unsigned Level,
                   unsigned Layer,
@@ -73,6 +76,7 @@ NineSurface9_ctor( struct NineSurface9 *This,
                    struct NineUnknownParams *pParams,
                    struct NineUnknown *pContainer,
                    struct pipe_resource *pResource,
+                   void *user_buffer,
                    uint8_t TextureType,
                    unsigned Level,
                    unsigned Layer,
@@ -125,9 +129,6 @@ NineSurface9_ClearDirtyRects( struct NineSurface9 *This )
 }
 
 HRESULT
-NineSurface9_AllocateData( struct NineSurface9 *This );
-
-HRESULT
 NineSurface9_UploadSelf( struct NineSurface9 *This );
 
 HRESULT
diff --git a/src/gallium/state_trackers/nine/swapchain9.c b/src/gallium/state_trackers/nine/swapchain9.c
index b6f5ef6..5061bf2 100644
--- a/src/gallium/state_trackers/nine/swapchain9.c
+++ b/src/gallium/state_trackers/nine/swapchain9.c
@@ -304,7 +304,7 @@ NineSwapChain9_Resize( struct NineSwapChain9 *This,
         } else {
             desc.Format = pParams->BackBufferFormat;
             desc.Usage = D3DUSAGE_RENDERTARGET;
-            hr = NineSurface9_new(pDevice, NineUnknown(This), resource, 0,
+            hr = NineSurface9_new(pDevice, NineUnknown(This), resource, NULL, 0,
                                   0, 0, &desc, &This->buffers[i]);
             if (has_present_buffers)
                 pipe_resource_reference(&resource, NULL);
@@ -347,7 +347,7 @@ NineSwapChain9_Resize( struct NineSwapChain9 *This,
             /* XXX wine thinks the container of this should be the device */
             desc.Format = pParams->AutoDepthStencilFormat;
             desc.Usage = D3DUSAGE_DEPTHSTENCIL;
-            hr = NineSurface9_new(pDevice, NineUnknown(pDevice), resource, 0,
+            hr = NineSurface9_new(pDevice, NineUnknown(pDevice), resource, NULL, 0,
                                   0, 0, &desc, &This->zsbuf);
             pipe_resource_reference(&resource, NULL);
             if (FAILED(hr)) {
@@ -832,7 +832,7 @@ NineSwapChain9_GetFrontBufferData( struct NineSwapChain9 *This,
     /* NineSurface9_CopySurface needs same format. */
     desc.Format = dest_surface->desc.Format;
     desc.Usage = D3DUSAGE_RENDERTARGET;
-    hr = NineSurface9_new(pDevice, NineUnknown(This), temp_resource, 0,
+    hr = NineSurface9_new(pDevice, NineUnknown(This), temp_resource, NULL, 0,
                           0, 0, &desc, &temp_surface);
     pipe_resource_reference(&temp_resource, NULL);
     if (FAILED(hr)) {
diff --git a/src/gallium/state_trackers/nine/texture9.c b/src/gallium/state_trackers/nine/texture9.c
index c13268d..9537b25 100644
--- a/src/gallium/state_trackers/nine/texture9.c
+++ b/src/gallium/state_trackers/nine/texture9.c
@@ -46,10 +46,11 @@ NineTexture9_ctor( struct NineTexture9 *This,
 {
     struct pipe_screen *screen = pParams->device->screen;
     struct pipe_resource *info = &This->base.base.info;
+    struct pipe_resource *resource;
     unsigned l;
     D3DSURFACE_DESC sfdesc;
     HRESULT hr;
-    const boolean shared_create = pSharedHandle && !*pSharedHandle;
+    void *user_buffer = NULL;
 
     DBG("(%p) Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s "
         "pSharedHandle=%p\n", This, Width, Height, Levels,
@@ -77,10 +78,7 @@ NineTexture9_ctor( struct NineTexture9 *This,
                 Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL);
 
     if (pSharedHandle && Pool == D3DPOOL_DEFAULT) {
-        /* Note: Below there is some implementation to support buffer sharing in
-         * this case, but it won't work for cross-process. Thus just ignore
-         * that code. */
-        if (shared_create) {
+        if (!*pSharedHandle) {
             DBG("Creating Texture with invalid handle. Importing will fail\n.");
             *pSharedHandle = (HANDLE)1; /* Wine would keep it NULL */
             pSharedHandle = NULL;
@@ -94,9 +92,6 @@ NineTexture9_ctor( struct NineTexture9 *This,
     if (Usage & D3DUSAGE_AUTOGENMIPMAP)
         Levels = 0;
 
-    This->base.format = Format;
-    This->base.base.usage = Usage;
-
     info->screen = screen;
     info->target = PIPE_TEXTURE_2D;
     info->format = d3d9_to_pipe_format(Format);
@@ -130,25 +125,15 @@ NineTexture9_ctor( struct NineTexture9 *This,
     if (Pool == D3DPOOL_SYSTEMMEM)
         info->usage = PIPE_USAGE_STAGING;
 
-    if (pSharedHandle && !shared_create) {
-        if (Pool == D3DPOOL_SYSTEMMEM) {
-            /* Hack for surface creation. */
-            This->base.base.resource = (struct pipe_resource *)*pSharedHandle;
-        } else {
-            struct pipe_resource *res;
-            res = screen->resource_from_handle(screen, info,
-                                      (struct winsys_handle *)pSharedHandle);
-            if (!res)
-                return D3DERR_NOTFOUND;
-            This->base.base.resource = res;
-        }
+    if (pSharedHandle && *pSharedHandle) { /* Pool == D3DPOOL_SYSTEMMEM */
+        user_buffer = (void *)*pSharedHandle;
     }
 
     This->surfaces = CALLOC(info->last_level + 1, sizeof(*This->surfaces));
     if (!This->surfaces)
         return E_OUTOFMEMORY;
 
-    hr = NineBaseTexture9_ctor(&This->base, pParams, D3DRTYPE_TEXTURE, Pool);
+    hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_TEXTURE, Format, Pool, Usage);
     if (FAILED(hr))
         return hr;
     This->base.pstype = (Height == 1) ? 1 : 0;
@@ -163,12 +148,19 @@ NineTexture9_ctor( struct NineTexture9 *This,
     sfdesc.Pool = Pool;
     sfdesc.MultiSampleType = D3DMULTISAMPLE_NONE;
     sfdesc.MultiSampleQuality = 0;
+
+    if (Pool == D3DPOOL_SYSTEMMEM)
+        resource = NULL;
+    else
+        resource = This->base.base.resource;
+
     for (l = 0; l <= info->last_level; ++l) {
         sfdesc.Width = u_minify(Width, l);
         sfdesc.Height = u_minify(Height, l);
 
         hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This),
-                              This->base.base.resource, D3DRTYPE_TEXTURE, l, 0,
+                              resource, user_buffer,
+                              D3DRTYPE_TEXTURE, l, 0,
                               &sfdesc, &This->surfaces[l]);
         if (FAILED(hr))
             return hr;
@@ -176,19 +168,8 @@ NineTexture9_ctor( struct NineTexture9 *This,
 
     This->dirty_rect.depth = 1; /* widht == 0 means empty, depth stays 1 */
 
-    if (pSharedHandle) {
-        if (Pool == D3DPOOL_SYSTEMMEM) {
-            This->base.base.resource = NULL;
-            if (shared_create)
-                *pSharedHandle = This->surfaces[0]->base.data;
-        } else
-        if (shared_create) {
-            boolean ok;
-            ok = screen->resource_get_handle(screen, This->base.base.resource,
-                                         (struct winsys_handle *)pSharedHandle);
-            if (!ok)
-                return D3DERR_DRIVERINTERNALERROR;
-        }
+    if (pSharedHandle && !*pSharedHandle) {/* Pool == D3DPOOL_SYSTEMMEM */
+        *pSharedHandle = This->surfaces[0]->data;
     }
 
     return D3D_OK;
diff --git a/src/gallium/state_trackers/nine/vertexbuffer9.c b/src/gallium/state_trackers/nine/vertexbuffer9.c
index 6a57349..11cc60f 100644
--- a/src/gallium/state_trackers/nine/vertexbuffer9.c
+++ b/src/gallium/state_trackers/nine/vertexbuffer9.c
@@ -85,8 +85,8 @@ NineVertexBuffer9_ctor( struct NineVertexBuffer9 *This,
     info->last_level = 0;
     info->nr_samples = 0;
 
-    hr = NineResource9_ctor(&This->base, pParams, TRUE, D3DRTYPE_VERTEXBUFFER,
-                            pDesc->Pool);
+    hr = NineResource9_ctor(&This->base, pParams, NULL, TRUE,
+                            D3DRTYPE_VERTEXBUFFER, pDesc->Pool, pDesc->Usage);
     if (FAILED(hr))
         return hr;
 
diff --git a/src/gallium/state_trackers/nine/volumetexture9.c b/src/gallium/state_trackers/nine/volumetexture9.c
index 65d320c..a35d3f7 100644
--- a/src/gallium/state_trackers/nine/volumetexture9.c
+++ b/src/gallium/state_trackers/nine/volumetexture9.c
@@ -52,9 +52,6 @@ NineVolumeTexture9_ctor( struct NineVolumeTexture9 *This,
     if (Usage & D3DUSAGE_AUTOGENMIPMAP)
         Levels = 0;
 
-    This->base.format = Format;
-    This->base.base.usage = Usage;
-
     info->screen = pParams->device->screen;
     info->target = PIPE_TEXTURE_3D;
     info->format = d3d9_to_pipe_format(Format);
@@ -83,8 +80,8 @@ NineVolumeTexture9_ctor( struct NineVolumeTexture9 *This,
         return E_OUTOFMEMORY;
     This->base.pstype = 3;
 
-    hr = NineBaseTexture9_ctor(&This->base, pParams,
-                               D3DRTYPE_VOLUMETEXTURE, Pool);
+    hr = NineBaseTexture9_ctor(&This->base, pParams, NULL,
+                               D3DRTYPE_VOLUMETEXTURE, Format, Pool, Usage);
     if (FAILED(hr))
         return hr;
 
-- 
2.1.3



More information about the mesa-dev mailing list