diff options
Diffstat (limited to 'src/gallium/winsys/r600/drm')
-rw-r--r-- | src/gallium/winsys/r600/drm/Makefile | 3 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_drm.c | 23 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_state.c | 22 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_bo.c | 34 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_ctx.c | 35 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_priv.h | 30 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_state.c | 2 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_ws_bo.c | 63 |
8 files changed, 140 insertions, 72 deletions
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 <errno.h> #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 <malloc.h> +#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); +} |