vc4: Handle refcounting the exec BO like we do in the kernel.
authorEric Anholt <eric@anholt.net>
Fri, 12 Jun 2015 19:47:47 +0000 (12:47 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 16 Jun 2015 22:15:14 +0000 (15:15 -0700)
This reduces the diff to the kernel, and will be useful when I make the
kernel allocate more BOs as part of validation.

src/gallium/drivers/vc4/kernel/vc4_drv.h
src/gallium/drivers/vc4/kernel/vc4_gem.c
src/gallium/drivers/vc4/vc4_simulator.c
src/gallium/drivers/vc4/vc4_simulator_validate.h

index dede7162c424d45389f7274ba56790eaedc42fe9..8e9230b8949af859fc668e77883be608d44dec99 100644 (file)
@@ -52,6 +52,11 @@ struct vc4_exec_info {
        struct vc4_bo_exec_state *bo;
        uint32_t bo_count;
 
+       /* List of other BOs used in the job that need to be released
+        * once the job is complete.
+        */
+       struct list_head unref_list;
+
        /* Current unvalidated indices into @bo loaded by the non-hardware
         * VC4_PACKET_GEM_HANDLES.
         */
index ac29ab35dbca12bd5e9902e708a4387fe28312f1..e559ddd1d4e4504776e0dd53eee2c4cdec221304 100644 (file)
@@ -114,6 +114,9 @@ vc4_cl_validate(struct drm_device *dev, struct vc4_exec_info *exec)
        }
 #endif
 
+       list_addtail(&to_vc4_bo(&exec->exec_bo->base)->unref_head,
+                    &exec->unref_list);
+
        exec->ct0ca = exec->exec_bo->paddr + bin_offset;
        exec->ct1ca = exec->exec_bo->paddr + render_offset;
 
index 2f72e722fc558edf6db5b4f30b33df7c716da0b8..2e4d8798f8e3f06bda305a38f1ba4028b0fcff5d 100644 (file)
@@ -39,10 +39,11 @@ vc4_wrap_bo_with_cma(struct drm_device *dev, struct vc4_bo *bo)
 {
         struct vc4_context *vc4 = dev->vc4;
         struct vc4_screen *screen = vc4->screen;
-        struct drm_gem_cma_object *obj = CALLOC_STRUCT(drm_gem_cma_object);
+        struct drm_vc4_bo *drm_bo = CALLOC_STRUCT(drm_vc4_bo);
+        struct drm_gem_cma_object *obj = &drm_bo->base;
         uint32_t size = align(bo->size, 4096);
 
-        obj->bo = bo;
+        drm_bo->bo = bo;
         obj->base.size = size;
         obj->vaddr = screen->simulator_mem_base + dev->simulator_mem_next;
         obj->paddr = simpenrose_hw_addr(obj->vaddr);
@@ -94,7 +95,7 @@ vc4_simulator_unpin_bos(struct vc4_exec_info *exec)
 {
         for (int i = 0; i < exec->bo_count; i++) {
                 struct drm_gem_cma_object *obj = exec->bo[i].bo;
-                struct vc4_bo *bo = obj->bo;
+                struct vc4_bo *bo = to_vc4_bo(&obj->base)->bo;
 
                 memcpy(bo->map, obj->vaddr, bo->size);
 
@@ -124,6 +125,7 @@ vc4_simulator_flush(struct vc4_context *vc4, struct drm_vc4_submit_cl *args)
         int ret;
 
         memset(&exec, 0, sizeof(exec));
+        list_inithead(&exec.unref_list);
 
         if (ctex && ctex->bo->simulator_winsys_map) {
 #if 0
@@ -176,8 +178,12 @@ vc4_simulator_flush(struct vc4_context *vc4, struct drm_vc4_submit_cl *args)
         if (ret)
                 return ret;
 
-        vc4_bo_unreference(&exec.exec_bo->bo);
-        free(exec.exec_bo);
+        list_for_each_entry_safe(struct drm_vc4_bo, bo, &exec.unref_list,
+                                 unref_head) {
+               list_del(&bo->unref_head);
+                vc4_bo_unreference(&bo->bo);
+                free(bo);
+        }
 
         if (ctex && ctex->bo->simulator_winsys_map) {
                 for (int y = 0; y < ctex->base.b.height0; y++) {
index a1903269a20e2361321657d6376dc25a16395515..c3b7a638f93ba89c23f8037444a558f97962a9fd 100644 (file)
@@ -64,16 +64,26 @@ struct drm_device {
         uint32_t simulator_mem_next;
 };
 
-struct drm_gem_cma_object {
-        struct vc4_bo *bo;
+struct drm_gem_object {
+        uint32_t size;
+};
 
-        struct {
-                uint32_t size;
-        } base;
+struct drm_gem_cma_object {
+        struct drm_gem_object base;
         uint32_t paddr;
         void *vaddr;
 };
 
+struct drm_vc4_bo {
+        struct drm_gem_cma_object base;
+        struct vc4_bo *bo;
+        struct list_head unref_head;
+};
+
+static inline struct drm_vc4_bo *to_vc4_bo(struct drm_gem_object *obj)
+{
+        return (struct drm_vc4_bo *)obj;
+}
 
 struct drm_gem_cma_object *
 drm_gem_cma_create(struct drm_device *dev, size_t size);