Commit 6aeae744 authored by Axel Davy's avatar Axel Davy Committed by Emil Velikov

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" <mesa-stable@lists.freedesktop.org>
Tested-by: David Heidelberg's avatarDavid Heidelberg <david@ixit.cz>
Signed-off-by: Axel Davy's avatarAxel Davy <axel.davy@ens.fr>
parent 133b2087
......@@ -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),
......
......@@ -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))
......
......@@ -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);
}
......
......@@ -36,8 +36,6 @@ struct NineResource9
struct pipe_resource *resource; /* device resource */
uint8_t *data; /* system memory backing */
D3DRESOURCETYPE type;
D3DPOOL pool;
DWORD priority;
......
......@@ -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);
}
......@@ -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 );
......
......@@ -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)) {
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment