diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-03-17 21:49:56 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-03-18 15:11:30 +0000 |
commit | fe8866d6112c3e187d6682e9e4610325668427a0 (patch) | |
tree | af89ecaff6015acf6f6b89d55329e1ae4ab81776 | |
parent | 97cd0c7da51024400e8900e46f51620a5f7ad402 (diff) |
sna/gen[345]: Convert CPU mappings to GTT for vertices on submit
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/gen3_render.c | 24 | ||||
-rw-r--r-- | src/sna/gen4_render.c | 57 | ||||
-rw-r--r-- | src/sna/gen5_render.c | 25 | ||||
-rw-r--r-- | src/sna/kgem.c | 37 | ||||
-rw-r--r-- | src/sna/kgem.h | 4 |
5 files changed, 121 insertions, 26 deletions
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c index 0991a986..67c8956a 100644 --- a/src/sna/gen3_render.c +++ b/src/sna/gen3_render.c @@ -1680,14 +1680,21 @@ static void gen3_vertex_close(struct sna *sna) bo = sna->render.vbo; if (bo) { - if (IS_CPU_MAP(bo->map) || - sna->render.vertex_size - sna->render.vertex_used < 64) { - DBG(("%s: discarding vbo (was CPU mapped)\n", - __FUNCTION__)); + if (sna->render.vertex_size - sna->render.vertex_used < 64) { + DBG(("%s: discarding full vbo\n", __FUNCTION__)); sna->render.vbo = NULL; sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); free_bo = bo; + } else if (IS_CPU_MAP(bo->map)) { + DBG(("%s: converting CPU map to GTT\n", __FUNCTION__)); + sna->render.vertices = kgem_bo_map__gtt(&sna->kgem, bo); + if (sna->render.vertices == NULL) { + sna->render.vbo = NULL; + sna->render.vertices = sna->render.vertex_data; + sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); + free_bo = bo; + } } } else { if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) { @@ -1950,6 +1957,15 @@ gen3_render_reset(struct sna *sna) state->last_floats_per_vertex = 0; state->last_vertex_offset = 0; state->vertex_offset = 0; + + if (sna->render.vbo && + !kgem_bo_is_mappable(&sna->kgem, sna->render.vbo)) { + DBG(("%s: discarding unmappable vbo\n", __FUNCTION__)); + kgem_bo_destroy(&sna->kgem, sna->render.vbo); + sna->render.vbo = NULL; + sna->render.vertices = sna->render.vertex_data; + sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); + } } static void diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c index a69852e0..def5d19a 100644 --- a/src/sna/gen4_render.c +++ b/src/sna/gen4_render.c @@ -419,9 +419,14 @@ static int gen4_vertex_finish(struct sna *sna) static void gen4_vertex_close(struct sna *sna) { - struct kgem_bo *bo; + struct kgem_bo *bo, *free_bo = NULL; unsigned int i, delta = 0; + assert(sna->render_state.gen4.vertex_offset == 0); + + DBG(("%s: used=%d, vbo active? %d\n", + __FUNCTION__, sna->render.vertex_used, sna->render.vbo != NULL)); + if (!sna->render.vertex_used) { assert(sna->render.vbo == NULL); assert(sna->render.vertices == sna->render.vertex_data); @@ -429,10 +434,26 @@ static void gen4_vertex_close(struct sna *sna) return; } - DBG(("%s: used=%d\n", __FUNCTION__, sna->render.vertex_used)); - bo = sna->render.vbo; - if (bo == NULL) { + if (bo) { + if (sna->render.vertex_size - sna->render.vertex_used < 64) { + DBG(("%s: discarding full vbo\n", __FUNCTION__)); + sna->render.vbo = NULL; + sna->render.vertices = sna->render.vertex_data; + sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); + free_bo = bo; + } else if (IS_CPU_MAP(bo->map)) { + DBG(("%s: converting CPU map to GTT\n", __FUNCTION__)); + sna->render.vertices = + kgem_bo_map__gtt(&sna->kgem, sna->render.vbo); + if (sna->render.vertices == NULL) { + sna->render.vbo = NULL; + sna->render.vertices = sna->render.vertex_data; + sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); + free_bo = bo; + } + } + } else { if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) { DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__, sna->render.vertex_used, sna->kgem.nbatch)); @@ -449,10 +470,11 @@ static void gen4_vertex_close(struct sna *sna) sna->render.vertex_data, 4*sna->render.vertex_used)) { kgem_bo_destroy(&sna->kgem, bo); - goto reset; + bo = NULL; } DBG(("%s: new vbo: %d\n", __FUNCTION__, sna->render.vertex_used)); + free_bo = bo; } } @@ -471,17 +493,13 @@ static void gen4_vertex_close(struct sna *sna) } } - if (bo) - kgem_bo_destroy(&sna->kgem, bo); - -reset: - sna->render.vertex_used = 0; - sna->render.vertex_index = 0; - sna->render_state.gen4.vb_id = 0; + if (sna->render.vbo == NULL) { + sna->render.vertex_used = 0; + sna->render.vertex_index = 0; + } - sna->render.vbo = NULL; - sna->render.vertices = sna->render.vertex_data; - sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); + if (free_bo) + kgem_bo_destroy(&sna->kgem, free_bo); } @@ -3207,6 +3225,15 @@ static void gen4_render_reset(struct sna *sna) sna->render_state.gen4.drawrect_offset = -1; sna->render_state.gen4.drawrect_limit = -1; sna->render_state.gen4.surface_table = -1; + + if (sna->render.vbo && + !kgem_bo_is_mappable(&sna->kgem, sna->render.vbo)) { + DBG(("%s: discarding unmappable vbo\n", __FUNCTION__)); + kgem_bo_destroy(&sna->kgem, sna->render.vbo); + sna->render.vbo = NULL; + sna->render.vertices = sna->render.vertex_data; + sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); + } } static void gen4_render_fini(struct sna *sna) diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c index 01604ef9..565d22aa 100644 --- a/src/sna/gen5_render.c +++ b/src/sna/gen5_render.c @@ -428,14 +428,22 @@ static void gen5_vertex_close(struct sna *sna) bo = sna->render.vbo; if (bo) { - if (IS_CPU_MAP(bo->map) || - sna->render.vertex_size - sna->render.vertex_used < 64) { - DBG(("%s: discarding vbo (was CPU mapped)\n", - __FUNCTION__)); + if (sna->render.vertex_size - sna->render.vertex_used < 64) { + DBG(("%s: discarding full vbo\n", __FUNCTION__)); sna->render.vbo = NULL; sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); free_bo = bo; + } else if (IS_CPU_MAP(bo->map)) { + DBG(("%s: converting CPU map to GTT\n", __FUNCTION__)); + sna->render.vertices = + kgem_bo_map__gtt(&sna->kgem, sna->render.vbo); + if (sna->render.vertices == NULL) { + sna->render.vbo = NULL; + sna->render.vertices = sna->render.vertex_data; + sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); + free_bo = bo; + } } } else { if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) { @@ -3655,6 +3663,15 @@ static void gen5_render_reset(struct sna *sna) sna->render_state.gen5.drawrect_offset = -1; sna->render_state.gen5.drawrect_limit = -1; sna->render_state.gen5.surface_table = -1; + + if (sna->render.vbo && + !kgem_bo_is_mappable(&sna->kgem, sna->render.vbo)) { + DBG(("%s: discarding unmappable vbo\n", __FUNCTION__)); + kgem_bo_destroy(&sna->kgem, sna->render.vbo); + sna->render.vbo = NULL; + sna->render.vertices = sna->render.vertex_data; + sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); + } } static void gen5_render_fini(struct sna *sna) diff --git a/src/sna/kgem.c b/src/sna/kgem.c index daca7afd..8a2222cf 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -3190,6 +3190,43 @@ void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo) return ptr; } +void *kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo) +{ + void *ptr; + + DBG(("%s: handle=%d, offset=%d, tiling=%d, map=%p, domain=%d\n", __FUNCTION__, + bo->handle, bo->presumed_offset, bo->tiling, bo->map, bo->domain)); + + assert(!bo->purged); + assert(bo->exec == NULL); + assert(list_is_empty(&bo->list)); + + if (IS_CPU_MAP(bo->map)) + kgem_bo_release_map(kgem, bo); + + ptr = bo->map; + if (ptr == NULL) { + assert(bytes(bo) <= kgem->aperture_mappable / 4); + + kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo)); + + ptr = gem_mmap(kgem->fd, bo->handle, bytes(bo), + PROT_READ | PROT_WRITE); + if (ptr == NULL) + return NULL; + + /* Cache this mapping to avoid the overhead of an + * excruciatingly slow GTT pagefault. This is more an + * issue with compositing managers which need to frequently + * flush CPU damage to their GPU bo. + */ + bo->map = ptr; + DBG(("%s: caching GTT vma for %d\n", __FUNCTION__, bo->handle)); + } + + return ptr; +} + void *kgem_bo_map__debug(struct kgem *kgem, struct kgem_bo *bo) { if (bo->map) diff --git a/src/sna/kgem.h b/src/sna/kgem.h index 98534d93..27e0e040 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -364,6 +364,7 @@ uint32_t kgem_add_reloc(struct kgem *kgem, uint32_t delta); void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo); +void *kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo); void *kgem_bo_map__debug(struct kgem *kgem, struct kgem_bo *bo); void *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo); void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo); @@ -425,9 +426,6 @@ static inline bool kgem_bo_is_mappable(struct kgem *kgem, if (bo->domain == DOMAIN_GTT) return true; - if (IS_GTT_MAP(bo->map)) - return true; - if (kgem->gen < 40 && bo->tiling && bo->presumed_offset & (kgem_bo_fenced_size(kgem, bo) - 1)) return false; |