st/nine: Allocate surface resources in surface ctor

Allocate resources in surface ctor.
Allows to use statetracker internal memory accounting.

Fix for issue #231.

Signed-off-by: Patrick Rudolph <siro@das-labor.org>
Signed-off-by: Axel Davy <axel.davy@ens.fr>
This commit is contained in:
Patrick Rudolph
2016-09-15 20:28:17 +02:00
committed by Axel Davy
parent 1f65f67b21
commit ba0274c7d6
2 changed files with 46 additions and 70 deletions
+8 -50
View File
@@ -1134,11 +1134,8 @@ create_zs_or_rt_surface(struct NineDevice9 *This,
HANDLE *pSharedHandle)
{
struct NineSurface9 *surface;
struct pipe_screen *screen = This->screen;
struct pipe_resource *resource = NULL;
HRESULT hr;
D3DSURFACE_DESC desc;
struct pipe_resource templ;
DBG("This=%p type=%u Pool=%s Width=%u Height=%u Format=%s MS=%u Quality=%u "
"Discard_or_Lockable=%i ppSurface=%p pSharedHandle=%p\n",
@@ -1152,31 +1149,6 @@ create_zs_or_rt_surface(struct NineDevice9 *This,
user_assert(Width && Height, D3DERR_INVALIDCALL);
user_assert(Pool != D3DPOOL_MANAGED, D3DERR_INVALIDCALL);
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.width0 = Width;
templ.height0 = Height;
templ.depth0 = 1;
templ.array_size = 1;
templ.last_level = 0;
templ.nr_samples = (unsigned)MultiSample;
templ.usage = PIPE_USAGE_DEFAULT;
templ.flags = 0;
templ.bind = PIPE_BIND_SAMPLER_VIEW; /* StretchRect */
switch (type) {
case 0: templ.bind |= PIPE_BIND_RENDER_TARGET; break;
case 1: templ.bind = d3d9_get_pipe_depth_format_bindings(Format); break;
default:
assert(type == 2);
break;
}
templ.format = d3d9_to_pipe_format_checked(screen, Format, templ.target,
templ.nr_samples, templ.bind,
FALSE, Pool == D3DPOOL_SCRATCH);
if (templ.format == PIPE_FORMAT_NONE && Format != D3DFMT_NULL)
return D3DERR_INVALIDCALL;
desc.Format = Format;
desc.Type = D3DRTYPE_SURFACE;
desc.Usage = 0;
@@ -1188,31 +1160,17 @@ create_zs_or_rt_surface(struct NineDevice9 *This,
switch (type) {
case 0: desc.Usage = D3DUSAGE_RENDERTARGET; break;
case 1: desc.Usage = D3DUSAGE_DEPTHSTENCIL; break;
default: break;
default: assert(type == 2); break;
}
if (compressed_format(Format)) {
const unsigned w = util_format_get_blockwidth(templ.format);
const unsigned h = util_format_get_blockheight(templ.format);
user_assert(!(Width % w) && !(Height % h), D3DERR_INVALIDCALL);
}
if (Pool == D3DPOOL_DEFAULT && Format != D3DFMT_NULL) {
/* resource_create doesn't return an error code, so check format here */
user_assert(templ.format != PIPE_FORMAT_NONE, D3DERR_INVALIDCALL);
resource = screen->resource_create(screen, &templ);
user_assert(resource, D3DERR_OUTOFVIDEOMEMORY);
if (Discard_or_Lockable && (desc.Usage & D3DUSAGE_RENDERTARGET))
resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
} else {
resource = NULL;
}
hr = NineSurface9_new(This, NULL, resource, NULL, 0, 0, 0, &desc, &surface);
pipe_resource_reference(&resource, NULL);
if (SUCCEEDED(hr))
hr = NineSurface9_new(This, NULL, NULL, NULL, 0, 0, 0, &desc, &surface);
if (SUCCEEDED(hr)) {
*ppSurface = (IDirect3DSurface9 *)surface;
if (surface->base.resource && Discard_or_Lockable && (type != 1))
surface->base.resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
}
return hr;
}
+38 -20
View File
@@ -57,30 +57,34 @@ NineSurface9_ctor( struct NineSurface9 *This,
union pipe_color_union rgba = {0};
struct pipe_surface *surf;
struct pipe_context *pipe = pParams->device->pipe;
bool allocate = !pContainer && pDesc->Format != D3DFMT_NULL;
DBG("This=%p pDevice=%p pResource=%p Level=%u Layer=%u pDesc=%p\n",
This, pParams->device, pResource, Level, Layer, pDesc);
/* Mark this as a special surface held by another internal resource. */
pParams->container = pContainer;
/* Make sure there's a Desc */
assert(pDesc);
/* D3DUSAGE_DYNAMIC isn't allowed on managed buffers */
user_assert(!(pDesc->Usage & D3DUSAGE_DYNAMIC) ||
(pDesc->Pool != D3DPOOL_MANAGED), D3DERR_INVALIDCALL);
assert(pResource || (user_buffer && pDesc->Pool != D3DPOOL_DEFAULT) ||
(!pContainer && pDesc->Pool != D3DPOOL_DEFAULT) ||
assert(allocate || pResource || user_buffer ||
pDesc->Format == D3DFMT_NULL);
assert(!allocate || (!pResource && !user_buffer));
assert(!pResource || !user_buffer);
assert(!user_buffer || pDesc->Pool != D3DPOOL_DEFAULT);
/* The only way we can have !pContainer is being created
* from create_zs_or_rt_surface with params 0 0 0 */
assert(pContainer || (Level == 0 && Layer == 0 && TextureType == 0));
/* Make sure no resource is passed for pool systemmem */
assert(pDesc->Pool != D3DPOOL_SYSTEMMEM || !pResource);
assert(!pResource || pDesc->Pool == D3DPOOL_DEFAULT);
/* Allocation only from create_zs_or_rt_surface with params 0 0 0 */
assert(!allocate || (Level == 0 && Layer == 0 && TextureType == 0));
This->data = (uint8_t *)user_buffer;
/* TODO: this is (except width and height) duplicate from
* container info (in the pContainer case). Some refactoring is
* needed to avoid duplication */
This->base.info.screen = pParams->device->screen;
This->base.info.target = PIPE_TEXTURE_2D;
This->base.info.width0 = pDesc->Width;
@@ -90,7 +94,16 @@ NineSurface9_ctor( struct NineSurface9 *This,
This->base.info.array_size = 1;
This->base.info.nr_samples = pDesc->MultiSampleType;
This->base.info.usage = PIPE_USAGE_DEFAULT;
This->base.info.bind = PIPE_BIND_SAMPLER_VIEW;
This->base.info.bind = PIPE_BIND_SAMPLER_VIEW; /* StretchRect */
if (pDesc->Usage & D3DUSAGE_RENDERTARGET) {
This->base.info.bind |= PIPE_BIND_RENDER_TARGET;
} else if (pDesc->Usage & D3DUSAGE_DEPTHSTENCIL) {
This->base.info.bind = d3d9_get_pipe_depth_format_bindings(pDesc->Format);
if (TextureType)
This->base.info.bind |= PIPE_BIND_SAMPLER_VIEW;
}
This->base.info.flags = 0;
This->base.info.format = d3d9_to_pipe_format_checked(This->base.info.screen,
pDesc->Format,
@@ -100,10 +113,16 @@ NineSurface9_ctor( struct NineSurface9 *This,
FALSE,
pDesc->Pool == D3DPOOL_SCRATCH);
if (pDesc->Usage & D3DUSAGE_RENDERTARGET)
This->base.info.bind |= PIPE_BIND_RENDER_TARGET;
if (pDesc->Usage & D3DUSAGE_DEPTHSTENCIL)
This->base.info.bind |= PIPE_BIND_DEPTH_STENCIL;
if (This->base.info.format == PIPE_FORMAT_NONE && pDesc->Format != D3DFMT_NULL)
return D3DERR_INVALIDCALL;
if (allocate && compressed_format(pDesc->Format)) {
const unsigned w = util_format_get_blockwidth(This->base.info.format);
const unsigned h = util_format_get_blockheight(This->base.info.format);
/* Note: In the !allocate case, the test could fail (lower levels of a texture) */
user_assert(!(pDesc->Width % w) && !(pDesc->Height % h), D3DERR_INVALIDCALL);
}
/* Get true format */
This->format_conversion = d3d9_to_pipe_format_checked(This->base.info.screen,
@@ -125,8 +144,8 @@ NineSurface9_ctor( struct NineSurface9 *This,
pDesc->Width);
}
/* Ram buffer with no parent. Has to allocate the resource itself */
if (!pResource && !pContainer) {
if ((allocate && pDesc->Pool != D3DPOOL_DEFAULT) || pDesc->Format == D3DFMT_NULL) {
/* Ram buffer with no parent. Has to allocate the resource itself */
assert(!user_buffer);
This->data = align_malloc(
nine_format_get_level_alloc_size(This->base.info.format,
@@ -137,11 +156,10 @@ NineSurface9_ctor( struct NineSurface9 *This,
return E_OUTOFMEMORY;
}
if (pResource && (pDesc->Usage & D3DUSAGE_DYNAMIC))
pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
hr = NineResource9_ctor(&This->base, pParams, pResource,
allocate && (pDesc->Pool == D3DPOOL_DEFAULT),
D3DRTYPE_SURFACE, pDesc->Pool, pDesc->Usage);
hr = NineResource9_ctor(&This->base, pParams, pResource, FALSE, D3DRTYPE_SURFACE,
pDesc->Pool, pDesc->Usage);
if (FAILED(hr))
return hr;
@@ -156,7 +174,7 @@ NineSurface9_ctor( struct NineSurface9 *This,
This->stride = nine_format_get_stride(This->base.info.format, pDesc->Width);
if (pResource && NineSurface9_IsOffscreenPlain(This))
if (pDesc->Usage & D3DUSAGE_DYNAMIC)
pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
/* TODO: investigate what else exactly needs to be cleared */