diff options
author | Dave Airlie <airlied@redhat.com> | 2010-07-06 16:54:20 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-07-06 16:54:20 +1000 |
commit | 3fc3ee1250e308ff535997f19616e82efcca3025 (patch) | |
tree | 1b7f911d586d67cfab2316e3d3733c64c6c27788 | |
parent | d8ef7c15dedd6cbb48a6866131f6a9a15e627e12 (diff) |
planb: multi-ib command submissioncs-start
-rw-r--r-- | include/drm/radeon_drm.h | 2 | ||||
-rw-r--r-- | radeon/radeon_cs_gem.c | 123 | ||||
-rw-r--r-- | radeon/radeon_cs_gem.h | 5 |
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 |