[Mesa-dev] [PATCH v3 03/19] st/nine: rework the way D3DPOOL_SYSTEMMEM is handled

David Heidelberg david at ixit.cz
Mon Nov 24 15:38:03 PST 2014


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

This patch moves the data field from Resource9 to Surface9 and cleans
D3DPOOL_SYSTEMMEM handling in Texture9. This fixes HL2 lost coast.

It also removes in Texture9 some code written to support importing
and exporting non D3DPOOL_SYSTEMMEM shared buffers. This code hadn't
the design required to support the feature and wasn't used.

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/basetexture9.c |   4 +-
 src/gallium/state_trackers/nine/cubetexture9.c |   2 +-
 src/gallium/state_trackers/nine/resource9.c    |   5 --
 src/gallium/state_trackers/nine/resource9.h    |   2 -
 src/gallium/state_trackers/nine/surface9.c     | 106 ++++++-------------------
 src/gallium/state_trackers/nine/surface9.h     |   7 +-
 src/gallium/state_trackers/nine/swapchain9.c   |   6 +-
 src/gallium/state_trackers/nine/texture9.c     |  46 ++++-------
 8 files changed, 51 insertions(+), 127 deletions(-)

diff --git a/src/gallium/state_trackers/nine/basetexture9.c b/src/gallium/state_trackers/nine/basetexture9.c
index 6d41592..7bf2f56 100644
--- a/src/gallium/state_trackers/nine/basetexture9.c
+++ b/src/gallium/state_trackers/nine/basetexture9.c
@@ -493,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/cubetexture9.c b/src/gallium/state_trackers/nine/cubetexture9.c
index 4f63162..5ef09f7 100644
--- a/src/gallium/state_trackers/nine/cubetexture9.c
+++ b/src/gallium/state_trackers/nine/cubetexture9.c
@@ -102,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/resource9.c b/src/gallium/state_trackers/nine/resource9.c
index c82180b..6bdc1d0 100644
--- a/src/gallium/state_trackers/nine/resource9.c
+++ b/src/gallium/state_trackers/nine/resource9.c
@@ -63,7 +63,6 @@ NineResource9_ctor( struct NineResource9 *This,
             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;
@@ -88,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 d18f0cf..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;
diff --git a/src/gallium/state_trackers/nine/surface9.c b/src/gallium/state_trackers/nine/surface9.c
index 94b4d07..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,9 +85,8 @@ 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;
@@ -107,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);
@@ -131,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);
 }
 
@@ -165,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),
@@ -284,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
@@ -358,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;
@@ -417,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,
@@ -697,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,
@@ -704,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 e30f955..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;
@@ -127,18 +125,8 @@ 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));
@@ -160,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;
@@ -173,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;
-- 
2.1.3



More information about the mesa-dev mailing list