summaryrefslogtreecommitdiffstats
path: root/src/gallium/winsys/r600
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/r600')
-rw-r--r--src/gallium/winsys/r600/drm/r600_hw_context.c1
-rw-r--r--src/gallium/winsys/r600/drm/r600_priv.h5
-rw-r--r--src/gallium/winsys/r600/drm/radeon_bo.c37
3 files changed, 43 insertions, 0 deletions
diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c
index 7a908b3ca4d..822b65facfb 100644
--- a/src/gallium/winsys/r600/drm/r600_hw_context.c
+++ b/src/gallium/winsys/r600/drm/r600_hw_context.c
@@ -1044,6 +1044,7 @@ void r600_context_flush(struct r600_context *ctx)
sizeof(struct drm_radeon_cs));
#endif
/* restart */
+ radeon_bo_fencelist(ctx->radeon, ctx->bo, ctx->creloc);
for (int i = 0; i < ctx->creloc; i++) {
radeon_bo_reference(ctx->radeon, &ctx->bo[i], NULL);
}
diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h
index 5c954ea6213..76a7ba9ec25 100644
--- a/src/gallium/winsys/r600/drm/r600_priv.h
+++ b/src/gallium/winsys/r600/drm/r600_priv.h
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <assert.h>
#include <pipebuffer/pb_bufmgr.h>
+#include "util/u_double_list.h"
#include "r600.h"
struct radeon {
@@ -63,6 +64,8 @@ struct radeon_bo {
unsigned alignment;
unsigned map_count;
void *data;
+ struct list_head fencedlist;
+ boolean shared;
};
struct r600_bo {
@@ -86,6 +89,8 @@ void radeon_bo_reference(struct radeon *radeon, struct radeon_bo **dst,
int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo);
int radeon_bo_busy(struct radeon *radeon, struct radeon_bo *bo, uint32_t *domain);
void radeon_bo_pbmgr_flush_maps(struct pb_manager *_mgr);
+int radeon_bo_fencelist(struct radeon *radeon, struct radeon_bo **bolist, uint32_t num_bo);
+
/* radeon_bo_pb.c */
struct radeon_bo *radeon_bo_pb_get_bo(struct pb_buffer *_buf);
diff --git a/src/gallium/winsys/r600/drm/radeon_bo.c b/src/gallium/winsys/r600/drm/radeon_bo.c
index 14af3ec97ec..97138f9f9ef 100644
--- a/src/gallium/winsys/r600/drm/radeon_bo.c
+++ b/src/gallium/winsys/r600/drm/radeon_bo.c
@@ -95,6 +95,7 @@ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle,
}
bo->handle = open_arg.handle;
bo->size = open_arg.size;
+ bo->shared = TRUE;
} else {
struct drm_radeon_gem_create args;
@@ -122,6 +123,7 @@ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle,
if (ptr) {
memcpy(bo->data, ptr, size);
}
+ LIST_INITHEAD(&bo->fencedlist);
return bo;
}
@@ -130,6 +132,7 @@ static void radeon_bo_destroy(struct radeon *radeon, struct radeon_bo *bo)
{
struct drm_gem_close args;
+ LIST_DEL(&bo->fencedlist);
radeon_bo_fixed_unmap(radeon, bo);
memset(&args, 0, sizeof(args));
args.handle = bo->handle;
@@ -154,6 +157,9 @@ int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo)
struct drm_radeon_gem_wait_idle args;
int ret;
+ if (LIST_IS_EMPTY(&bo->fencedlist) && !bo->shared)
+ return 0;
+
/* Zero out args to make valgrind happy */
memset(&args, 0, sizeof(args));
args.handle = bo->handle;
@@ -169,6 +175,9 @@ int radeon_bo_busy(struct radeon *radeon, struct radeon_bo *bo, uint32_t *domain
struct drm_radeon_gem_busy args;
int ret;
+ if (LIST_IS_EMPTY(&bo->fencedlist) && !bo->shared)
+ return 0;
+
memset(&args, 0, sizeof(args));
args.handle = bo->handle;
args.domain = 0;
@@ -176,6 +185,34 @@ int radeon_bo_busy(struct radeon *radeon, struct radeon_bo *bo, uint32_t *domain
ret = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_BUSY,
&args, sizeof(args));
+ if (ret == 0) {
+ struct radeon_bo *entry, *tent;
+ LIST_FOR_EACH_ENTRY_SAFE(entry, tent, &bo->fencedlist, fencedlist) {
+ LIST_DELINIT(&entry->fencedlist);
+ }
+ }
*domain = args.domain;
return ret;
}
+
+int radeon_bo_fencelist(struct radeon *radeon, struct radeon_bo **bolist,
+ uint32_t num_bo)
+{
+ struct radeon_bo *first;
+ int i;
+
+ first = bolist[0];
+
+ if (!LIST_IS_EMPTY(&first->fencedlist))
+ LIST_DELINIT(&first->fencedlist);
+
+ LIST_INITHEAD(&first->fencedlist);
+
+ for (i = 1; i < num_bo; i++) {
+ if (!LIST_IS_EMPTY(&bolist[i]->fencedlist))
+ LIST_DELINIT(&bolist[i]->fencedlist);
+
+ LIST_ADDTAIL(&bolist[i]->fencedlist, &first->fencedlist);
+ }
+ return 0;
+}