From f70f79f6f6027bdf2f7de09bb39e12a24420f338 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 16 Sep 2010 20:22:09 +1000 Subject: r600g: attempt to abstract kernel bos from pipe driver. introduce an abstraction layer between kernel bos and the winsys BOs. this is to allow plugging in pb manager with minimal disruption to pipe driver. --- src/gallium/winsys/r600/drm/Makefile | 3 +- src/gallium/winsys/r600/drm/r600_drm.c | 23 ----------- src/gallium/winsys/r600/drm/r600_state.c | 22 +++++------ src/gallium/winsys/r600/drm/radeon_bo.c | 34 +++++++--------- src/gallium/winsys/r600/drm/radeon_ctx.c | 35 +++++++++-------- src/gallium/winsys/r600/drm/radeon_priv.h | 30 +++++++++++++- src/gallium/winsys/r600/drm/radeon_state.c | 2 +- src/gallium/winsys/r600/drm/radeon_ws_bo.c | 63 ++++++++++++++++++++++++++++++ 8 files changed, 140 insertions(+), 72 deletions(-) create mode 100644 src/gallium/winsys/r600/drm/radeon_ws_bo.c (limited to 'src/gallium/winsys/r600') diff --git a/src/gallium/winsys/r600/drm/Makefile b/src/gallium/winsys/r600/drm/Makefile index e3b943c4d4..86688a213c 100644 --- a/src/gallium/winsys/r600/drm/Makefile +++ b/src/gallium/winsys/r600/drm/Makefile @@ -13,7 +13,8 @@ C_SOURCES = \ radeon_bo.c \ radeon_pciid.c \ radeon.c \ - r600_drm.c + r600_drm.c \ + radeon_ws_bo.c LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r600 \ $(shell pkg-config libdrm --cflags-only-I) diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c index c76e7f5fa5..bbf53fcbdc 100644 --- a/src/gallium/winsys/r600/drm/r600_drm.c +++ b/src/gallium/winsys/r600/drm/r600_drm.c @@ -39,26 +39,3 @@ struct radeon *r600_drm_winsys_create(int drmfd) return radeon_new(drmfd, 0); } -boolean r600_buffer_get_handle(struct radeon *rw, - struct pipe_resource *buf, - struct winsys_handle *whandle) -{ - struct drm_gem_flink flink; - struct r600_resource* rbuffer = (struct r600_resource*)buf; - - if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { - if (!rbuffer->flink) { - flink.handle = rbuffer->bo->handle; - - if (ioctl(rw->fd, DRM_IOCTL_GEM_FLINK, &flink)) { - return FALSE; - } - - rbuffer->flink = flink.name; - } - whandle->handle = rbuffer->flink; - } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { - whandle->handle = rbuffer->bo->handle; - } - return TRUE; -} diff --git a/src/gallium/winsys/r600/drm/r600_state.c b/src/gallium/winsys/r600/drm/r600_state.c index b8ef89dfd6..82eb0cc863 100644 --- a/src/gallium/winsys/r600/drm/r600_state.c +++ b/src/gallium/winsys/r600/drm/r600_state.c @@ -155,7 +155,7 @@ static int r600_state_pm4_bytecode(struct radeon_state *state, unsigned offset, r = radeon_state_reloc(state, state->cpm4, regs[id + i].bo_id); if (r) return r; - state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle; + state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->bo->handle; } } return 0; @@ -172,7 +172,7 @@ static int r600_state_pm4_bytecode(struct radeon_state *state, unsigned offset, r = radeon_state_reloc(state, state->cpm4, regs[id + i].bo_id); if (r) return r; - state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle; + state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->bo->handle; } } return 0; @@ -220,7 +220,7 @@ static int eg_state_pm4_bytecode(struct radeon_state *state, unsigned offset, un r = radeon_state_reloc(state, state->cpm4, regs[id + i].bo_id); if (r) return r; - state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle; + state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->bo->handle; } } return 0; @@ -237,7 +237,7 @@ static int eg_state_pm4_bytecode(struct radeon_state *state, unsigned offset, un r = radeon_state_reloc(state, state->cpm4, regs[id + i].bo_id); if (r) return r; - state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle; + state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->bo->handle; } } return 0; @@ -318,7 +318,7 @@ static void r600_state_pm4_with_flush(struct radeon_state *state, u32 flags, int } } for (i = 0; i < state->nreloc; i++) { - size = (state->bo[state->reloc_bo_id[i]]->size + 255) >> 8; + size = (state->bo[state->reloc_bo_id[i]]->bo->size + 255) >> 8; state->pm4[state->cpm4++] = PKT3(PKT3_SURFACE_SYNC, 3); if (bufs_are_cbs) flags |= S_0085F0_CB0_DEST_BASE_ENA(1 << i); @@ -328,7 +328,7 @@ static void r600_state_pm4_with_flush(struct radeon_state *state, u32 flags, int state->pm4[state->cpm4++] = 0x0000000A; state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0); state->reloc_pm4_id[i] = state->cpm4; - state->pm4[state->cpm4++] = state->bo[state->reloc_bo_id[i]]->handle; + state->pm4[state->cpm4++] = state->bo[state->reloc_bo_id[i]]->bo->handle; } } @@ -384,7 +384,7 @@ static int r600_state_pm4_query_begin(struct radeon_state *state) r = radeon_state_reloc(state, state->cpm4, 0); if (r) return r; - state->pm4[state->cpm4++] = state->bo[0]->handle; + state->pm4[state->cpm4++] = state->bo[0]->bo->handle; return 0; } @@ -401,7 +401,7 @@ static int r600_state_pm4_query_end(struct radeon_state *state) r = radeon_state_reloc(state, state->cpm4, 0); if (r) return r; - state->pm4[state->cpm4++] = state->bo[0]->handle; + state->pm4[state->cpm4++] = state->bo[0]->bo->handle; return 0; } @@ -486,7 +486,7 @@ static int r600_state_pm4_draw(struct radeon_state *state) r = radeon_state_reloc(state, state->cpm4, 0); if (r) return r; - state->pm4[state->cpm4++] = state->bo[0]->handle; + state->pm4[state->cpm4++] = state->bo[0]->bo->handle; } else { state->pm4[state->cpm4++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1); state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_NUM_INDICES]; @@ -572,13 +572,13 @@ static int r600_state_pm4_resource(struct radeon_state *state) r = radeon_state_reloc(state, state->cpm4, 0); if (r) return r; - state->pm4[state->cpm4++] = state->bo[0]->handle; + state->pm4[state->cpm4++] = state->bo[0]->bo->handle; if (type == 2) { state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0); r = radeon_state_reloc(state, state->cpm4, 1); if (r) return r; - state->pm4[state->cpm4++] = state->bo[1]->handle; + state->pm4[state->cpm4++] = state->bo[1]->bo->handle; } return 0; } diff --git a/src/gallium/winsys/r600/drm/radeon_bo.c b/src/gallium/winsys/r600/drm/radeon_bo.c index f79135bfa1..e8604a82db 100644 --- a/src/gallium/winsys/r600/drm/radeon_bo.c +++ b/src/gallium/winsys/r600/drm/radeon_bo.c @@ -45,7 +45,7 @@ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle, } bo->size = size; bo->handle = handle; - bo->refcount = 1; + pipe_reference_init(&bo->reference, 1); bo->alignment = alignment; if (handle) { @@ -82,7 +82,8 @@ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle, if (ptr) { if (radeon_bo_map(radeon, bo)) { fprintf(stderr, "%s failed to copy data into bo\n", __func__); - return radeon_bo_decref(radeon, bo); + radeon_bo_reference(radeon, &bo, NULL); + return bo; } memcpy(bo->data, ptr, size); radeon_bo_unmap(radeon, bo); @@ -133,31 +134,26 @@ void radeon_bo_unmap(struct radeon *radeon, struct radeon_bo *bo) bo->data = NULL; } -struct radeon_bo *radeon_bo_incref(struct radeon *radeon, struct radeon_bo *bo) -{ - bo->refcount++; - return bo; -} - -struct radeon_bo *radeon_bo_decref(struct radeon *radeon, struct radeon_bo *bo) +static void radeon_bo_destroy(struct radeon *radeon, struct radeon_bo *bo) { struct drm_gem_close args; - if (bo == NULL) - return NULL; - if (--bo->refcount > 0) { - return NULL; - } - - if (bo->map_count) { - munmap(bo->data, bo->size); - } memset(&args, 0, sizeof(args)); args.handle = bo->handle; drmIoctl(radeon->fd, DRM_IOCTL_GEM_CLOSE, &args); memset(bo, 0, sizeof(struct radeon_bo)); free(bo); - return NULL; +} + +void radeon_bo_reference(struct radeon *radeon, + struct radeon_bo **dst, + struct radeon_bo *src) +{ + struct radeon_bo *old = *dst; + if (pipe_reference(&(*dst)->reference, &src->reference)) { + radeon_bo_destroy(radeon, old); + } + *dst = src; } int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo) diff --git a/src/gallium/winsys/r600/drm/radeon_ctx.c b/src/gallium/winsys/r600/drm/radeon_ctx.c index 9f166b209a..d6e58451b8 100644 --- a/src/gallium/winsys/r600/drm/radeon_ctx.c +++ b/src/gallium/winsys/r600/drm/radeon_ctx.c @@ -30,24 +30,26 @@ #include "radeon_drm.h" #include "bof.h" -static int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_bo *bo) +static int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_ws_bo *bo) { if (ctx->nbo >= RADEON_CTX_MAX_PM4) return -EBUSY; - ctx->bo[ctx->nbo] = radeon_bo_incref(ctx->radeon, bo); + radeon_ws_bo_reference(ctx->radeon, &ctx->bo[ctx->nbo], bo); ctx->nbo++; return 0; } -static struct radeon_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc) +static struct radeon_ws_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc) { struct radeon_cs_reloc *greloc; unsigned i; + struct radeon_ws_bo *bo; greloc = (void *)(((u8 *)ctx->reloc) + reloc * 4); for (i = 0; i < ctx->nbo; i++) { - if (ctx->bo[i]->handle == greloc->handle) { - return radeon_bo_incref(ctx->radeon, ctx->bo[i]); + if (ctx->bo[i]->bo->handle == greloc->handle) { + radeon_ws_bo_reference(ctx->radeon, &bo, ctx->bo[i]); + return bo; } } fprintf(stderr, "%s no bo for reloc[%d 0x%08X] %d\n", __func__, reloc, greloc->handle, ctx->nbo); @@ -63,7 +65,7 @@ static void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 placement[1] = 0; greloc = (void *)(((u8 *)ctx->reloc) + reloc * 4); for (i = 0; i < ctx->nbo; i++) { - if (ctx->bo[i]->handle == greloc->handle) { + if (ctx->bo[i]->bo->handle == greloc->handle) { placement[0] = greloc->read_domain | greloc->write_domain; placement[1] = placement[0]; return; @@ -74,7 +76,7 @@ static void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 void radeon_ctx_clear(struct radeon_ctx *ctx) { for (int i = 0; i < ctx->nbo; i++) { - ctx->bo[i] = radeon_bo_decref(ctx->radeon, ctx->bo[i]); + radeon_ws_bo_reference(ctx->radeon, &ctx->bo[i], NULL); } ctx->ndwords = RADEON_CTX_MAX_PM4; ctx->cdwords = 0; @@ -116,7 +118,7 @@ void radeon_ctx_fini(struct radeon_ctx *ctx) return; for (i = 0; i < ctx->nbo; i++) { - ctx->bo[i] = radeon_bo_decref(ctx->radeon, ctx->bo[i]); + radeon_ws_bo_reference(ctx->radeon, &ctx->bo[i], NULL); } ctx->radeon = radeon_decref(ctx->radeon); free(ctx->bo); @@ -178,13 +180,13 @@ int radeon_ctx_submit(struct radeon_ctx *ctx) return r; } -static int radeon_ctx_reloc(struct radeon_ctx *ctx, struct radeon_bo *bo, +static int radeon_ctx_reloc(struct radeon_ctx *ctx, struct radeon_ws_bo *bo, unsigned id, unsigned *placement) { unsigned i; for (i = 0; i < ctx->nreloc; i++) { - if (ctx->reloc[i].handle == bo->handle) { + if (ctx->reloc[i].handle == bo->bo->handle) { ctx->pm4[id] = i * sizeof(struct radeon_cs_reloc) / 4; return 0; } @@ -192,7 +194,7 @@ static int radeon_ctx_reloc(struct radeon_ctx *ctx, struct radeon_bo *bo, if (ctx->nreloc >= RADEON_CTX_MAX_PM4) { return -EBUSY; } - ctx->reloc[ctx->nreloc].handle = bo->handle; + ctx->reloc[ctx->nreloc].handle = bo->bo->handle; ctx->reloc[ctx->nreloc].read_domain = placement[0] | placement [1]; ctx->reloc[ctx->nreloc].write_domain = placement[0] | placement [1]; ctx->reloc[ctx->nreloc].flags = 0; @@ -307,6 +309,7 @@ void radeon_ctx_dump_bof(struct radeon_ctx *ctx, const char *file) { bof_t *bcs, *blob, *array, *bo, *size, *handle, *device_id, *root; unsigned i; + void *data; root = device_id = bcs = blob = array = bo = size = handle = NULL; root = bof_object(); @@ -343,23 +346,23 @@ void radeon_ctx_dump_bof(struct radeon_ctx *ctx, const char *file) bo = bof_object(); if (bo == NULL) goto out_err; - size = bof_int32(ctx->bo[i]->size); + size = bof_int32(ctx->bo[i]->bo->size); if (size == NULL) goto out_err; if (bof_object_set(bo, "size", size)) goto out_err; bof_decref(size); size = NULL; - handle = bof_int32(ctx->bo[i]->handle); + handle = bof_int32(ctx->bo[i]->bo->handle); if (handle == NULL) goto out_err; if (bof_object_set(bo, "handle", handle)) goto out_err; bof_decref(handle); handle = NULL; - radeon_bo_map(ctx->radeon, ctx->bo[i]); - blob = bof_blob(ctx->bo[i]->size, ctx->bo[i]->data); - radeon_bo_unmap(ctx->radeon, ctx->bo[i]); + data = radeon_ws_bo_map(ctx->radeon, ctx->bo[i]); + blob = bof_blob(ctx->bo[i]->bo->size, data); + radeon_ws_bo_unmap(ctx->radeon, ctx->bo[i]); if (blob == NULL) goto out_err; if (bof_object_set(bo, "data", blob)) diff --git a/src/gallium/winsys/r600/drm/radeon_priv.h b/src/gallium/winsys/r600/drm/radeon_priv.h index b5a4eeae6b..6bd8d9850f 100644 --- a/src/gallium/winsys/r600/drm/radeon_priv.h +++ b/src/gallium/winsys/r600/drm/radeon_priv.h @@ -23,9 +23,14 @@ #include #include "radeon.h" +#include "pipe/p_compiler.h" +#include "util/u_inlines.h" +#include "pipe/p_defines.h" + struct radeon; struct radeon_ctx; + /* * radeon functions */ @@ -37,6 +42,15 @@ struct radeon_register { char name[64]; }; +struct radeon_bo { + struct pipe_reference reference; + unsigned handle; + unsigned size; + unsigned alignment; + unsigned map_count; + void *data; +}; + struct radeon_sub_type { int shader_type; const struct radeon_register *regs; @@ -61,7 +75,7 @@ struct radeon_ctx { unsigned nreloc; struct radeon_cs_reloc *reloc; unsigned nbo; - struct radeon_bo **bo; + struct radeon_ws_bo **bo; }; struct radeon { @@ -74,6 +88,11 @@ struct radeon { unsigned max_states; }; +struct radeon_ws_bo { + struct pipe_reference reference; + struct radeon_bo *bo; +}; + extern struct radeon *radeon_new(int fd, unsigned device); extern struct radeon *radeon_incref(struct radeon *radeon); extern struct radeon *radeon_decref(struct radeon *radeon); @@ -102,4 +121,13 @@ extern int radeon_state_reloc(struct radeon_state *state, unsigned id, unsigned */ extern int radeon_draw_pm4(struct radeon_draw *draw); +/* bo */ +struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle, + unsigned size, unsigned alignment, void *ptr); +int radeon_bo_map(struct radeon *radeon, struct radeon_bo *bo); +void radeon_bo_unmap(struct radeon *radeon, struct radeon_bo *bo); +void radeon_bo_reference(struct radeon *radeon, struct radeon_bo **dst, + struct radeon_bo *src); +int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo); + #endif diff --git a/src/gallium/winsys/r600/drm/radeon_state.c b/src/gallium/winsys/r600/drm/radeon_state.c index e37e714533..b237b39c2b 100644 --- a/src/gallium/winsys/r600/drm/radeon_state.c +++ b/src/gallium/winsys/r600/drm/radeon_state.c @@ -139,7 +139,7 @@ void radeon_state_fini(struct radeon_state *state) if (state == NULL) return NULL; for (i = 0; i < state->nbo; i++) { - state->bo[i] = radeon_bo_decref(state->radeon, state->bo[i]); + radeon_ws_bo_reference(state->radeon, &state->bo[i], NULL); } memset(state, 0, sizeof(struct radeon_state)); } diff --git a/src/gallium/winsys/r600/drm/radeon_ws_bo.c b/src/gallium/winsys/r600/drm/radeon_ws_bo.c new file mode 100644 index 0000000000..c789f8780f --- /dev/null +++ b/src/gallium/winsys/r600/drm/radeon_ws_bo.c @@ -0,0 +1,63 @@ +#include +#include "radeon_priv.h" + +struct radeon_ws_bo *radeon_ws_bo(struct radeon *radeon, + unsigned size, unsigned alignment) +{ + struct radeon_ws_bo *ws_bo = calloc(1, sizeof(struct radeon_ws_bo)); + + ws_bo->bo = radeon_bo(radeon, 0, size, alignment, NULL); + if (!ws_bo->bo) { + free(ws_bo); + return NULL; + } + + pipe_reference_init(&ws_bo->reference, 1); + return ws_bo; +} + +struct radeon_ws_bo *radeon_ws_bo_handle(struct radeon *radeon, + unsigned handle) +{ + struct radeon_ws_bo *ws_bo = calloc(1, sizeof(struct radeon_ws_bo)); + + ws_bo->bo = radeon_bo(radeon, handle, 0, 0, NULL); + if (!ws_bo->bo) { + free(ws_bo); + return NULL; + } + pipe_reference_init(&ws_bo->reference, 1); + return ws_bo; +} + +void *radeon_ws_bo_map(struct radeon *radeon, struct radeon_ws_bo *bo) +{ + radeon_bo_map(radeon, bo->bo); + return bo->bo->data; +} + +void radeon_ws_bo_unmap(struct radeon *radeon, struct radeon_ws_bo *bo) +{ + radeon_bo_unmap(radeon, bo->bo); +} + +static void radeon_ws_bo_destroy(struct radeon *radeon, struct radeon_ws_bo *bo) +{ + radeon_bo_reference(radeon, &bo->bo, NULL); + free(bo); +} + +void radeon_ws_bo_reference(struct radeon *radeon, struct radeon_ws_bo **dst, + struct radeon_ws_bo *src) +{ + struct radeon_ws_bo *old = *dst; + if (pipe_reference(&(*dst)->reference, &src->reference)) { + radeon_ws_bo_destroy(radeon, old); + } + *dst = src; +} + +int radeon_ws_bo_wait(struct radeon *radeon, struct radeon_ws_bo *bo) +{ + return radeon_bo_wait(radeon, bo->bo); +} -- cgit v1.2.3