summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-07-06 16:54:20 +1000
committerDave Airlie <airlied@redhat.com>2010-07-06 16:54:20 +1000
commit3fc3ee1250e308ff535997f19616e82efcca3025 (patch)
tree1b7f911d586d67cfab2316e3d3733c64c6c27788
parentd8ef7c15dedd6cbb48a6866131f6a9a15e627e12 (diff)
planb: multi-ib command submissioncs-start
-rw-r--r--include/drm/radeon_drm.h2
-rw-r--r--radeon/radeon_cs_gem.c123
-rw-r--r--radeon/radeon_cs_gem.h5
3 files changed, 69 insertions, 61 deletions
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h
index 42409daa..99316b22 100644
--- a/include/drm/radeon_drm.h
+++ b/include/drm/radeon_drm.h
@@ -874,7 +874,7 @@ struct drm_radeon_gem_pwrite {
#define RADEON_CHUNK_ID_RELOCS 0x01
#define RADEON_CHUNK_ID_IB 0x02
-#define RADEON_CHUNK_ID_IB_SETUP 0x03
+#define RADEON_CHUNK_ID_IB_CONTINUED 0x03
struct drm_radeon_cs_chunk {
uint32_t chunk_id;
diff --git a/radeon/radeon_cs_gem.c b/radeon/radeon_cs_gem.c
index e0cdbaa2..9f6ac4b5 100644
--- a/radeon/radeon_cs_gem.c
+++ b/radeon/radeon_cs_gem.c
@@ -49,6 +49,8 @@
#define CS_BOF_DUMP 0
+#define CS_MAX_IBS 4
+
struct radeon_cs_manager_gem {
struct radeon_cs_manager base;
uint32_t device_id;
@@ -68,12 +70,13 @@ struct cs_reloc_gem {
struct cs_gem {
struct radeon_cs_int base;
- struct drm_radeon_cs cs;
- struct drm_radeon_cs_chunk chunks[3];
unsigned nrelocs;
+ unsigned reloc_length_dw;
uint32_t *relocs;
struct radeon_bo_int **relocs_bo;
- struct radeon_cs alt;
+ struct radeon_cs ibs[CS_MAX_IBS];
+ unsigned num_ibs_alloced;
+ unsigned num_ibs_used;
};
static pthread_mutex_t id_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -120,21 +123,11 @@ static void free_id(uint32_t id)
pthread_mutex_unlock( &id_mutex );
}
-void radeon_cs_gem_switch_alt(struct radeon_cs *cs)
-{
- struct cs_gem *csg = (struct cs_gem*)cs;
- struct radeon_cs tmp;
-
- /* swap alt and tmp */
- tmp = *cs;
- *cs = csg->alt;
- csg->alt = tmp;
-}
-
struct radeon_cs *radeon_cs_gem_create_setup(struct radeon_cs_manager *csm,
- uint32_t ndw, uint32_t setup_ndw)
+ uint32_t ndw, uint32_t num_ibs)
{
struct cs_gem *csg;
+ uint32_t i;
/* max cmd buffer size is 64Kb */
if (ndw > (64 * 1024 / 4)) {
@@ -145,12 +138,18 @@ struct radeon_cs *radeon_cs_gem_create_setup(struct radeon_cs_manager *csm,
return NULL;
}
csg->base.csm = csm;
- csg->base.ndw = 64 * 1024 / 4;
- csg->base.packets = (uint32_t*)calloc(1, 64 * 1024);
- if (csg->base.packets == NULL) {
- free(csg);
- return NULL;
+
+ for (i = 0; i < num_ibs; i++) {
+ csg->ibs[i].packets = (uint32_t *)calloc(1, 64 * 1024);
+ if (!csg->ibs[i].packets) {
+ free(csg);
+ return NULL;
+ }
}
+ csg->num_ibs_alloced = num_ibs;
+ csg->num_ibs_used = 1;
+ csg->base.ndw = 64 * 1024 / 4;
+ csg->base.packets = csg->ibs[0].packets;
csg->base.relocs_total_size = 0;
csg->base.crelocs = 0;
csg->base.id = generate_id();
@@ -158,39 +157,37 @@ struct radeon_cs *radeon_cs_gem_create_setup(struct radeon_cs_manager *csm,
csg->relocs_bo = (struct radeon_bo_int**)calloc(1,
csg->nrelocs*sizeof(void*));
if (csg->relocs_bo == NULL) {
- free(csg->base.packets);
free(csg);
return NULL;
}
csg->base.relocs = csg->relocs = (uint32_t*)calloc(1, 4096);
if (csg->relocs == NULL) {
free(csg->relocs_bo);
- free(csg->base.packets);
free(csg);
return NULL;
}
- csg->alt.ndw = setup_ndw;
- csg->alt.packets = (uint32_t*)calloc(1, 4*1024);
- if (csg->alt.packets == NULL) {
- free(csg);
- return NULL;
- }
- csg->chunks[0].chunk_id = RADEON_CHUNK_ID_IB;
- csg->chunks[0].length_dw = 0;
- csg->chunks[0].chunk_data = (uint64_t)(uintptr_t)csg->base.packets;
- csg->chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
- csg->chunks[1].length_dw = 0;
- csg->chunks[1].chunk_data = (uint64_t)(uintptr_t)csg->relocs;
- csg->chunks[2].chunk_id = RADEON_CHUNK_ID_IB_SETUP;
- csg->chunks[2].length_dw = 0;
- csg->chunks[2].chunk_data = (uint64_t)(uintptr_t)csg->alt.packets;
return (struct radeon_cs*)csg;
}
+int radeon_cs_gem_switch_next_ib(struct radeon_cs *cs)
+{
+ struct cs_gem *csg = (struct cs_gem *)cs;
+
+ if (csg->num_ibs_used + 1 > csg->num_ibs_alloced)
+ return -1;
+
+ csg->ibs[csg->num_ibs_used - 1].cdw = csg->base.cdw;
+
+ csg->base.packets = csg->ibs[csg->num_ibs_used].packets;
+ csg->base.cdw = 0;
+ csg->num_ibs_used++;
+ return 0;
+}
+
static struct radeon_cs_int *cs_gem_create(struct radeon_cs_manager *csm,
uint32_t ndw)
{
- return (struct radeon_cs_int *)radeon_cs_gem_create_setup(csm, ndw, 0);
+ return (struct radeon_cs_int *)radeon_cs_gem_create_setup(csm, ndw, 1);
}
static int cs_gem_write_reloc(struct radeon_cs_int *cs,
@@ -278,7 +275,6 @@ static int cs_gem_write_reloc(struct radeon_cs_int *cs,
}
cs->relocs = csg->relocs = tmp;
csg->nrelocs += 1;
- csg->chunks[1].chunk_data = (uint64_t)(uintptr_t)csg->relocs;
}
csg->relocs_bo[csg->base.crelocs] = boi;
idx = (csg->base.crelocs++) * RELOC_SIZE;
@@ -287,7 +283,7 @@ static int cs_gem_write_reloc(struct radeon_cs_int *cs,
reloc->read_domain = read_domain;
reloc->write_domain = write_domain;
reloc->flags = flags;
- csg->chunks[1].length_dw += RELOC_SIZE;
+ csg->reloc_length_dw += RELOC_SIZE;
radeon_bo_ref(bo);
/* bo might be referenced from another context so have to use atomic opertions */
atomic_add((atomic_t *)radeon_gem_get_reloc_in_cs(bo), cs->id);
@@ -446,30 +442,42 @@ out_err:
static int cs_gem_emit(struct radeon_cs_int *cs)
{
struct cs_gem *csg = (struct cs_gem*)cs;
- uint64_t chunk_array[3];
+ uint64_t chunk_array[8];
+ struct drm_radeon_cs_chunk chunks[8];
+ struct drm_radeon_cs cs_pkt;
unsigned i;
int r;
#if CS_BOF_DUMP
cs_gem_dump_bof(cs);
#endif
- csg->chunks[0].length_dw = cs->cdw;
- chunk_array[0] = (uint64_t)(uintptr_t)&csg->chunks[0];
- chunk_array[1] = (uint64_t)(uintptr_t)&csg->chunks[1];
+ memset(&cs_pkt, 0, sizeof(struct drm_radeon_cs));
+ memset(chunks, 0, sizeof(chunks));
+
+ if (csg->num_ibs_used > 1)
+ fprintf(stderr,"reloc length is %d\n", csg->reloc_length_dw);
+
+ chunks[0].chunk_id = RADEON_CHUNK_ID_RELOCS;
+ chunks[0].length_dw = csg->reloc_length_dw;
+ chunks[0].chunk_data = (uint64_t)(uintptr_t)csg->relocs;
- csg->cs.num_chunks = 2;
+ chunk_array[0] = (uint64_t)(uintptr_t)&chunks[0];
+ cs_pkt.num_chunks = 1;
- if (csg->alt.cdw > 0) {
- csg->chunks[2].length_dw = csg->alt.cdw;
- chunk_array[2] = (uint64_t)(uintptr_t)&csg->chunks[2];
- csg->cs.num_chunks++;
+ csg->ibs[csg->num_ibs_used - 1].cdw = csg->base.cdw;
+ for (i = 0; i < csg->num_ibs_used; i++) {
+ chunks[i + 1].chunk_id = RADEON_CHUNK_ID_IB;
+ chunks[i + 1].chunk_data = (uint64_t)(uintptr_t)csg->ibs[i].packets;
+ chunks[i + 1].length_dw = csg->ibs[i].cdw;
+ chunk_array[i + 1] = (uint64_t)(uintptr_t)&chunks[i + 1];
+ cs_pkt.num_chunks++;
}
- csg->cs.chunks = (uint64_t)(uintptr_t)chunk_array;
+ cs_pkt.chunks = (uint64_t)(uintptr_t)chunk_array;
r = drmCommandWriteRead(cs->csm->fd, DRM_RADEON_CS,
- &csg->cs, sizeof(struct drm_radeon_cs));
+ &cs_pkt, sizeof(struct drm_radeon_cs));
for (i = 0; i < csg->base.crelocs; i++) {
csg->relocs_bo[i]->space_accounted = 0;
/* bo might be referenced from another context so have to use atomic opertions */
@@ -487,12 +495,13 @@ static int cs_gem_emit(struct radeon_cs_int *cs)
static int cs_gem_destroy(struct radeon_cs_int *cs)
{
struct cs_gem *csg = (struct cs_gem*)cs;
+ int i;
free_id(cs->id);
free(csg->relocs_bo);
free(cs->relocs);
- free(cs->packets);
- free(csg->alt.packets);
+ for (i = 0; i < CS_MAX_IBS; i++)
+ free(csg->ibs[i].packets);
free(cs);
return 0;
}
@@ -514,13 +523,11 @@ static int cs_gem_erase(struct radeon_cs_int *cs)
}
cs->relocs_total_size = 0;
cs->cdw = 0;
- csg->alt.cdw = 0;
cs->section_ndw = 0;
- csg->alt.section_ndw = 0;
cs->crelocs = 0;
- csg->chunks[0].length_dw = 0;
- csg->chunks[1].length_dw = 0;
- csg->chunks[2].length_dw = 0;
+ csg->num_ibs_used = 1;
+ csg->reloc_length_dw = 0;
+ csg->base.packets = csg->ibs[0].packets;
return 0;
}
diff --git a/radeon/radeon_cs_gem.h b/radeon/radeon_cs_gem.h
index fb51cd5d..340ed500 100644
--- a/radeon/radeon_cs_gem.h
+++ b/radeon/radeon_cs_gem.h
@@ -1,3 +1,4 @@
+
/*
* Copyright © 2008 Nicolai Haehnle
* Copyright © 2008 Jérôme Glisse
@@ -38,7 +39,7 @@
struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd);
void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm);
-void radeon_cs_gem_switch_alt(struct radeon_cs *cs);
struct radeon_cs *radeon_cs_gem_create_setup(struct radeon_cs_manager *csm,
- uint32_t ndw, uint32_t setup_ndw);
+ uint32_t ndw, uint32_t num_ibs);
+int radeon_cs_gem_switch_next_ib(struct radeon_cs *cs);
#endif