nv50: make mm available as common code

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Ben Skeggs
2011-03-01 10:27:45 +10:00
parent 7a8ee058a8
commit 2f30a5bdaa
9 changed files with 82 additions and 70 deletions
+2 -1
View File
@@ -8,6 +8,7 @@ LIBRARY_INCLUDES = \
-I$(TOP)/src/gallium/drivers/nouveau/include
C_SOURCES = nouveau_screen.c \
nouveau_fence.c
nouveau_fence.c \
nouveau_mm.c
include ../../Makefile.template
@@ -3,7 +3,10 @@
#include "util/u_memory.h"
#include "util/u_double_list.h"
#include "nv50_screen.h"
#include "nouveau_screen.h"
#include "nouveau_mm.h"
#include "nouveau/nouveau_bo.h"
#define MM_MIN_ORDER 7
#define MM_MAX_ORDER 20
@@ -20,7 +23,7 @@ struct mm_bucket {
int num_free;
};
struct nv50_mman {
struct nouveau_mman {
struct nouveau_device *dev;
struct mm_bucket bucket[MM_NUM_BUCKETS];
uint32_t storage_type;
@@ -31,7 +34,7 @@ struct nv50_mman {
struct mm_slab {
struct list_head head;
struct nouveau_bo *bo;
struct nv50_mman *cache;
struct nouveau_mman *cache;
int order;
int count;
int free;
@@ -79,7 +82,7 @@ mm_get_order(uint32_t size)
}
static struct mm_bucket *
mm_bucket_by_order(struct nv50_mman *cache, int order)
mm_bucket_by_order(struct nouveau_mman *cache, int order)
{
if (order > MM_MAX_ORDER)
return NULL;
@@ -87,7 +90,7 @@ mm_bucket_by_order(struct nv50_mman *cache, int order)
}
static struct mm_bucket *
mm_bucket_by_size(struct nv50_mman *cache, unsigned size)
mm_bucket_by_size(struct nouveau_mman *cache, unsigned size)
{
return mm_bucket_by_order(cache, mm_get_order(size));
}
@@ -107,7 +110,7 @@ mm_default_slab_size(unsigned chunk_order)
}
static int
mm_slab_new(struct nv50_mman *cache, int chunk_order)
mm_slab_new(struct nouveau_mman *cache, int chunk_order)
{
struct mm_slab *slab;
int words, ret;
@@ -147,13 +150,13 @@ mm_slab_new(struct nv50_mman *cache, int chunk_order)
}
/* @return token to identify slab or NULL if we just allocated a new bo */
struct nv50_mm_allocation *
nv50_mm_allocate(struct nv50_mman *cache,
struct nouveau_mm_allocation *
nouveau_mm_allocate(struct nouveau_mman *cache,
uint32_t size, struct nouveau_bo **bo, uint32_t *offset)
{
struct mm_bucket *bucket;
struct mm_slab *slab;
struct nv50_mm_allocation *alloc;
struct nouveau_mm_allocation *alloc;
int ret;
bucket = mm_bucket_by_size(cache, size);
@@ -181,7 +184,7 @@ nv50_mm_allocate(struct nv50_mman *cache,
*offset = mm_slab_alloc(slab) << slab->order;
alloc = MALLOC_STRUCT(nv50_mm_allocation);
alloc = MALLOC_STRUCT(nouveau_mm_allocation);
if (!alloc)
return NULL;
@@ -200,7 +203,7 @@ nv50_mm_allocate(struct nv50_mman *cache,
}
void
nv50_mm_free(struct nv50_mm_allocation *alloc)
nouveau_mm_free(struct nouveau_mm_allocation *alloc)
{
struct mm_slab *slab = (struct mm_slab *)alloc->priv;
struct mm_bucket *bucket = mm_bucket_by_order(slab->cache, slab->order);
@@ -219,11 +222,11 @@ nv50_mm_free(struct nv50_mm_allocation *alloc)
FREE(alloc);
}
struct nv50_mman *
nv50_mm_create(struct nouveau_device *dev, uint32_t domain,
struct nouveau_mman *
nouveau_mm_create(struct nouveau_device *dev, uint32_t domain,
uint32_t storage_type)
{
struct nv50_mman *cache = MALLOC_STRUCT(nv50_mman);
struct nouveau_mman *cache = MALLOC_STRUCT(nouveau_mman);
int i;
if (!cache)
@@ -244,7 +247,7 @@ nv50_mm_create(struct nouveau_device *dev, uint32_t domain,
}
static INLINE void
nv50_mm_free_slabs(struct list_head *head)
nouveau_mm_free_slabs(struct list_head *head)
{
struct mm_slab *slab, *next;
@@ -256,7 +259,7 @@ nv50_mm_free_slabs(struct list_head *head)
}
void
nv50_mm_destroy(struct nv50_mman *cache)
nouveau_mm_destroy(struct nouveau_mman *cache)
{
int i;
@@ -269,9 +272,9 @@ nv50_mm_destroy(struct nv50_mman *cache)
debug_printf("WARNING: destroying GPU memory cache "
"with some buffers still in use\n");
nv50_mm_free_slabs(&cache->bucket[i].free);
nv50_mm_free_slabs(&cache->bucket[i].used);
nv50_mm_free_slabs(&cache->bucket[i].full);
nouveau_mm_free_slabs(&cache->bucket[i].free);
nouveau_mm_free_slabs(&cache->bucket[i].used);
nouveau_mm_free_slabs(&cache->bucket[i].full);
}
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef __NOUVEAU_MM_H__
#define __NOUVEAU_MM_H__
struct nouveau_mman;
/* Since a resource can be migrated, we need to decouple allocations from
* them. This struct is linked with fences for delayed freeing of allocs.
*/
struct nouveau_mm_allocation {
struct nouveau_mm_allocation *next;
void *priv;
uint32_t offset;
};
extern struct nouveau_mman *
nouveau_mm_create(struct nouveau_device *, uint32_t domain,
uint32_t storage_type);
extern void
nouveau_mm_destroy(struct nouveau_mman *);
extern struct nouveau_mm_allocation *
nouveau_mm_allocate(struct nouveau_mman *, uint32_t size,
struct nouveau_bo **, uint32_t *offset);
extern void
nouveau_mm_free(struct nouveau_mm_allocation *);
#endif // __NOUVEAU_MM_H__
-1
View File
@@ -26,7 +26,6 @@ C_SOURCES = \
nv50_pc_optimize.c \
nv50_pc_regalloc.c \
nv50_push.c \
nv50_mm.c \
nv50_query.c
LIBRARY_INCLUDES = \
+13 -12
View File
@@ -6,6 +6,7 @@
#define NOUVEAU_NVC0
#include "nouveau/nouveau_screen.h"
#include "nouveau/nouveau_winsys.h"
#include "nouveau/nouveau_mm.h"
#undef NOUVEAU_NVC0
#include "nv50_context.h"
@@ -26,14 +27,14 @@ nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf,
unsigned domain)
{
if (domain == NOUVEAU_BO_VRAM) {
buf->mm = nv50_mm_allocate(screen->mm_VRAM, buf->base.width0, &buf->bo,
&buf->offset);
buf->mm = nouveau_mm_allocate(screen->mm_VRAM, buf->base.width0, &buf->bo,
&buf->offset);
if (!buf->bo)
return nv50_buffer_allocate(screen, buf, NOUVEAU_BO_GART);
} else
if (domain == NOUVEAU_BO_GART) {
buf->mm = nv50_mm_allocate(screen->mm_GART, buf->base.width0, &buf->bo,
&buf->offset);
buf->mm = nouveau_mm_allocate(screen->mm_GART, buf->base.width0, &buf->bo,
&buf->offset);
if (!buf->bo)
return FALSE;
}
@@ -49,9 +50,9 @@ nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf,
}
static INLINE void
release_allocation(struct nv50_mm_allocation **mm, struct nouveau_fence *fence)
release_allocation(struct nouveau_mm_allocation **mm, struct nouveau_fence *fence)
{
nouveau_fence_work(fence, nv50_mm_free, *mm);
nouveau_fence_work(fence, nouveau_mm_free, *mm);
(*mm) = NULL;
}
@@ -94,13 +95,13 @@ boolean
nv50_buffer_download(struct nv50_context *nv50, struct nv50_resource *buf,
unsigned start, unsigned size)
{
struct nv50_mm_allocation *mm;
struct nouveau_mm_allocation *mm;
struct nouveau_bo *bounce = NULL;
uint32_t offset;
assert(buf->domain == NOUVEAU_BO_VRAM);
mm = nv50_mm_allocate(nv50->screen->mm_GART, size, &bounce, &offset);
mm = nouveau_mm_allocate(nv50->screen->mm_GART, size, &bounce, &offset);
if (!bounce)
return FALSE;
@@ -117,7 +118,7 @@ nv50_buffer_download(struct nv50_context *nv50, struct nv50_resource *buf,
nouveau_bo_ref(NULL, &bounce);
if (mm)
nv50_mm_free(mm);
nouveau_mm_free(mm);
return TRUE;
}
@@ -125,7 +126,7 @@ static boolean
nv50_buffer_upload(struct nv50_context *nv50, struct nv50_resource *buf,
unsigned start, unsigned size)
{
struct nv50_mm_allocation *mm;
struct nouveau_mm_allocation *mm;
struct nouveau_bo *bounce = NULL;
uint32_t offset;
@@ -135,7 +136,7 @@ nv50_buffer_upload(struct nv50_context *nv50, struct nv50_resource *buf,
return TRUE;
}
mm = nv50_mm_allocate(nv50->screen->mm_GART, size, &bounce, &offset);
mm = nouveau_mm_allocate(nv50->screen->mm_GART, size, &bounce, &offset);
if (!bounce)
return FALSE;
@@ -429,7 +430,7 @@ nv50_buffer_migrate(struct nv50_context *nv50,
FREE(buf->data);
} else
if (old_domain != 0 && new_domain != 0) {
struct nv50_mm_allocation *mm = buf->mm;
struct nouveau_mm_allocation *mm = buf->mm;
if (new_domain == NOUVEAU_BO_VRAM) {
/* keep a system memory copy of our data in case we hit a fallback */
+4 -4
View File
@@ -41,7 +41,7 @@ struct nv50_query {
uint32_t offset; /* base + i * 16 */
boolean ready;
boolean is64bit;
struct nv50_mm_allocation *mm;
struct nouveau_mm_allocation *mm;
};
#define NV50_QUERY_ALLOC_SPACE 128
@@ -62,13 +62,13 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size)
nouveau_bo_ref(NULL, &q->bo);
if (q->mm) {
if (q->ready)
nv50_mm_free(q->mm);
nouveau_mm_free(q->mm);
else
nouveau_fence_work(screen->base.fence.current, nv50_mm_free, q->mm);
nouveau_fence_work(screen->base.fence.current, nouveau_mm_free, q->mm);
}
}
if (size) {
q->mm = nv50_mm_allocate(screen->mm_GART, size, &q->bo, &q->base);
q->mm = nouveau_mm_allocate(screen->mm_GART, size, &q->bo, &q->base);
if (!q->bo)
return FALSE;
q->offset = q->base;
+1 -1
View File
@@ -46,7 +46,7 @@ struct nv50_resource {
struct nouveau_fence *fence;
struct nouveau_fence *fence_wr;
struct nv50_mm_allocation *mm;
struct nouveau_mm_allocation *mm;
};
void
+7 -7
View File
@@ -229,9 +229,9 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
if (screen->tic.entries)
FREE(screen->tic.entries);
nv50_mm_destroy(screen->mm_GART);
nv50_mm_destroy(screen->mm_VRAM);
nv50_mm_destroy(screen->mm_VRAM_fe0);
nouveau_mm_destroy(screen->mm_GART);
nouveau_mm_destroy(screen->mm_VRAM);
nouveau_mm_destroy(screen->mm_VRAM_fe0);
nouveau_grobj_free(&screen->tesla);
nouveau_grobj_free(&screen->eng2d);
@@ -586,10 +586,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
screen->tic.entries = CALLOC(4096, sizeof(void *));
screen->tsc.entries = screen->tic.entries + 2048;
screen->mm_GART = nv50_mm_create(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
0x000);
screen->mm_VRAM = nv50_mm_create(dev, NOUVEAU_BO_VRAM, 0x000);
screen->mm_VRAM_fe0 = nv50_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0);
screen->mm_GART = nouveau_mm_create(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
0x000);
screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0x000);
screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0);
nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
+4 -25
View File
@@ -4,6 +4,7 @@
#define NOUVEAU_NVC0
#include "nouveau/nouveau_screen.h"
#include "nouveau/nouveau_fence.h"
#include "nouveau/nouveau_mm.h"
#undef NOUVEAU_NVC0
#include "nv50_winsys.h"
#include "nv50_stateobj.h"
@@ -11,7 +12,6 @@
#define NV50_TIC_MAX_ENTRIES 2048
#define NV50_TSC_MAX_ENTRIES 2048
struct nv50_mman;
struct nv50_context;
#define NV50_SCRATCH_SIZE (2 << 20)
@@ -54,9 +54,9 @@ struct nv50_screen {
struct nouveau_notifier *sync;
struct nv50_mman *mm_GART;
struct nv50_mman *mm_VRAM;
struct nv50_mman *mm_VRAM_fe0;
struct nouveau_mman *mm_GART;
struct nouveau_mman *mm_VRAM;
struct nouveau_mman *mm_VRAM_fe0;
struct nouveau_grobj *tesla;
struct nouveau_grobj *eng2d;
@@ -69,27 +69,6 @@ nv50_screen(struct pipe_screen *screen)
return (struct nv50_screen *)screen;
}
/* Since a resource can be migrated, we need to decouple allocations from
* them. This struct is linked with fences for delayed freeing of allocs.
*/
struct nv50_mm_allocation {
struct nv50_mm_allocation *next;
void *priv;
uint32_t offset;
};
extern struct nv50_mman *
nv50_mm_create(struct nouveau_device *, uint32_t domain, uint32_t storage_type);
extern void
nv50_mm_destroy(struct nv50_mman *);
extern struct nv50_mm_allocation *
nv50_mm_allocate(struct nv50_mman *,
uint32_t size, struct nouveau_bo **, uint32_t *offset);
extern void
nv50_mm_free(struct nv50_mm_allocation *);
void nv50_screen_make_buffers_resident(struct nv50_screen *);
int nv50_screen_tic_alloc(struct nv50_screen *, void *);