From ba0274c7d6c3b77a36bbe1b444f427b0c873e2f3 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Thu, 15 Sep 2016 20:28:17 +0200 Subject: [PATCH] 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 Signed-off-by: Axel Davy --- src/gallium/state_trackers/nine/device9.c | 54 +++----------------- src/gallium/state_trackers/nine/surface9.c | 58 ++++++++++++++-------- 2 files changed, 44 insertions(+), 68 deletions(-) diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c index 298af86e484..50565b876dd 100644 --- a/src/gallium/state_trackers/nine/device9.c +++ b/src/gallium/state_trackers/nine/device9.c @@ -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); + hr = NineSurface9_new(This, NULL, NULL, NULL, 0, 0, 0, &desc, &surface); + if (SUCCEEDED(hr)) { + *ppSurface = (IDirect3DSurface9 *)surface; - user_assert(!(Width % w) && !(Height % h), D3DERR_INVALIDCALL); + if (surface->base.resource && Discard_or_Lockable && (type != 1)) + surface->base.resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; } - 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)) - *ppSurface = (IDirect3DSurface9 *)surface; return hr; } diff --git a/src/gallium/state_trackers/nine/surface9.c b/src/gallium/state_trackers/nine/surface9.c index 508fa9a508d..e6a48e2041b 100644 --- a/src/gallium/state_trackers/nine/surface9.c +++ b/src/gallium/state_trackers/nine/surface9.c @@ -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 */ -- 2.30.2