vk: Actually implement some sort of destructor for all object types
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 22 May 2015 22:15:08 +0000 (15:15 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Fri, 22 May 2015 22:15:08 +0000 (15:15 -0700)
src/vulkan/device.c
src/vulkan/pipeline.c
src/vulkan/private.h

index a1c8846f2145af55370710151f3c238378b169e4..db90093eb857f26d59d3680c4ea4e7a4a14713e2 100644 (file)
@@ -930,117 +930,72 @@ VkResult anv_OpenPeerImage(
    return VK_UNSUPPORTED;
 }
 
-static VkResult
-anv_instance_destructor(struct anv_device *     device,
-                        VkObject                object)
-{
-   return vkDestroyInstance(object);
-}
-
-static VkResult
-anv_noop_destructor(struct anv_device *         device,
-                    VkObject                    object)
-{
-   return VK_SUCCESS;
-}
-
-static VkResult
-anv_device_destructor(struct anv_device *       device,
-                      VkObject                  object)
-{
-   return vkDestroyDevice(object);
-}
-
-static VkResult
-anv_cmd_buffer_destructor(struct anv_device *   device,
-                          VkObject              object)
-{
-   struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) object;
-   
-   anv_gem_munmap(cmd_buffer->surface_bo.map, BATCH_SIZE);
-   anv_gem_close(device, cmd_buffer->surface_bo.gem_handle);
-   anv_state_stream_finish(&cmd_buffer->surface_state_stream);
-   anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
-   anv_state_stream_finish(&cmd_buffer->binding_table_state_stream);
-   anv_batch_finish(&cmd_buffer->batch, device);
-   anv_device_free(device, cmd_buffer->exec2_objects);
-   anv_device_free(device, cmd_buffer->exec2_bos);
-   anv_device_free(device, cmd_buffer);
-
-   return VK_SUCCESS;
-}
-
-static VkResult
-anv_pipeline_destructor(struct anv_device *   device,
-                        VkObject              object)
-{
-   struct anv_pipeline *pipeline = (struct anv_pipeline *) object;
-
-   return anv_pipeline_destroy(pipeline);
-}
-
-static VkResult
-anv_free_destructor(struct anv_device *         device,
-                    VkObject                    object)
+VkResult anv_DestroyObject(
+    VkDevice                                    _device,
+    VkObjectType                                objType,
+    VkObject                                    _object)
 {
-   anv_device_free(device, (void *) object);
+   struct anv_device *device = (struct anv_device *) _device;
+   struct anv_object *object = (struct anv_object *) _object;
 
-   return VK_SUCCESS;
-}
+   switch (objType) {
+   case VK_OBJECT_TYPE_INSTANCE:
+      return anv_DestroyInstance((VkInstance) _object);
 
-static VkResult
-anv_fence_destructor(struct anv_device *   device,
-                     VkObject              object)
-{
-   struct anv_fence *fence = (struct anv_fence *) object;
+   case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
+      /* We don't want to actually destroy physical devices */
+      return VK_SUCCESS;
 
-   anv_gem_munmap(fence->bo.map, fence->bo.size);
-   anv_gem_close(device, fence->bo.gem_handle);
-   anv_device_free(device, fence);
+   case VK_OBJECT_TYPE_DEVICE:
+      assert(_device == (VkDevice) _object);
+      return anv_DestroyDevice((VkDevice) _object);
 
-   return VK_SUCCESS;
-}
+   case VK_OBJECT_TYPE_QUEUE:
+      /* TODO */
+      return VK_SUCCESS;
 
-static VkResult
-anv_query_pool_destructor(struct anv_device *   device,
-                          VkObject              object)
-{
-   struct anv_query_pool *pool = (struct anv_query_pool *) object;
+   case VK_OBJECT_TYPE_DEVICE_MEMORY:
+      return anv_FreeMemory(_device, (VkDeviceMemory) _object);
 
-   anv_gem_munmap(pool->bo.map, pool->bo.size);
-   anv_gem_close(device, pool->bo.gem_handle);
-   anv_device_free(device, pool);
+   case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
+      /* These are just dummys anyway, so we don't need to destroy them */
+      return VK_SUCCESS;
 
-   return VK_SUCCESS;
-}
+   case VK_OBJECT_TYPE_BUFFER:
+   case VK_OBJECT_TYPE_BUFFER_VIEW:
+   case VK_OBJECT_TYPE_IMAGE:
+   case VK_OBJECT_TYPE_IMAGE_VIEW:
+   case VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW:
+   case VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW:
+   case VK_OBJECT_TYPE_SHADER:
+   case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
+   case VK_OBJECT_TYPE_SAMPLER:
+   case VK_OBJECT_TYPE_DESCRIPTOR_SET:
+   case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
+   case VK_OBJECT_TYPE_DYNAMIC_RS_STATE:
+   case VK_OBJECT_TYPE_DYNAMIC_CB_STATE:
+   case VK_OBJECT_TYPE_DYNAMIC_DS_STATE:
+   case VK_OBJECT_TYPE_RENDER_PASS:
+      /* These are trivially destroyable */
+      anv_device_free(device, (void *) _object);
+      return VK_SUCCESS;
 
-static VkResult (*anv_object_destructors[])(struct anv_device *device,
-                                            VkObject object) = {
-   [VK_OBJECT_TYPE_INSTANCE] =        anv_instance_destructor,
-   [VK_OBJECT_TYPE_PHYSICAL_DEVICE] = anv_noop_destructor,
-   [VK_OBJECT_TYPE_DEVICE] =          anv_device_destructor,
-   [VK_OBJECT_TYPE_QUEUE] =           anv_noop_destructor,
-   [VK_OBJECT_TYPE_COMMAND_BUFFER] =  anv_cmd_buffer_destructor,
-   [VK_OBJECT_TYPE_PIPELINE] =        anv_pipeline_destructor,
-   [VK_OBJECT_TYPE_SHADER] =          anv_free_destructor,
-   [VK_OBJECT_TYPE_BUFFER] =          anv_free_destructor,
-   [VK_OBJECT_TYPE_IMAGE] =           anv_free_destructor,
-   [VK_OBJECT_TYPE_RENDER_PASS] =     anv_free_destructor,
-   [VK_OBJECT_TYPE_FENCE] =           anv_fence_destructor,
-   [VK_OBJECT_TYPE_QUERY_POOL] =      anv_query_pool_destructor
-};
+   case VK_OBJECT_TYPE_COMMAND_BUFFER:
+   case VK_OBJECT_TYPE_PIPELINE:
+   case VK_OBJECT_TYPE_DYNAMIC_VP_STATE:
+   case VK_OBJECT_TYPE_FENCE:
+   case VK_OBJECT_TYPE_QUERY_POOL:
+   case VK_OBJECT_TYPE_FRAMEBUFFER:
+      (object->destructor)(device, object, objType);
+      return VK_SUCCESS;
 
-VkResult anv_DestroyObject(
-    VkDevice                                    _device,
-    VkObjectType                                objType,
-    VkObject                                    object)
-{
-   struct anv_device *device = (struct anv_device *) _device;
+   case VK_OBJECT_TYPE_SEMAPHORE:
+   case VK_OBJECT_TYPE_EVENT:
+      stub_return(VK_UNSUPPORTED);
 
-   assert(objType < ARRAY_SIZE(anv_object_destructors) &&
-          anv_object_destructors[objType] != NULL);
-      
-   return anv_object_destructors[objType](device, object);
+   default:
+      unreachable("Invalid object type");
+   }
 }
 
 static void
@@ -1180,6 +1135,20 @@ VkResult anv_QueueBindImageMemoryRange(
    stub_return(VK_UNSUPPORTED);
 }
 
+static void
+anv_fence_destroy(struct anv_device *device,
+                  struct anv_object *object,
+                  VkObjectType obj_type)
+{
+   struct anv_fence *fence = (struct anv_fence *) object;
+
+   assert(obj_type == VK_OBJECT_TYPE_FENCE);
+
+   anv_gem_munmap(fence->bo.map, fence->bo.size);
+   anv_gem_close(device, fence->bo.gem_handle);
+   anv_device_free(device, fence);
+}
+
 VkResult anv_CreateFence(
     VkDevice                                    _device,
     const VkFenceCreateInfo*                    pCreateInfo,
@@ -1203,6 +1172,8 @@ VkResult anv_CreateFence(
    if (result != VK_SUCCESS)
       goto fail;
 
+   fence->base.destructor = anv_fence_destroy;
+
    fence->bo.map =
       anv_gem_mmap(device, fence->bo.gem_handle, 0, fence->bo.size);
    batch.next = fence->bo.map;
@@ -1358,6 +1329,20 @@ VkResult anv_ResetEvent(
 
 // Query functions
 
+static void
+anv_query_pool_destroy(struct anv_device *device,
+                       struct anv_object *object,
+                       VkObjectType obj_type)
+{
+   struct anv_query_pool *pool = (struct anv_query_pool *) object;
+
+   assert(obj_type == VK_OBJECT_TYPE_QUERY_POOL);
+
+   anv_gem_munmap(pool->bo.map, pool->bo.size);
+   anv_gem_close(device, pool->bo.gem_handle);
+   anv_device_free(device, pool);
+}
+
 VkResult anv_CreateQueryPool(
     VkDevice                                    _device,
     const VkQueryPoolCreateInfo*                pCreateInfo,
@@ -1384,6 +1369,8 @@ VkResult anv_CreateQueryPool(
    if (pool == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
+   pool->base.destructor = anv_query_pool_destroy;
+
    pool->type = pCreateInfo->queryType;
    size = pCreateInfo->slots * sizeof(struct anv_query_pool_slot);
    result = anv_bo_init_new(&pool->bo, device, size);
@@ -1936,6 +1923,22 @@ clamp_int64(int64_t x, int64_t min, int64_t max)
       return max;
 }
 
+static void
+anv_dynamic_vp_state_destroy(struct anv_device *device,
+                             struct anv_object *object,
+                             VkObjectType obj_type)
+{
+   struct anv_dynamic_vp_state *state = (void *)object;
+
+   assert(obj_type == VK_OBJECT_TYPE_DYNAMIC_VP_STATE);
+
+   anv_state_pool_free(&device->dynamic_state_pool, state->sf_clip_vp);
+   anv_state_pool_free(&device->dynamic_state_pool, state->cc_vp);
+   anv_state_pool_free(&device->dynamic_state_pool, state->scissor);
+
+   anv_device_free(device, state);
+}
+
 VkResult anv_CreateDynamicViewportState(
     VkDevice                                    _device,
     const VkDynamicVpStateCreateInfo*           pCreateInfo,
@@ -1951,6 +1954,8 @@ VkResult anv_CreateDynamicViewportState(
    if (state == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
+   state->base.destructor = anv_dynamic_vp_state_destroy;
+
    unsigned count = pCreateInfo->viewportAndScissorCount;
    state->sf_clip_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
                                             count * 64, 64);
@@ -2087,6 +2092,26 @@ VkResult anv_CreateDynamicDepthStencilState(
 
 // Command buffer functions
 
+static void
+anv_cmd_buffer_destroy(struct anv_device *device,
+                       struct anv_object *object,
+                       VkObjectType obj_type)
+{
+   struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) object;
+
+   assert(obj_type == VK_OBJECT_TYPE_COMMAND_BUFFER);
+
+   anv_gem_munmap(cmd_buffer->surface_bo.map, BATCH_SIZE);
+   anv_gem_close(device, cmd_buffer->surface_bo.gem_handle);
+   anv_state_stream_finish(&cmd_buffer->surface_state_stream);
+   anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
+   anv_state_stream_finish(&cmd_buffer->binding_table_state_stream);
+   anv_batch_finish(&cmd_buffer->batch, device);
+   anv_device_free(device, cmd_buffer->exec2_objects);
+   anv_device_free(device, cmd_buffer->exec2_bos);
+   anv_device_free(device, cmd_buffer);
+}
+
 VkResult anv_CreateCommandBuffer(
     VkDevice                                    _device,
     const VkCmdBufferCreateInfo*                pCreateInfo,
@@ -2101,6 +2126,8 @@ VkResult anv_CreateCommandBuffer(
    if (cmd_buffer == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
+   cmd_buffer->base.destructor = anv_cmd_buffer_destroy;
+
    cmd_buffer->device = device;
    cmd_buffer->rs_state = NULL;
    cmd_buffer->vp_state = NULL;
@@ -3062,6 +3089,22 @@ void anv_CmdSaveAtomicCounters(
    stub();
 }
 
+static void
+anv_framebuffer_destroy(struct anv_device *device,
+                        struct anv_object *object,
+                        VkObjectType obj_type)
+{
+   struct anv_framebuffer *fb = (struct anv_framebuffer *)object;
+
+   assert(obj_type == VK_OBJECT_TYPE_FRAMEBUFFER);
+
+   anv_DestroyObject((VkDevice) device,
+                     VK_OBJECT_TYPE_DYNAMIC_VP_STATE,
+                     fb->vp_state);
+
+   anv_device_free(device, fb);
+}
+
 VkResult anv_CreateFramebuffer(
     VkDevice                                    _device,
     const VkFramebufferCreateInfo*              pCreateInfo,
@@ -3077,6 +3120,8 @@ VkResult anv_CreateFramebuffer(
    if (framebuffer == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
+   framebuffer->base.destructor = anv_framebuffer_destroy;
+
    framebuffer->color_attachment_count = pCreateInfo->colorAttachmentCount;
    for (uint32_t i = 0; i < pCreateInfo->colorAttachmentCount; i++) {
       framebuffer->color_attachments[i] =
index 52c96a248cc34045560ac5813e0213cee7453820..a9594a71c95ce0bd5d7eeae7fcdaf95864736fc4 100644 (file)
@@ -224,6 +224,19 @@ VkResult anv_CreateGraphicsPipeline(
    return anv_pipeline_create(device, pCreateInfo, NULL, pPipeline);
 }
 
+static void
+anv_pipeline_destroy(struct anv_device *device,
+                     struct anv_object *object,
+                     VkObjectType obj_type)
+{
+   struct anv_pipeline *pipeline = (struct anv_pipeline*) object;
+
+   assert(obj_type == VK_OBJECT_TYPE_PIPELINE);
+
+   anv_compiler_free(pipeline);
+   anv_batch_finish(&pipeline->batch, pipeline->device);
+   anv_device_free(pipeline->device, pipeline);
+}
 
 VkResult
 anv_pipeline_create(
@@ -249,6 +262,7 @@ anv_pipeline_create(
    if (pipeline == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
+   pipeline->base.destructor = anv_pipeline_destroy;
    pipeline->device = device;
    pipeline->layout = (struct anv_pipeline_layout *) pCreateInfo->layout;
    memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
@@ -501,16 +515,6 @@ anv_pipeline_create(
    return result;
 }
 
-VkResult
-anv_pipeline_destroy(struct anv_pipeline *pipeline)
-{
-   anv_compiler_free(pipeline);
-   anv_batch_finish(&pipeline->batch, pipeline->device);
-   anv_device_free(pipeline->device, pipeline);
-
-   return VK_SUCCESS;
-}
-
 VkResult anv_CreateGraphicsPipelineDerivative(
     VkDevice                                    device,
     const VkGraphicsPipelineCreateInfo*         pCreateInfo,
index da568e87017fcea7a2ac5bb1c52fb5659e94955a..b957151cdbc0358946d7b6d8c4f97c3a8314d6c2 100644 (file)
@@ -251,6 +251,17 @@ void anv_state_stream_finish(struct anv_state_stream *stream);
 struct anv_state anv_state_stream_alloc(struct anv_state_stream *stream,
                                         uint32_t size, uint32_t alignment);
 
+struct anv_object;
+struct anv_device;
+
+typedef void (*anv_object_destructor_cb)(struct anv_device *,
+                                         struct anv_object *,
+                                         VkObjectType);
+
+struct anv_object {
+   anv_object_destructor_cb                     destructor;
+};
+
 struct anv_physical_device {
     struct anv_instance *                       instance;
     uint32_t                                    chipset_id;
@@ -437,12 +448,13 @@ __gen_combine_address(struct anv_batch *batch, void *location,
    } while (0)
 
 struct anv_device_memory {
-   struct anv_bo bo;
-   VkDeviceSize map_size;
-   void *map;
+   struct anv_bo                                bo;
+   VkDeviceSize                                 map_size;
+   void *                                       map;
 };
 
 struct anv_dynamic_vp_state {
+   struct anv_object base;
    struct anv_state sf_clip_vp;
    struct anv_state cc_vp;
    struct anv_state scissor;
@@ -463,6 +475,7 @@ struct anv_query_pool_slot {
 };
 
 struct anv_query_pool {
+   struct anv_object                            base;
    VkQueryType                                  type;
    uint32_t                                     slots;
    struct anv_bo                                bo;
@@ -535,6 +548,7 @@ struct anv_bindings {
 };
 
 struct anv_cmd_buffer {
+   struct anv_object                            base;
    struct anv_device *                          device;
 
    struct drm_i915_gem_execbuffer2              execbuf;
@@ -567,6 +581,7 @@ void anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer);
 void anv_aub_writer_destroy(struct anv_aub_writer *writer);
 
 struct anv_fence {
+   struct anv_object base;
    struct anv_bo bo;
    struct drm_i915_gem_execbuffer2 execbuf;
    struct drm_i915_gem_exec_object2 exec2_objects[1];
@@ -579,6 +594,7 @@ struct anv_shader {
 };
 
 struct anv_pipeline {
+   struct anv_object                            base;
    struct anv_device *                          device;
    struct anv_batch                             batch;
    struct anv_shader *                          shaders[VK_NUM_SHADER_STAGE];
@@ -631,8 +647,6 @@ anv_pipeline_create(VkDevice device,
                     const struct anv_pipeline_create_info *extra,
                     VkPipeline *pPipeline);
 
-VkResult anv_pipeline_destroy(struct anv_pipeline *pipeline);
-
 struct anv_compiler *anv_compiler_create(int fd);
 void anv_compiler_destroy(struct anv_compiler *compiler);
 int anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline);
@@ -698,6 +712,7 @@ struct anv_depth_stencil_view {
 };
 
 struct anv_framebuffer {
+   struct anv_object                            base;
    uint32_t                                     color_attachment_count;
    struct anv_surface_view *                    color_attachments[MAX_RTS];
    struct anv_depth_stencil_view *              depth_stencil;