From: Jason Ekstrand Date: Fri, 22 May 2015 22:15:08 +0000 (-0700) Subject: vk: Actually implement some sort of destructor for all object types X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=57153da2d5fe95e0eb731d827ba940028a80cf1c;p=mesa.git vk: Actually implement some sort of destructor for all object types --- diff --git a/src/vulkan/device.c b/src/vulkan/device.c index a1c8846f214..db90093eb85 100644 --- a/src/vulkan/device.c +++ b/src/vulkan/device.c @@ -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] = diff --git a/src/vulkan/pipeline.c b/src/vulkan/pipeline.c index 52c96a248cc..a9594a71c95 100644 --- a/src/vulkan/pipeline.c +++ b/src/vulkan/pipeline.c @@ -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, diff --git a/src/vulkan/private.h b/src/vulkan/private.h index da568e87017..b957151cdbc 100644 --- a/src/vulkan/private.h +++ b/src/vulkan/private.h @@ -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;