diff --git a/src/nouveau/winsys/nouveau_push.c b/src/nouveau/winsys/nouveau_push.c index 28879ea3216..67415b65eae 100644 --- a/src/nouveau/winsys/nouveau_push.c +++ b/src/nouveau/winsys/nouveau_push.c @@ -62,12 +62,41 @@ fail_bo: return NULL; } +void +nouveau_ws_push_init_cpu(struct nouveau_ws_push *push, + void *data, size_t size) +{ + push->map = data; + push->orig_map = push->map; + push->end = push->map + size; + + util_dynarray_init(&push->bos, NULL); +} + void nouveau_ws_push_destroy(struct nouveau_ws_push *push) { util_dynarray_fini(&push->bos); - munmap(push->orig_map, push->bo->size); - nouveau_ws_bo_destroy(push->bo); + if (push->bo) { + munmap(push->orig_map, push->bo->size); + nouveau_ws_bo_destroy(push->bo); + } +} + +void +nouveau_ws_push_append(struct nouveau_ws_push *push, + const struct nouveau_ws_push *other) +{ + /* We only use this for CPU pushes. */ + assert(other->bo == NULL); + + /* We don't support BO refs for now */ + assert(other->bos.size == 0); + + size_t count = other->map - other->orig_map; + memcpy(push->map, other->orig_map, count * sizeof(*push->map)); + push->map += count; + push->last_size = NULL; } static void @@ -249,6 +278,9 @@ nouveau_ws_push_submit( struct drm_nouveau_gem_pushbuf req = {}; struct drm_nouveau_gem_pushbuf_push req_push = {}; + /* Can't submit a CPU push */ + assert(push->bo); + if (push->map == push->orig_map) return 0; diff --git a/src/nouveau/winsys/nouveau_push.h b/src/nouveau/winsys/nouveau_push.h index 1b093296d91..19b371a74fe 100644 --- a/src/nouveau/winsys/nouveau_push.h +++ b/src/nouveau/winsys/nouveau_push.h @@ -25,7 +25,11 @@ struct nouveau_ws_push { }; struct nouveau_ws_push *nouveau_ws_push_new(struct nouveau_ws_device *, uint64_t size); +void nouveau_ws_push_init_cpu(struct nouveau_ws_push *push, + void *data, size_t size); void nouveau_ws_push_destroy(struct nouveau_ws_push *); +void nouveau_ws_push_append(struct nouveau_ws_push *, + const struct nouveau_ws_push *); int nouveau_ws_push_submit(struct nouveau_ws_push *, struct nouveau_ws_device *, struct nouveau_ws_context *); void nouveau_ws_push_ref(struct nouveau_ws_push *, struct nouveau_ws_bo *, enum nouveau_ws_bo_map_flags); void nouveau_ws_push_reset(struct nouveau_ws_push *);