summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/r600/drm
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/r600/drm')
-rw-r--r--src/gallium/winsys/r600/drm/Makefile3
-rw-r--r--src/gallium/winsys/r600/drm/r600_drm.c23
-rw-r--r--src/gallium/winsys/r600/drm/r600_state.c22
-rw-r--r--src/gallium/winsys/r600/drm/radeon_bo.c34
-rw-r--r--src/gallium/winsys/r600/drm/radeon_ctx.c35
-rw-r--r--src/gallium/winsys/r600/drm/radeon_priv.h30
-rw-r--r--src/gallium/winsys/r600/drm/radeon_state.c2
-rw-r--r--src/gallium/winsys/r600/drm/radeon_ws_bo.c63
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);
+}