aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/winsys/drm
diff options
context:
space:
mode:
authorMichel Dänzer <[email protected]>2009-03-04 11:58:48 +0100
committerMichel Dänzer <[email protected]>2009-03-04 11:58:48 +0100
commit5e27cd46c04a9e7b5904cc014bffd0f4daae31fe (patch)
treea57289f14d69f1977dfaee592af908052d726b8c /src/gallium/winsys/drm
parent60041203d5847de8ab71842a6ce5d33d96cc4930 (diff)
gallium: Unify reference counting.
The core reference counting code is centralized in p_refcnt.h. This has some consequences related to struct pipe_buffer: * The screen member of struct pipe_buffer must be initialized, or pipe_buffer_reference() will crash trying to destroy a buffer with reference count 0. u_simple_screen takes care of this, but I may have missed some of the drivers not using it. * Except for rare exceptions deep in winsys code, buffers must always be allocated via pipe_buffer_create() or via screen->*buffer_create() rather than via winsys->*buffer_create().
Diffstat (limited to 'src/gallium/winsys/drm')
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c4
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.c19
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_fence.h18
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_context.c7
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_context.h2
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c6
-rw-r--r--src/gallium/winsys/drm/radeon/radeon_buffer.c10
-rw-r--r--src/gallium/winsys/drm/radeon/radeon_drm.c3
8 files changed, 28 insertions, 41 deletions
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
index 01374337852..d5e63c3bae5 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
@@ -114,10 +114,10 @@ intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
if (fence) {
if (*fence)
- intel_be_fence_unreference(*fence);
+ intel_be_fence_reference(fence, NULL);
(*fence) = CALLOC_STRUCT(intel_be_fence);
- (*fence)->refcount = 1;
+ pipe_reference_init(&(*fence)->reference, 1);
(*fence)->bo = NULL;
}
}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
index 2e191a6d126..de13fb39c7e 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
@@ -51,8 +51,7 @@ intel_be_buffer_unmap(struct pipe_winsys *winsys,
}
static void
-intel_be_buffer_destroy(struct pipe_winsys *winsys,
- struct pipe_buffer *buf)
+intel_be_buffer_destroy(struct pipe_buffer *buf)
{
drm_intel_bo_unreference(intel_bo(buf));
free(buf);
@@ -72,7 +71,7 @@ intel_be_buffer_create(struct pipe_winsys *winsys,
if (!buffer)
return NULL;
- buffer->base.refcount = 1;
+ pipe_reference_init(&buffer->base.reference, 1);
buffer->base.alignment = alignment;
buffer->base.usage = usage;
buffer->base.size = size;
@@ -115,7 +114,7 @@ intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned byte
if (!buffer)
return NULL;
- buffer->base.refcount = 1;
+ pipe_reference_init(&buffer->base.reference, 1);
buffer->base.alignment = 0;
buffer->base.usage = 0;
buffer->base.size = bytes;
@@ -155,7 +154,7 @@ intel_be_buffer_from_handle(struct pipe_screen *screen,
if (!buffer->bo)
goto err;
- buffer->base.refcount = 1;
+ pipe_reference_init(&buffer->base.reference, 1);
buffer->base.alignment = buffer->bo->align;
buffer->base.usage = PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE |
@@ -215,15 +214,7 @@ intel_be_fence_refunref(struct pipe_winsys *sws,
struct intel_be_fence **p = (struct intel_be_fence **)ptr;
struct intel_be_fence *f = (struct intel_be_fence *)fence;
- assert(p);
-
- if (f)
- intel_be_fence_reference(f);
-
- if (*p)
- intel_be_fence_unreference(*p);
-
- *p = f;
+ intel_be_fence_reference(p, f);
}
static int
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_fence.h b/src/gallium/winsys/drm/intel/gem/intel_be_fence.h
index 0fe18f66f83..a8abb01a9ed 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_fence.h
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_fence.h
@@ -15,23 +15,19 @@
*/
struct intel_be_fence
{
- uint32_t refcount;
+ struct pipe_reference reference;
drm_intel_bo *bo;
};
static INLINE void
-intel_be_fence_reference(struct intel_be_fence *f)
+intel_be_fence_reference(struct intel_be_fence **ptr, struct intel_be_fence *f)
{
- f->refcount++;
-}
+ struct intel_be_fence *old_fence = *ptr;
-static INLINE void
-intel_be_fence_unreference(struct intel_be_fence *f)
-{
- if (!--f->refcount) {
- if (f->bo)
- drm_intel_bo_unreference(f->bo);
- free(f);
+ if (pipe_reference((struct pipe_reference**)ptr, &f->reference)) {
+ if (old_fence->bo)
+ drm_intel_bo_unreference(old_fence->bo);
+ free(old_fence);
}
}
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c
index d6ae0827cd7..25c98456ac4 100644
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c
@@ -109,8 +109,7 @@ nouveau_context_init(struct nouveau_screen *nv_screen,
nv_screen->nvc = nvc;
}
- nvc->refcount++;
- nv->nvc = nvc;
+ pipe_reference((struct pipe_reference**)&nv->nvc, &nvc->reference);
/* Find a free slot for a pipe context, allocate a new one if needed */
nv->pctx_id = -1;
@@ -159,7 +158,7 @@ nouveau_context_init(struct nouveau_screen *nv_screen,
enum pipe_format format;
fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer));
- fb_buf->base.refcount = 1;
+ pipe_reference_init(&fb_buf->base.reference, 1);
fb_buf->base.usage = PIPE_BUFFER_USAGE_PIXEL;
nouveau_bo_fake(dev, nv_screen->front_offset, NOUVEAU_BO_VRAM,
@@ -195,7 +194,7 @@ nouveau_context_cleanup(struct nouveau_context *nv)
if (nv->pctx_id >= 0) {
nvc->pctx[nv->pctx_id] = NULL;
- if (--nvc->refcount <= 0) {
+ if (pipe_reference((struct pipe_reference**)&nv->nvc, NULL)) {
nouveau_channel_context_destroy(nvc);
nv->nv_screen->nvc = NULL;
}
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h
index 02d2745680c..ba8fc3ad2df 100644
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h
@@ -13,8 +13,8 @@
#include "nouveau_local.h"
struct nouveau_channel_context {
+ struct pipe_reference reference;
struct pipe_screen *pscreen;
- int refcount;
unsigned cur_pctx;
unsigned nr_pctx;
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c
index 54c7dd46b14..24bbd4516f1 100644
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c
@@ -67,7 +67,7 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
if (!nvbuf)
return NULL;
- nvbuf->base.refcount = 1;
+ pipe_reference_init(&nvbuf->base.reference, 1);
nvbuf->base.alignment = alignment;
nvbuf->base.usage = usage;
nvbuf->base.size = size;
@@ -92,7 +92,7 @@ nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
if (!nvbuf)
return NULL;
- nvbuf->base.refcount = 1;
+ pipe_reference_init(&nvbuf->base.reference, 1);
nvbuf->base.size = bytes;
if (nouveau_bo_user(dev, ptr, bytes, &nvbuf->bo)) {
@@ -104,7 +104,7 @@ nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
}
static void
-nouveau_pipe_bo_del(struct pipe_winsys *ws, struct pipe_buffer *buf)
+nouveau_pipe_bo_del(struct pipe_buffer *buf)
{
struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);
diff --git a/src/gallium/winsys/drm/radeon/radeon_buffer.c b/src/gallium/winsys/drm/radeon/radeon_buffer.c
index 79b8f777ca8..b3582e3314a 100644
--- a/src/gallium/winsys/drm/radeon/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/radeon_buffer.c
@@ -63,7 +63,7 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
return NULL;
}
- radeon_buffer->base.refcount = 1;
+ pipe_reference_init(&radeon_buffer->base.reference, 1);
radeon_buffer->base.alignment = alignment;
radeon_buffer->base.usage = usage;
radeon_buffer->base.size = size;
@@ -104,7 +104,7 @@ static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws,
return &radeon_buffer->base;
}
-static void radeon_buffer_del(struct pipe_winsys *ws, struct pipe_buffer *buffer)
+static void radeon_buffer_del(struct pipe_buffer *buffer)
{
struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer;
@@ -207,7 +207,7 @@ static struct pipe_buffer *radeon_buffer_from_handle(struct radeon_screen *radeo
radeon_bo_unref(bo);
return NULL;
}
- radeon_buffer->base.refcount = 1;
+ pipe_reference_init(&radeon_buffer->base.reference, 1);
radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL;
radeon_buffer->bo = bo;
return &radeon_buffer->base;
@@ -242,10 +242,10 @@ struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_co
pt = pipe_screen->texture_blanket(pipe_screen, &tmpl, &pitch, pb);
if (pt == NULL) {
- pipe_buffer_reference(pipe_screen, &pb, NULL);
+ pipe_buffer_reference(&pb, NULL);
}
ps = pipe_screen->get_tex_surface(pipe_screen, pt, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
return ps;
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/gallium/winsys/drm/radeon/radeon_drm.c b/src/gallium/winsys/drm/radeon/radeon_drm.c
index 21f2a62e0fe..016634c8fd3 100644
--- a/src/gallium/winsys/drm/radeon/radeon_drm.c
+++ b/src/gallium/winsys/drm/radeon/radeon_drm.c
@@ -84,7 +84,8 @@ struct pipe_buffer* radeon_buffer_from_handle(struct pipe_screen* screen,
return NULL;
}
- radeon_buffer->base.refcount = 1;
+ pipe_reference_init(&radeon_buffer->base.reference, 1);
+ radeon_buffer->base.screen = screen;
radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL;
radeon_buffer->bo = bo;
return &radeon_buffer->base;