diff --git a/src/gallium/frontends/nine/cubetexture9.c b/src/gallium/frontends/nine/cubetexture9.c index a4259dce61e..052845be8a0 100644 --- a/src/gallium/frontends/nine/cubetexture9.c +++ b/src/gallium/frontends/nine/cubetexture9.c @@ -24,6 +24,7 @@ #include "device9.h" #include "cubetexture9.h" +#include "nine_memory_helper.h" #include "nine_helpers.h" #include "nine_pipe.h" @@ -45,7 +46,7 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This, unsigned i, l, f, offset, face_size = 0; unsigned *level_offsets = NULL; D3DSURFACE_DESC sfdesc; - void *p; + struct nine_allocation *p; HRESULT hr; DBG("This=%p pParams=%p EdgeLength=%u Levels=%u Usage=%d " @@ -118,7 +119,7 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This, face_size = nine_format_get_size_and_offsets(pf, level_offsets, EdgeLength, EdgeLength, This->base.level_count-1); - This->managed_buffer = align_calloc(6 * face_size, 32); + This->managed_buffer = nine_allocate(pParams->device->allocator, 6 * face_size); if (!This->managed_buffer) return E_OUTOFMEMORY; } @@ -145,8 +146,8 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This, offset = f * face_size; for (l = 0; l < This->base.level_count; l++) { sfdesc.Width = sfdesc.Height = u_minify(EdgeLength, l); - p = This->managed_buffer ? This->managed_buffer + offset + - level_offsets[l] : NULL; + p = This->managed_buffer ? + nine_suballocate(pParams->device->allocator, This->managed_buffer, offset + level_offsets[l]) : NULL; hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This), This->base.base.resource, p, D3DRTYPE_CUBETEXTURE, @@ -170,6 +171,7 @@ static void NineCubeTexture9_dtor( struct NineCubeTexture9 *This ) { unsigned i; + bool is_worker = nine_context_is_worker(This->base.base.base.device); DBG("This=%p\n", This); @@ -179,8 +181,12 @@ NineCubeTexture9_dtor( struct NineCubeTexture9 *This ) FREE(This->surfaces); } - if (This->managed_buffer) - align_free(This->managed_buffer); + if (This->managed_buffer) { + if (is_worker) + nine_free_worker(This->base.base.base.device->allocator, This->managed_buffer); + else + nine_free(This->base.base.base.device->allocator, This->managed_buffer); + } NineBaseTexture9_dtor(&This->base); } diff --git a/src/gallium/frontends/nine/cubetexture9.h b/src/gallium/frontends/nine/cubetexture9.h index 129789d0d69..ec787c9af8d 100644 --- a/src/gallium/frontends/nine/cubetexture9.h +++ b/src/gallium/frontends/nine/cubetexture9.h @@ -24,6 +24,7 @@ #define _NINE_CUBETEXTURE9_H_ #include "basetexture9.h" +#include "nine_memory_helper.h" #include "surface9.h" struct NineCubeTexture9 @@ -31,7 +32,7 @@ struct NineCubeTexture9 struct NineBaseTexture9 base; struct NineSurface9 **surfaces; struct pipe_box dirty_rect[6]; /* covers all mip levels */ - uint8_t *managed_buffer; + struct nine_allocation *managed_buffer; }; static inline struct NineCubeTexture9 * NineCubeTexture9( void *data ) diff --git a/src/gallium/frontends/nine/device9.c b/src/gallium/frontends/nine/device9.c index e9b2a5e75ee..1495eb7feaf 100644 --- a/src/gallium/frontends/nine/device9.c +++ b/src/gallium/frontends/nine/device9.c @@ -36,6 +36,7 @@ #include "volumetexture9.h" #include "nine_buffer_upload.h" #include "nine_helpers.h" +#include "nine_memory_helper.h" #include "nine_pipe.h" #include "nine_ff.h" #include "nine_dump.h" @@ -235,6 +236,8 @@ NineDevice9_ctor( struct NineDevice9 *This, /* Create first, it messes up our state. */ This->hud = hud_create(This->context.cso, NULL, NULL); /* NULL result is fine */ + This->allocator = nine_allocator_create(This); + /* Available memory counter. Updated only for allocations with this device * instance. This is the Win 7 behavior. * Win XP shares this counter across multiple devices. */ @@ -599,6 +602,9 @@ NineDevice9_dtor( struct NineDevice9 *This ) if (This->buffer_upload) nine_upload_destroy(This->buffer_upload); + if (This->allocator) + nine_allocator_destroy(This->allocator); + /* Destroy cso first */ if (This->context.cso) { cso_destroy_context(This->context.cso); } if (This->cso_sw) { cso_destroy_context(This->cso_sw); } diff --git a/src/gallium/frontends/nine/device9.h b/src/gallium/frontends/nine/device9.h index 7a75a5c1a75..974251f3fe9 100644 --- a/src/gallium/frontends/nine/device9.h +++ b/src/gallium/frontends/nine/device9.h @@ -29,6 +29,7 @@ #include "adapter9.h" #include "nine_helpers.h" +#include "nine_memory_helper.h" #include "nine_state.h" struct gen_mipmap_state; @@ -148,6 +149,8 @@ struct NineDevice9 struct hud_context *hud; /* NULL if hud is disabled */ + struct nine_allocator *allocator; + /* dummy vbo (containing 0 0 0 0) to bind if vertex shader input * is not bound to anything by the vertex declaration */ struct pipe_resource *dummy_vbo; diff --git a/src/gallium/frontends/nine/nine_state.h b/src/gallium/frontends/nine/nine_state.h index ab732c9ced9..cc76bef3418 100644 --- a/src/gallium/frontends/nine/nine_state.h +++ b/src/gallium/frontends/nine/nine_state.h @@ -24,6 +24,7 @@ #define _NINE_STATE_H_ #include "d3d9.h" +#include "iunknown.h" #include "nine_defines.h" #include "pipe/p_state.h" #include "util/list.h" diff --git a/src/gallium/frontends/nine/surface9.c b/src/gallium/frontends/nine/surface9.c index 7582104239f..eb7183fd07a 100644 --- a/src/gallium/frontends/nine/surface9.c +++ b/src/gallium/frontends/nine/surface9.c @@ -32,6 +32,7 @@ #include "nine_helpers.h" #include "nine_pipe.h" #include "nine_dump.h" +#include "nine_memory_helper.h" #include "nine_state.h" #include "pipe/p_context.h" @@ -52,7 +53,7 @@ NineSurface9_ctor( struct NineSurface9 *This, struct NineUnknownParams *pParams, struct NineUnknown *pContainer, struct pipe_resource *pResource, - void *user_buffer, + struct nine_allocation *user_buffer, uint8_t TextureType, unsigned Level, unsigned Layer, @@ -79,7 +80,7 @@ NineSurface9_ctor( struct NineSurface9 *This, /* 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; + This->data = user_buffer; multisample_type = pDesc->MultiSampleType; @@ -151,11 +152,11 @@ NineSurface9_ctor( struct NineSurface9 *This, * Do not use workaround by default as it eats more virtual space */ (pParams->device->workarounds.dynamic_texture_workaround && pDesc->Pool == D3DPOOL_DEFAULT && pDesc->Usage & D3DUSAGE_DYNAMIC)) { - This->data_internal = align_calloc( + This->data_internal = nine_allocate(pParams->device->allocator, nine_format_get_level_alloc_size(This->format_internal, pDesc->Width, pDesc->Height, - 0), 32); + 0)); if (!This->data_internal) return E_OUTOFMEMORY; This->stride_internal = nine_format_get_stride(This->format_internal, @@ -165,11 +166,11 @@ NineSurface9_ctor( struct NineSurface9 *This, 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_calloc( + This->data = nine_allocate(pParams->device->allocator, nine_format_get_level_alloc_size(This->base.info.format, pDesc->Width, pDesc->Height, - 0), 32); + 0)); if (!This->data) return E_OUTOFMEMORY; } @@ -209,6 +210,7 @@ NineSurface9_ctor( struct NineSurface9 *This, void NineSurface9_dtor( struct NineSurface9 *This ) { + bool is_worker = nine_context_is_worker(This->base.base.device); DBG("This=%p\n", This); if (This->transfer) { @@ -226,11 +228,25 @@ NineSurface9_dtor( struct NineSurface9 *This ) pipe_surface_reference(&This->surface[0], NULL); pipe_surface_reference(&This->surface[1], NULL); + if (!is_worker && This->lock_count && (This->data_internal || This->data)) { + /* For is_worker nine_free_worker will handle it */ + nine_pointer_strongrelease(This->base.base.device->allocator, + This->data_internal ? This->data_internal : This->data); + } + /* Release system memory when we have to manage it (no parent) */ - if (!This->base.base.container && This->data) - align_free(This->data); - if (This->data_internal) - align_free(This->data_internal); + if (This->data) { + if (is_worker) + nine_free_worker(This->base.base.device->allocator, This->data); + else + nine_free(This->base.base.device->allocator, This->data); + } + if (This->data_internal) { + if (is_worker) + nine_free_worker(This->base.base.device->allocator, This->data_internal); + else + nine_free(This->base.base.device->allocator, This->data_internal); + } NineResource9_dtor(&This->base); } @@ -489,11 +505,10 @@ NineSurface9_LockRect( struct NineSurface9 *This, if (This->data_internal || This->data) { enum pipe_format format = This->base.info.format; unsigned stride = This->stride; - uint8_t *data = This->data; + uint8_t *data = nine_get_pointer(This->base.base.device->allocator, This->data_internal ? This->data_internal : This->data); if (This->data_internal) { format = This->format_internal; stride = This->stride_internal; - data = This->data_internal; } /* ATI1 and ATI2 need special handling, because of d3d9 bug. * We must advertise to the application as if it is uncompressed @@ -562,15 +577,19 @@ NineSurface9_UnlockRect( struct NineSurface9 *This ) --This->lock_count; if (This->data_internal) { + nine_pointer_weakrelease(This->base.base.device->allocator, This->data_internal); if (This->data) { (void) util_format_translate(This->base.info.format, - This->data, This->stride, + nine_get_pointer(This->base.base.device->allocator, This->data), + This->stride, 0, 0, This->format_internal, - This->data_internal, + nine_get_pointer(This->base.base.device->allocator, This->data_internal), This->stride_internal, 0, 0, This->desc.Width, This->desc.Height); + nine_pointer_weakrelease(This->base.base.device->allocator, This->data); + nine_pointer_strongrelease(This->base.base.device->allocator, This->data_internal); } else { u_box_2d_zslice(0, 0, This->layer, This->desc.Width, This->desc.Height, &dst_box); @@ -584,12 +603,16 @@ NineSurface9_UnlockRect( struct NineSurface9 *This ) This->level, &dst_box, This->format_internal, - This->data_internal, + nine_get_pointer(This->base.base.device->allocator, This->data_internal), This->stride_internal, 0, /* depth = 1 */ &src_box); + nine_pointer_delayedstrongrelease(This->base.base.device->allocator, This->data_internal, &This->pending_uploads_counter); } + } else if (This->data) { + nine_pointer_weakrelease(This->base.base.device->allocator, This->data); } + return D3D_OK; } @@ -667,6 +690,20 @@ NineSurface9_CopyMemToDefault( struct NineSurface9 *This, u_box_2d_zslice(src_x, src_y, 0, copy_width, copy_height, &src_box); + if (This->data_internal) { + (void) util_format_translate(This->format_internal, + nine_get_pointer(This->base.base.device->allocator, This->data_internal), + This->stride_internal, + dst_x, dst_y, + From->base.info.format, + nine_get_pointer(This->base.base.device->allocator, From->data), + From->stride, + src_x, src_y, + copy_width, copy_height); + nine_pointer_weakrelease(This->base.base.device->allocator, From->data); + nine_pointer_strongrelease(This->base.base.device->allocator, This->data_internal); + } + nine_context_box_upload(This->base.base.device, &From->pending_uploads_counter, (struct NineUnknown *)From, @@ -674,9 +711,12 @@ NineSurface9_CopyMemToDefault( struct NineSurface9 *This, This->level, &dst_box, From->base.info.format, - From->data, From->stride, + nine_get_pointer(This->base.base.device->allocator, From->data), + From->stride, 0, /* depth = 1 */ &src_box); + nine_pointer_delayedstrongrelease(This->base.base.device->allocator, From->data, &From->pending_uploads_counter); + if (From->texture == D3DRTYPE_TEXTURE) { struct NineTexture9 *tex = NineTexture9(From->base.base.container); @@ -691,16 +731,6 @@ NineSurface9_CopyMemToDefault( struct NineSurface9 *This, nine_csmt_process(This->base.base.device); } - if (This->data_internal) - (void) util_format_translate(This->format_internal, - This->data_internal, - This->stride_internal, - dst_x, dst_y, - From->base.info.format, - From->data, From->stride, - src_x, src_y, - copy_width, copy_height); - NineSurface9_MarkContainerDirty(This); } @@ -731,7 +761,7 @@ NineSurface9_CopyDefaultToMem( struct NineSurface9 *This, p_src = pipe->transfer_map(pipe, r_src, From->level, PIPE_MAP_READ, &src_box, &transfer); - p_dst = This->data; + p_dst = nine_get_pointer(This->base.base.device->allocator, This->data); assert (p_src && p_dst); @@ -742,6 +772,8 @@ NineSurface9_CopyDefaultToMem( struct NineSurface9 *This, transfer->stride, 0, 0); pipe->transfer_unmap(pipe, transfer); + + nine_pointer_weakrelease(This->base.base.device->allocator, This->data); } @@ -779,9 +811,11 @@ NineSurface9_UploadSelf( struct NineSurface9 *This, This->level, &box, res->format, - This->data, This->stride, + nine_get_pointer(This->base.base.device->allocator, This->data), + This->stride, 0, /* depth = 1 */ &box); + nine_pointer_delayedstrongrelease(This->base.base.device->allocator, This->data, &This->pending_uploads_counter); return D3D_OK; } @@ -850,7 +884,7 @@ HRESULT NineSurface9_new( struct NineDevice9 *pDevice, struct NineUnknown *pContainer, struct pipe_resource *pResource, - void *user_buffer, + struct nine_allocation *user_buffer, uint8_t TextureType, unsigned Level, unsigned Layer, diff --git a/src/gallium/frontends/nine/surface9.h b/src/gallium/frontends/nine/surface9.h index ee700603bd8..9dc6576d546 100644 --- a/src/gallium/frontends/nine/surface9.h +++ b/src/gallium/frontends/nine/surface9.h @@ -23,6 +23,7 @@ #ifndef _NINE_SURFACE9_H_ #define _NINE_SURFACE9_H_ +#include "nine_memory_helper.h" #include "resource9.h" #include "pipe/p_state.h" @@ -46,8 +47,8 @@ struct NineSurface9 unsigned layer; D3DSURFACE_DESC desc; - uint8_t *data; /* system memory backing */ - uint8_t *data_internal; /* for conversions */ + struct nine_allocation *data; /* system memory backing */ + struct nine_allocation *data_internal; /* for conversions */ enum pipe_format format_internal; unsigned stride; /* for system memory backing */ unsigned stride_internal; @@ -64,7 +65,7 @@ HRESULT NineSurface9_new( struct NineDevice9 *pDevice, struct NineUnknown *pContainer, struct pipe_resource *pResource, - void *user_buffer, + struct nine_allocation *user_buffer, uint8_t TextureType, /* 0 if pContainer isn't BaseTexure9 */ unsigned Level, unsigned Layer, @@ -76,7 +77,7 @@ NineSurface9_ctor( struct NineSurface9 *This, struct NineUnknownParams *pParams, struct NineUnknown *pContainer, struct pipe_resource *pResource, - void *user_buffer, + struct nine_allocation *user_buffer, uint8_t TextureType, unsigned Level, unsigned Layer, diff --git a/src/gallium/frontends/nine/texture9.c b/src/gallium/frontends/nine/texture9.c index b1a45763b81..3163b8550b7 100644 --- a/src/gallium/frontends/nine/texture9.c +++ b/src/gallium/frontends/nine/texture9.c @@ -26,6 +26,7 @@ #include "surface9.h" #include "texture9.h" #include "nine_helpers.h" +#include "nine_memory_helper.h" #include "nine_pipe.h" #include "nine_dump.h" @@ -53,7 +54,7 @@ NineTexture9_ctor( struct NineTexture9 *This, unsigned l; D3DSURFACE_DESC sfdesc; HRESULT hr; - void *user_buffer = NULL, *user_buffer_for_level; + struct nine_allocation *user_buffer = NULL, *user_buffer_for_level; DBG("(%p) Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s " "pSharedHandle=%p\n", This, Width, Height, Levels, @@ -155,17 +156,17 @@ NineTexture9_ctor( struct NineTexture9 *This, This->base.pstype = (Height == 1) ? 1 : 0; if (pSharedHandle && *pSharedHandle) { /* Pool == D3DPOOL_SYSTEMMEM */ - user_buffer = (void *)*pSharedHandle; + user_buffer = nine_wrap_external_pointer(pParams->device->allocator, (void *)*pSharedHandle); level_offsets = alloca(sizeof(unsigned) * This->base.level_count); (void) nine_format_get_size_and_offsets(pf, level_offsets, Width, Height, This->base.level_count-1); } else if (Pool != D3DPOOL_DEFAULT) { level_offsets = alloca(sizeof(unsigned) * This->base.level_count); - user_buffer = align_calloc( + user_buffer = nine_allocate(pParams->device->allocator, nine_format_get_size_and_offsets(pf, level_offsets, Width, Height, - This->base.level_count-1), 32); + This->base.level_count-1)); This->managed_buffer = user_buffer; if (!This->managed_buffer) return E_OUTOFMEMORY; @@ -191,8 +192,8 @@ NineTexture9_ctor( struct NineTexture9 *This, sfdesc.Height = u_minify(Height, l); /* Some apps expect the memory to be allocated in * continous blocks */ - user_buffer_for_level = user_buffer ? user_buffer + - level_offsets[l] : NULL; + user_buffer_for_level = user_buffer ? + nine_suballocate(pParams->device->allocator, user_buffer, level_offsets[l]) : NULL; hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This), This->base.base.resource, user_buffer_for_level, @@ -217,6 +218,7 @@ NineTexture9_ctor( struct NineTexture9 *This, static void NineTexture9_dtor( struct NineTexture9 *This ) { + bool is_worker = nine_context_is_worker(This->base.base.base.device); unsigned l; DBG("This=%p\n", This); @@ -229,8 +231,12 @@ NineTexture9_dtor( struct NineTexture9 *This ) FREE(This->surfaces); } - if (This->managed_buffer) - align_free(This->managed_buffer); + if (This->managed_buffer) { + if (is_worker) + nine_free_worker(This->base.base.base.device->allocator, This->managed_buffer); + else + nine_free(This->base.base.base.device->allocator, This->managed_buffer); + } NineBaseTexture9_dtor(&This->base); } diff --git a/src/gallium/frontends/nine/texture9.h b/src/gallium/frontends/nine/texture9.h index 3911f26d468..f577382cb38 100644 --- a/src/gallium/frontends/nine/texture9.h +++ b/src/gallium/frontends/nine/texture9.h @@ -24,6 +24,7 @@ #define _NINE_TEXTURE9_H_ #include "basetexture9.h" +#include "nine_memory_helper.h" #include "surface9.h" struct NineTexture9 @@ -31,7 +32,7 @@ struct NineTexture9 struct NineBaseTexture9 base; struct NineSurface9 **surfaces; struct pipe_box dirty_rect; /* covers all mip levels */ - uint8_t *managed_buffer; + struct nine_allocation *managed_buffer; }; static inline struct NineTexture9 * NineTexture9( void *data )