[PATCH] libdrm/libradeon: Unify read & write domain into a single one

From: Jerome Glisse
Date: Wed Oct 21 2009 - 18:26:32 EST


This unify read & write domain into a single domain
without changing the API or ABI of libdrm_radeon.
---
libdrm/radeon/radeon_cs.h | 11 +--
libdrm/radeon/radeon_cs_gem.c | 35 +++-----
libdrm/radeon/radeon_cs_space.c | 169 +++++++++++++--------------------------
3 files changed, 71 insertions(+), 144 deletions(-)

diff --git a/libdrm/radeon/radeon_cs.h b/libdrm/radeon/radeon_cs.h
index 1117a85..8005550 100644
--- a/libdrm/radeon/radeon_cs.h
+++ b/libdrm/radeon/radeon_cs.h
@@ -40,8 +40,7 @@

struct radeon_cs_reloc {
struct radeon_bo *bo;
- uint32_t read_domain;
- uint32_t write_domain;
+ uint32_t domains;
uint32_t flags;
};

@@ -52,8 +51,7 @@ struct radeon_cs_reloc {

struct radeon_cs_space_check {
struct radeon_bo *bo;
- uint32_t read_domains;
- uint32_t write_domain;
+ uint32_t domains;
uint32_t new_accounted;
};

@@ -109,9 +107,8 @@ struct radeon_cs_funcs {
struct radeon_cs_manager {
struct radeon_cs_funcs *funcs;
int fd;
- int32_t vram_limit, gart_limit;
- int32_t vram_write_used, gart_write_used;
- int32_t read_used;
+ int32_t vram_limit, gart_limit;
+ int32_t vram_free, gart_free;
};

static inline struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm,
diff --git a/libdrm/radeon/radeon_cs_gem.c b/libdrm/radeon/radeon_cs_gem.c
index e42ec48..5762c68 100644
--- a/libdrm/radeon/radeon_cs_gem.c
+++ b/libdrm/radeon/radeon_cs_gem.c
@@ -115,11 +115,12 @@ static int cs_gem_write_reloc(struct radeon_cs *cs,
{
struct cs_gem *csg = (struct cs_gem*)cs;
struct cs_reloc_gem *reloc;
- uint32_t idx;
+ uint32_t idx, domains;
unsigned i;

assert(bo->space_accounted);
-
+ domains = read_domain | write_domain;
+#if 0
/* check domains */
if ((read_domain && write_domain) || (!read_domain && !write_domain)) {
/* in one CS a bo can only be in read or write domain but not
@@ -127,10 +128,11 @@ static int cs_gem_write_reloc(struct radeon_cs *cs,
*/
return -EINVAL;
}
- if (read_domain == RADEON_GEM_DOMAIN_CPU) {
+#endif
+ if (read_domain & RADEON_GEM_DOMAIN_CPU) {
return -EINVAL;
}
- if (write_domain == RADEON_GEM_DOMAIN_CPU) {
+ if (write_domain & RADEON_GEM_DOMAIN_CPU) {
return -EINVAL;
}
/* check if bo is already referenced */
@@ -145,20 +147,8 @@ static int cs_gem_write_reloc(struct radeon_cs *cs,
* new relocation.
*/
/* the DDX expects to read and write from same pixmap */
- if (write_domain && (reloc->read_domain & write_domain)) {
- reloc->read_domain = 0;
- reloc->write_domain = write_domain;
- } else if (read_domain & reloc->write_domain) {
- reloc->read_domain = 0;
- } else {
- if (write_domain != reloc->write_domain)
- return -EINVAL;
- if (read_domain != reloc->read_domain)
- return -EINVAL;
- }
-
- reloc->read_domain |= read_domain;
- reloc->write_domain |= write_domain;
+ reloc->read_domain |= domains;
+ reloc->write_domain = 0;
/* update flags */
reloc->flags |= (flags & reloc->flags);
/* write relocation packet */
@@ -190,8 +180,8 @@ static int cs_gem_write_reloc(struct radeon_cs *cs,
idx = (csg->base.crelocs++) * RELOC_SIZE;
reloc = (struct cs_reloc_gem*)&csg->relocs[idx];
reloc->handle = bo->handle;
- reloc->read_domain = read_domain;
- reloc->write_domain = write_domain;
+ reloc->read_domain = domains;
+ reloc->write_domain = 0;
reloc->flags = flags;
csg->chunks[1].length_dw += RELOC_SIZE;
radeon_bo_ref(bo);
@@ -283,9 +273,8 @@ static int cs_gem_emit(struct radeon_cs *cs)
csg->relocs_bo[i] = NULL;
}

- cs->csm->read_used = 0;
- cs->csm->vram_write_used = 0;
- cs->csm->gart_write_used = 0;
+ cs->csm->vram_free = cs->csm->vram_limit;
+ cs->csm->gart_free = cs->csm->gart_limit;
return r;
}

diff --git a/libdrm/radeon/radeon_cs_space.c b/libdrm/radeon/radeon_cs_space.c
index 4c1ef93..f4160e3 100644
--- a/libdrm/radeon/radeon_cs_space.c
+++ b/libdrm/radeon/radeon_cs_space.c
@@ -31,72 +31,39 @@
#include "radeon_cs.h"

struct rad_sizes {
- int32_t op_read;
- int32_t op_gart_write;
- int32_t op_vram_write;
+ int32_t op_gtt;
+ int32_t op_vram;
};

-static inline int radeon_cs_setup_bo(struct radeon_cs_space_check *sc, struct rad_sizes *sizes)
+static inline int radeon_cs_setup_bo(struct radeon_cs_space_check *sc,
+ struct radeon_cs_manager *csm,
+ struct rad_sizes *sizes)
{
- uint32_t read_domains, write_domain;
+ uint32_t domains;
struct radeon_bo *bo;

bo = sc->bo;
sc->new_accounted = 0;
- read_domains = sc->read_domains;
- write_domain = sc->write_domain;
+ domains = sc->domains;

/* legacy needs a static check */
if (radeon_bo_is_static(bo)) {
- bo->space_accounted = sc->new_accounted = (read_domains << 16) | write_domain;
- return 0;
+ bo->space_accounted = sc->new_accounted = domains;
+ return 0;
}

- /* already accounted this bo */
- if (write_domain && (write_domain == bo->space_accounted)) {
- sc->new_accounted = bo->space_accounted;
- return 0;
+ /* bo accounted in vram */
+ if (bo->space_accounted == RADEON_GEM_DOMAIN_VRAM) {
+ sc->new_accounted = bo->space_accounted;
+ return 0;
}
- if (read_domains && ((read_domains << 16) == bo->space_accounted)) {
- sc->new_accounted = bo->space_accounted;
- return 0;
- }
-
- if (bo->space_accounted == 0) {
- if (write_domain == RADEON_GEM_DOMAIN_VRAM)
- sizes->op_vram_write += bo->size;
- else if (write_domain == RADEON_GEM_DOMAIN_GTT)
- sizes->op_gart_write += bo->size;
- else
- sizes->op_read += bo->size;
- sc->new_accounted = (read_domains << 16) | write_domain;
- } else {
- uint16_t old_read, old_write;
-
- old_read = bo->space_accounted >> 16;
- old_write = bo->space_accounted & 0xffff;
-
- if (write_domain && (old_read & write_domain)) {
- sc->new_accounted = write_domain;
- /* moving from read to a write domain */
- if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
- sizes->op_read -= bo->size;
- sizes->op_vram_write += bo->size;
- } else if (write_domain == RADEON_GEM_DOMAIN_GTT) {
- sizes->op_read -= bo->size;
- sizes->op_gart_write += bo->size;
- }
- } else if (read_domains & old_write) {
- sc->new_accounted = bo->space_accounted & 0xffff;
- } else {
- /* rewrite the domains */
- if (write_domain != old_write)
- fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write);
- if (read_domains != old_read)
- fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read);
- return RADEON_CS_SPACE_FLUSH;
- }
+ if (bo->space_accounted & domains) {
+ sc->new_accounted = bo->space_accounted;
+ return 0;
}
+ sizes->op_gtt -= bo->size;
+ sizes->op_vram += bo->size;
+ bo->space_accounted = sc->new_accounted = RADEON_GEM_DOMAIN_VRAM;
return 0;
}

@@ -109,70 +76,51 @@ static int radeon_cs_do_space_check(struct radeon_cs *cs, struct radeon_cs_space
int ret;

/* check the totals for this operation */
-
if (cs->bo_count == 0 && !new_tmp)
- return 0;
-
+ return 0;
memset(&sizes, 0, sizeof(struct rad_sizes));

/* prepare */
for (i = 0; i < cs->bo_count; i++) {
- ret = radeon_cs_setup_bo(&cs->bos[i], &sizes);
- if (ret)
- return ret;
+ ret = radeon_cs_setup_bo(&cs->bos[i], csm, &sizes);
+ if (ret)
+ return ret;
}

if (new_tmp) {
- ret = radeon_cs_setup_bo(new_tmp, &sizes);
- if (ret)
- return ret;
- }
-
- if (sizes.op_read < 0)
- sizes.op_read = 0;
-
- /* check sizes - operation first */
- if ((sizes.op_read + sizes.op_gart_write > csm->gart_limit) ||
- (sizes.op_vram_write > csm->vram_limit)) {
- return RADEON_CS_SPACE_OP_TO_BIG;
- }
-
- if (((csm->vram_write_used + sizes.op_vram_write) > csm->vram_limit) ||
- ((csm->read_used + csm->gart_write_used + sizes.op_gart_write + sizes.op_read) > csm->gart_limit)) {
- return RADEON_CS_SPACE_FLUSH;
+ ret = radeon_cs_setup_bo(new_tmp, csm, &sizes);
+ if (ret)
+ return ret;
}
-
- csm->gart_write_used += sizes.op_gart_write;
- csm->vram_write_used += sizes.op_vram_write;
- csm->read_used += sizes.op_read;
+ if ((sizes.op_gtt + sizes.op_vram) >= (csm->gart_limit + csm->vram_limit))
+ return RADEON_CS_SPACE_FLUSH;
+ csm->gart_free -= sizes.op_gtt;
+ csm->vram_free -= sizes.op_vram;
/* commit */
for (i = 0; i < cs->bo_count; i++) {
- bo = cs->bos[i].bo;
- bo->space_accounted = cs->bos[i].new_accounted;
+ bo = cs->bos[i].bo;
+ bo->space_accounted = cs->bos[i].new_accounted;
}
if (new_tmp)
- new_tmp->bo->space_accounted = new_tmp->new_accounted;
-
+ new_tmp->bo->space_accounted = new_tmp->new_accounted;
return RADEON_CS_SPACE_OK;
}

void radeon_cs_space_add_persistent_bo(struct radeon_cs *cs, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
{
+ uint32_t domains = read_domains | write_domain;
int i;
+
for (i = 0; i < cs->bo_count; i++) {
- if (cs->bos[i].bo == bo &&
- cs->bos[i].read_domains == read_domains &&
- cs->bos[i].write_domain == write_domain)
- return;
+ if (cs->bos[i].bo == bo && (cs->bos[i].domains & domains))
+ return;
}
radeon_bo_ref(bo);
i = cs->bo_count;
cs->bos[i].bo = bo;
- cs->bos[i].read_domains = read_domains;
- cs->bos[i].write_domain = write_domain;
+ cs->bos[i].domains = domains;
cs->bos[i].new_accounted = 0;
cs->bo_count++;
-
assert(cs->bo_count < MAX_SPACE_BOS);
}

@@ -184,33 +132,29 @@ static int radeon_cs_check_space_internal(struct radeon_cs *cs, struct radeon_cs
again:
ret = radeon_cs_do_space_check(cs, tmp_bo);
if (ret == RADEON_CS_SPACE_OP_TO_BIG)
- return -1;
+ return -1;
if (ret == RADEON_CS_SPACE_FLUSH) {
- (*cs->space_flush_fn)(cs->space_flush_data);
- if (flushed)
- return -1;
- flushed = 1;
- goto again;
+ (*cs->space_flush_fn)(cs->space_flush_data);
+ if (flushed)
+ return -1;
+ flushed = 1;
+ goto again;
}
return 0;
}

int radeon_cs_space_check_with_bo(struct radeon_cs *cs,
- struct radeon_bo *bo,
- uint32_t read_domains, uint32_t write_domain)
-{
+ struct radeon_bo *bo,
+ uint32_t read_domains, uint32_t write_domain)
+{
struct radeon_cs_space_check temp_bo;
- int ret = 0;

if (bo) {
- temp_bo.bo = bo;
- temp_bo.read_domains = read_domains;
- temp_bo.write_domain = write_domain;
- temp_bo.new_accounted = 0;
+ temp_bo.bo = bo;
+ temp_bo.domains = read_domains | write_domain;
+ temp_bo.new_accounted = 0;
}
-
- ret = radeon_cs_check_space_internal(cs, bo ? &temp_bo : NULL);
- return ret;
+ return radeon_cs_check_space_internal(cs, bo ? &temp_bo : NULL);
}

int radeon_cs_space_check(struct radeon_cs *cs)
@@ -222,13 +166,10 @@ void radeon_cs_space_reset_bos(struct radeon_cs *cs)
{
int i;
for (i = 0; i < cs->bo_count; i++) {
- radeon_bo_unref(cs->bos[i].bo);
- cs->bos[i].bo = NULL;
- cs->bos[i].read_domains = 0;
- cs->bos[i].write_domain = 0;
- cs->bos[i].new_accounted = 0;
+ radeon_bo_unref(cs->bos[i].bo);
+ cs->bos[i].bo = NULL;
+ cs->bos[i].domains = 0;
+ cs->bos[i].new_accounted = 0;
}
cs->bo_count = 0;
}
-
-
--
1.6.5.rc2


--=-tKbvaVp0hj/WqbHcJLdR--

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/