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:
committed by
Axel Davy
parent
1f65f67b21
commit
ba0274c7d6
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user