From 6aeae7442d1d5a8b1ff77b6f50f4ac7333cd22b0 Mon Sep 17 00:00:00 2001 From: Axel Davy Date: Tue, 25 Nov 2014 00:38:03 +0100 Subject: [PATCH] st/nine: rework the way D3DPOOL_SYSTEMMEM is handled 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" Tested-by: David Heidelberg Signed-off-by: Axel Davy --- .../state_trackers/nine/basetexture9.c | 4 +- .../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 6d415921799..7bf2f564ea0 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 4f631620b9f..5ef09f74e2a 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 c82180be37c..6bdc1d08bac 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 d18f0cf2287..da1dd6320e0 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 94b4d07a900..aa791125319 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 4a9db25237c..32e17222f10 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, @@ -124,9 +128,6 @@ NineSurface9_ClearDirtyRects( struct NineSurface9 *This ) memset(&This->dirty_rects, 0, sizeof(This->dirty_rects)); } -HRESULT -NineSurface9_AllocateData( struct NineSurface9 *This ); - HRESULT NineSurface9_UploadSelf( struct NineSurface9 *This ); diff --git a/src/gallium/state_trackers/nine/swapchain9.c b/src/gallium/state_trackers/nine/swapchain9.c index b6f5ef65782..5061bf21906 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 e30f955aa0f..9537b25038d 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.30.2