summaryrefslogtreecommitdiff
path: root/libdrm/radeon
diff options
context:
space:
mode:
authorJerome Glisse <glisse@freedesktop.org>2008-11-12 15:56:40 +0100
committerJerome Glisse <glisse@freedesktop.org>2008-11-12 16:57:09 +0100
commita7457915f5775137436f3b16a640eb8bd6424ca6 (patch)
tree1276c211e5a72ace371bd85df0ffefd56f14d55b /libdrm/radeon
parent6d59bad8e9cab6170e1af3d67597b6f5f145c33f (diff)
radeon+libdrm-radeon: change relocation informations
Relocation now consist of the following informations (in this order) : handle buffer object handle identifier start_offset start offset of first data of the buffer object used by the cs end_offset end offset of last data of the buffer object used by the cs read_domain read domain (either VRAM, or GTT as GPU is invalid for CS) write_domain write domain (either VRAM, or GTT as GPU is invalid for CS) flags flags used for further optimization (like discard previous buffer content or forget buffer content after cs which can help in avoiding moving content in or out)
Diffstat (limited to 'libdrm/radeon')
-rw-r--r--libdrm/radeon/Makefile.am2
-rw-r--r--libdrm/radeon/radeon_cs.h33
-rw-r--r--libdrm/radeon/radeon_cs_gem.c103
3 files changed, 82 insertions, 56 deletions
diff --git a/libdrm/radeon/Makefile.am b/libdrm/radeon/Makefile.am
index cc4951a9..d15a266b 100644
--- a/libdrm/radeon/Makefile.am
+++ b/libdrm/radeon/Makefile.am
@@ -29,7 +29,7 @@ AM_CFLAGS = \
$(PTHREADSTUBS_CFLAGS) \
-I$(top_srcdir)/shared-core
-libdrm_radeon_la_LTLIBRARIES = libdrm_radeon.la
+libdrm_radeon_la_LTLIBRARIES = libdrm-radeon.la
libdrm_radeon_ladir = $(libdir)
libdrm_radeon_la_LDFLAGS = -version-number 1:0:0 -no-undefined
libdrm_radeon_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
diff --git a/libdrm/radeon/radeon_cs.h b/libdrm/radeon/radeon_cs.h
index 347e9f35..63f104b6 100644
--- a/libdrm/radeon/radeon_cs.h
+++ b/libdrm/radeon/radeon_cs.h
@@ -37,10 +37,11 @@
struct radeon_cs_reloc {
struct radeon_bo *bo;
- uint32_t soffset;
- uint32_t eoffset;
- uint32_t size;
- uint32_t domains;
+ uint32_t start_offset;
+ uint32_t end_offset;
+ uint32_t read_domain;
+ uint32_t write_domain;
+ uint32_t flags;
};
struct radeon_cs_manager;
@@ -68,9 +69,11 @@ struct radeon_cs_funcs {
int (*cs_write_dword)(struct radeon_cs *cs, uint32_t dword);
int (*cs_write_reloc)(struct radeon_cs *cs,
struct radeon_bo *bo,
- uint32_t soffset,
- uint32_t eoffset,
- uint32_t domains);
+ uint32_t start_offset,
+ uint32_t end_offset,
+ uint32_t read_domain,
+ uint32_t write_domain,
+ uint32_t flags);
int (*cs_begin)(struct radeon_cs *cs,
uint32_t ndw,
const char *file,
@@ -104,11 +107,19 @@ static inline int radeon_cs_write_dword(struct radeon_cs *cs, uint32_t dword)
static inline int radeon_cs_write_reloc(struct radeon_cs *cs,
struct radeon_bo *bo,
- uint32_t soffset,
- uint32_t eoffset,
- uint32_t domains)
+ uint32_t start_offset,
+ uint32_t end_offset,
+ uint32_t read_domain,
+ uint32_t write_domain,
+ uint32_t flags)
{
- return cs->csm->funcs->cs_write_reloc(cs, bo, soffset, eoffset, domains);
+ return cs->csm->funcs->cs_write_reloc(cs,
+ bo,
+ start_offset,
+ end_offset,
+ read_domain,
+ write_domain,
+ flags);
}
static inline int radeon_cs_begin(struct radeon_cs *cs,
diff --git a/libdrm/radeon/radeon_cs_gem.c b/libdrm/radeon/radeon_cs_gem.c
index 6be1728f..f9c9fabb 100644
--- a/libdrm/radeon/radeon_cs_gem.c
+++ b/libdrm/radeon/radeon_cs_gem.c
@@ -43,9 +43,11 @@
#pragma pack(1)
struct cs_reloc_gem {
uint32_t handle;
- uint32_t rdomain;
- uint32_t wdomain;
- uint32_t cnt;
+ uint32_t start_offset;
+ uint32_t end_offset;
+ uint32_t read_domain;
+ uint32_t write_domain;
+ uint32_t flags;
};
#pragma pack()
@@ -125,50 +127,74 @@ static int cs_gem_write_dword(struct radeon_cs *cs, uint32_t dword)
static int cs_gem_write_reloc(struct radeon_cs *cs,
struct radeon_bo *bo,
- uint32_t soffset,
- uint32_t eoffset,
- uint32_t domains)
+ uint32_t start_offset,
+ uint32_t end_offset,
+ uint32_t read_domain,
+ uint32_t write_domain,
+ uint32_t flags)
{
struct cs_gem *csg = (struct cs_gem*)cs;
struct cs_reloc_gem *reloc;
uint32_t idx;
unsigned i;
+ /* 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
+ * in read & write domain at the same sime
+ */
+ return -EINVAL;
+ }
+ if (read_domain == RADEON_GEM_DOMAIN_CPU) {
+ return -EINVAL;
+ }
+ if (write_domain == RADEON_GEM_DOMAIN_CPU) {
+ return -EINVAL;
+ }
/* check reloc window */
- if (eoffset > bo->size) {
+ if (end_offset > bo->size) {
return -EINVAL;
}
- if (soffset > eoffset) {
+ if (start_offset > end_offset) {
return -EINVAL;
}
/* check if bo is already referenced */
for(i = 0; i < cs->crelocs; i++) {
- idx = i * 4;
+ idx = i * 6;
reloc = (struct cs_reloc_gem*)&csg->relocs[idx];
-
if (reloc->handle == bo->handle) {
- /* update start offset and size */
- switch (bo->domains) {
- case RADEON_GEM_DOMAIN_VRAM:
- reloc->rdomain = 0;
- reloc->wdomain = RADEON_GEM_DOMAIN_VRAM;
- break;
- case RADEON_GEM_DOMAIN_GTT:
- reloc->rdomain = RADEON_GEM_DOMAIN_GTT;
- reloc->wdomain = 0;
- break;
- default:
- exit(0);
- break;
+ /* Check domains must be in read or write. As we check already
+ * checked that in argument one of the read or write domain was
+ * set we only need to check that if previous reloc as the read
+ * domain set then the read_domain should also be set for this
+ * new relocation.
+ */
+ if (reloc->read_domain && !read_domain) {
+ return -EINVAL;
+ }
+ if (reloc->write_domain && !write_domain) {
+ return -EINVAL;
+ }
+ reloc->read_domain |= read_domain;
+ reloc->write_domain |= write_domain;
+ /* update start and end offset */
+ if (start_offset < reloc->start_offset) {
+ reloc->start_offset = start_offset;
}
- reloc->cnt++;
+ if (end_offset > reloc->end_offset) {
+ reloc->end_offset = end_offset;
+ }
+ /* update flags */
+ reloc->flags |= (flags & reloc->flags);
+ /* write relocation packet */
cs_gem_write_dword(cs, 0xc0001000);
cs_gem_write_dword(cs, idx);
return 0;
}
}
- /* add bo */
+ /* new relocation */
if (csg->base.crelocs >= csg->nrelocs) {
+ /* allocate more memory (TODO: should use a slab allocatore maybe) */
uint32_t *tmp, size;
size = ((csg->nrelocs + 1) * sizeof(struct radeon_bo*));
tmp = (uint32_t*)realloc(csg->relocs_bo, size);
@@ -176,7 +202,7 @@ static int cs_gem_write_reloc(struct radeon_cs *cs,
return -ENOMEM;
}
csg->relocs_bo = (struct radeon_bo**)tmp;
- size = ((csg->nrelocs + 1) * 4 * 4);
+ size = ((csg->nrelocs + 1) * 6 * 4);
tmp = (uint32_t*)realloc(csg->relocs, size);
if (tmp == NULL) {
return -ENOMEM;
@@ -186,26 +212,15 @@ static int cs_gem_write_reloc(struct radeon_cs *cs,
csg->chunks[1].chunk_data = (uint64_t)(intptr_t)csg->relocs;
}
csg->relocs_bo[csg->base.crelocs] = bo;
- idx = (csg->base.crelocs++) * 4;
+ idx = (csg->base.crelocs++) * 6;
reloc = (struct cs_reloc_gem*)&csg->relocs[idx];
reloc->handle = bo->handle;
- reloc->rdomain = bo->domains;
- reloc->wdomain = bo->domains;
- switch (bo->domains) {
- case RADEON_GEM_DOMAIN_VRAM:
- reloc->rdomain = 0;
- reloc->wdomain = RADEON_GEM_DOMAIN_VRAM;
- break;
- case RADEON_GEM_DOMAIN_GTT:
- reloc->rdomain = RADEON_GEM_DOMAIN_GTT;
- reloc->wdomain = 0;
- break;
- default:
- exit(0);
- break;
- }
- reloc->cnt = 1;
- csg->chunks[1].length_dw += 4;
+ reloc->start_offset = start_offset;
+ reloc->end_offset = end_offset;
+ reloc->read_domain = read_domain;
+ reloc->write_domain = write_domain;
+ reloc->flags = flags;
+ csg->chunks[1].length_dw += 6;
radeon_bo_ref(bo);
cs->relocs_total_size += bo->size;
cs_gem_write_dword(cs, 0xc0001000);