Quellcode durchsuchen

Merge pull request #3214 from jpark37/vulkan-family-cleanup

win-capture: Make Vulkan frame data local to queue
Jim vor 5 Jahren
Ursprung
Commit
f22cde5073
1 geänderte Dateien mit 99 neuen und 71 gelöschten Zeilen
  1. 99 71
      plugins/win-capture/graphics-hook/vulkan-capture.c

+ 99 - 71
plugins/win-capture/graphics-hook/vulkan-capture.c

@@ -59,6 +59,9 @@ struct vk_queue_data {
 
 	uint32_t fam_idx;
 	bool supports_transfer;
+	struct vk_frame_data *frames;
+	uint32_t frame_index;
+	uint32_t frame_count;
 };
 
 struct vk_frame_data {
@@ -68,12 +71,6 @@ struct vk_frame_data {
 	bool cmd_buffer_busy;
 };
 
-struct vk_family_data {
-	struct vk_frame_data *frames;
-	uint32_t frame_index;
-	uint32_t frame_count;
-};
-
 struct vk_surf_data {
 	struct vk_obj_node node;
 
@@ -103,8 +100,6 @@ struct vk_data {
 
 	struct vk_obj_list queues;
 
-	struct vk_family_data *families;
-	uint32_t family_capacity;
 	VkExternalMemoryProperties external_mem_props;
 
 	struct vk_inst_data *inst_data;
@@ -200,6 +195,22 @@ static void init_obj_list(struct vk_obj_list *list)
 	InitializeSRWLock(&list->mutex);
 }
 
+static struct vk_obj_node *obj_walk_begin(struct vk_obj_list *list)
+{
+	AcquireSRWLockExclusive(&list->mutex);
+	return list->root;
+}
+
+static struct vk_obj_node *obj_walk_next(struct vk_obj_node *node)
+{
+	return node->next;
+}
+
+static void obj_walk_end(struct vk_obj_list *list)
+{
+	ReleaseSRWLockExclusive(&list->mutex);
+}
+
 /* ------------------------------------------------------------------------- */
 
 static struct vk_obj_list devices;
@@ -256,6 +267,9 @@ static struct vk_queue_data *add_queue_data(struct vk_data *data, VkQueue queue,
 	add_obj_data(&data->queues, (uint64_t)queue, queue_data);
 	queue_data->fam_idx = fam_idx;
 	queue_data->supports_transfer = supports_transfer;
+	queue_data->frames = NULL;
+	queue_data->frame_index = 0;
+	queue_data->frame_count = 0;
 	return queue_data;
 }
 
@@ -283,6 +297,22 @@ static void remove_free_queue_all(struct vk_data *data,
 	}
 }
 
+static struct vk_queue_data *queue_walk_begin(struct vk_data *data)
+{
+	return (struct vk_queue_data *)obj_walk_begin(&data->queues);
+}
+
+static struct vk_queue_data *queue_walk_next(struct vk_queue_data *queue_data)
+{
+	return (struct vk_queue_data *)obj_walk_next(
+		(struct vk_obj_node *)queue_data);
+}
+
+static void queue_walk_end(struct vk_data *data)
+{
+	obj_walk_end(&data->queues);
+}
+
 /* ------------------------------------------------------------------------- */
 
 static struct vk_swap_data *alloc_swap_data(const VkAllocationCallbacks *ac)
@@ -314,6 +344,22 @@ static void remove_free_swap_data(struct vk_data *data, VkSwapchainKHR sc,
 	vk_free(ac, swap_data);
 }
 
+static struct vk_swap_data *swap_walk_begin(struct vk_data *data)
+{
+	return (struct vk_swap_data *)obj_walk_begin(&data->swaps);
+}
+
+static struct vk_swap_data *swap_walk_next(struct vk_swap_data *swap_data)
+{
+	return (struct vk_swap_data *)obj_walk_next(
+		(struct vk_obj_node *)swap_data);
+}
+
+static void swap_walk_end(struct vk_data *data)
+{
+	obj_walk_end(&data->swaps);
+}
+
 /* ------------------------------------------------------------------------- */
 
 static void vk_shtex_clear_fence(const struct vk_data *data,
@@ -330,12 +376,12 @@ static void vk_shtex_clear_fence(const struct vk_data *data,
 }
 
 static void vk_shtex_wait_until_pool_idle(struct vk_data *data,
-					  struct vk_family_data *family_data)
+					  struct vk_queue_data *queue_data)
 {
-	for (uint32_t frame_idx = 0; frame_idx < family_data->frame_count;
+	for (uint32_t frame_idx = 0; frame_idx < queue_data->frame_count;
 	     frame_idx++) {
 		struct vk_frame_data *frame_data =
-			&family_data->frames[frame_idx];
+			&queue_data->frames[frame_idx];
 		if (frame_data->cmd_pool != VK_NULL_HANDLE)
 			vk_shtex_clear_fence(data, frame_data);
 	}
@@ -343,10 +389,15 @@ static void vk_shtex_wait_until_pool_idle(struct vk_data *data,
 
 static void vk_shtex_wait_until_idle(struct vk_data *data)
 {
-	for (uint32_t fam_idx = 0; fam_idx < data->family_capacity; fam_idx++) {
-		struct vk_family_data *family_data = &data->families[fam_idx];
-		vk_shtex_wait_until_pool_idle(data, family_data);
+	struct vk_queue_data *queue_data = queue_walk_begin(data);
+
+	while (queue_data) {
+		vk_shtex_wait_until_pool_idle(data, queue_data);
+
+		queue_data = queue_walk_next(queue_data);
 	}
+
+	queue_walk_end(data);
 }
 
 static void vk_shtex_free(struct vk_data *data)
@@ -355,9 +406,8 @@ static void vk_shtex_free(struct vk_data *data)
 
 	vk_shtex_wait_until_idle(data);
 
-	AcquireSRWLockExclusive(&data->swaps.mutex);
+	struct vk_swap_data *swap = swap_walk_begin(data);
 
-	struct vk_swap_data *swap = (struct vk_swap_data *)data->swaps.root;
 	while (swap) {
 		VkDevice device = data->device;
 		if (swap->export_image)
@@ -378,10 +428,10 @@ static void vk_shtex_free(struct vk_data *data)
 
 		swap->captured = false;
 
-		swap = (struct vk_swap_data *)swap->node.next;
+		swap = swap_walk_next(swap);
 	}
 
-	ReleaseSRWLockExclusive(&data->swaps.mutex);
+	swap_walk_end(data);
 
 	if (data->d3d11_context) {
 		ID3D11DeviceContext_Release(data->d3d11_context);
@@ -833,31 +883,30 @@ static bool vk_shtex_init(struct vk_data *data, HWND window,
 	return true;
 }
 
-static void vk_shtex_create_family_objects(struct vk_data *data,
-					   uint32_t fam_idx,
-					   uint32_t image_count)
+static void vk_shtex_create_frame_objects(struct vk_data *data,
+					  struct vk_queue_data *queue_data,
+					  uint32_t image_count)
 {
-	struct vk_family_data *family_data = &data->families[fam_idx];
-	family_data->frames =
+	queue_data->frames =
 		vk_alloc(data->ac, image_count * sizeof(struct vk_frame_data),
 			 _Alignof(struct vk_frame_data),
 			 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-	memset(family_data->frames, 0,
+	memset(queue_data->frames, 0,
 	       image_count * sizeof(struct vk_frame_data));
-	family_data->frame_index = 0;
-	family_data->frame_count = image_count;
+	queue_data->frame_index = 0;
+	queue_data->frame_count = image_count;
 
 	VkDevice device = data->device;
 	for (uint32_t image_index = 0; image_index < image_count;
 	     image_index++) {
 		struct vk_frame_data *frame_data =
-			&family_data->frames[image_index];
+			&queue_data->frames[image_index];
 
 		VkCommandPoolCreateInfo cpci;
 		cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
 		cpci.pNext = NULL;
 		cpci.flags = 0;
-		cpci.queueFamilyIndex = fam_idx;
+		cpci.queueFamilyIndex = queue_data->fam_idx;
 
 		VkResult res = data->funcs.CreateCommandPool(
 			device, &cpci, data->ac, &frame_data->cmd_pool);
@@ -899,15 +948,15 @@ static void vk_shtex_destroy_fence(struct vk_data *data, bool *cmd_buffer_busy,
 	*fence = VK_NULL_HANDLE;
 }
 
-static void vk_shtex_destroy_family_objects(struct vk_data *data,
-					    struct vk_family_data *family_data)
+static void vk_shtex_destroy_frame_objects(struct vk_data *data,
+					   struct vk_queue_data *queue_data)
 {
 	VkDevice device = data->device;
 
-	for (uint32_t frame_idx = 0; frame_idx < family_data->frame_count;
+	for (uint32_t frame_idx = 0; frame_idx < queue_data->frame_count;
 	     frame_idx++) {
 		struct vk_frame_data *frame_data =
-			&family_data->frames[frame_idx];
+			&queue_data->frames[frame_idx];
 		bool *cmd_buffer_busy = &frame_data->cmd_buffer_busy;
 		VkFence *fence = &frame_data->fence;
 		vk_shtex_destroy_fence(data, cmd_buffer_busy, fence);
@@ -917,9 +966,9 @@ static void vk_shtex_destroy_family_objects(struct vk_data *data,
 		frame_data->cmd_pool = VK_NULL_HANDLE;
 	}
 
-	vk_free(data->ac, family_data->frames);
-	family_data->frames = NULL;
-	family_data->frame_count = 0;
+	vk_free(data->ac, queue_data->frames);
+	queue_data->frames = NULL;
+	queue_data->frame_count = 0;
 }
 
 static void vk_shtex_capture(struct vk_data *data,
@@ -948,17 +997,16 @@ static void vk_shtex_capture(struct vk_data *data,
 	struct vk_queue_data *queue_data = get_queue_data(data, queue);
 	uint32_t fam_idx = queue_data->fam_idx;
 
-	struct vk_family_data *family_data = &data->families[fam_idx];
 	const uint32_t image_count = swap->image_count;
-	if (family_data->frame_count < image_count) {
-		if (family_data->frame_count > 0)
-			vk_shtex_destroy_family_objects(data, family_data);
-		vk_shtex_create_family_objects(data, fam_idx, image_count);
+	if (queue_data->frame_count < image_count) {
+		if (queue_data->frame_count > 0)
+			vk_shtex_destroy_frame_objects(data, queue_data);
+		vk_shtex_create_frame_objects(data, queue_data, image_count);
 	}
 
-	const uint32_t frame_index = family_data->frame_index;
-	struct vk_frame_data *frame_data = &family_data->frames[frame_index];
-	family_data->frame_index = (frame_index + 1) % family_data->frame_count;
+	const uint32_t frame_index = queue_data->frame_index;
+	struct vk_frame_data *frame_data = &queue_data->frames[frame_index];
+	queue_data->frame_index = (frame_index + 1) % queue_data->frame_count;
 	vk_shtex_clear_fence(data, frame_data);
 
 	VkDevice device = data->device;
@@ -1538,17 +1586,6 @@ static VkResult VKAPI_CALL OBS_CreateDevice(VkPhysicalDevice phy_device,
 		data->ac = &data->ac_storage;
 	}
 
-	uint32_t totol_queue_count = 0;
-	uint32_t family_capacity = 1;
-	for (uint32_t i = 0, count = info->queueCreateInfoCount; i < count;
-	     ++i) {
-		const VkDeviceQueueCreateInfo *queue_info =
-			&info->pQueueCreateInfos[i];
-		totol_queue_count += queue_info->queueCount;
-		family_capacity =
-			max(family_capacity, queue_info->queueFamilyIndex + 1);
-	}
-
 	uint32_t queue_family_property_count = 0;
 	ifuncs->GetPhysicalDeviceQueueFamilyProperties(
 		phy_device, &queue_family_property_count, NULL);
@@ -1582,14 +1619,6 @@ static VkResult VKAPI_CALL OBS_CreateDevice(VkPhysicalDevice phy_device,
 
 	_freea(queue_family_properties);
 
-	data->families =
-		vk_alloc(ac, family_capacity * sizeof(struct vk_family_data),
-			 _Alignof(struct vk_family_data),
-			 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
-	memset(data->families, 0,
-	       family_capacity * sizeof(struct vk_family_data));
-	data->family_capacity = family_capacity;
-
 	init_obj_list(&data->swaps);
 
 	data->valid = true;
@@ -1604,18 +1633,17 @@ static void VKAPI_CALL OBS_DestroyDevice(VkDevice device,
 	struct vk_data *data = remove_device_data(device);
 
 	if (data->valid) {
-		for (uint32_t fam_idx = 0; fam_idx < data->family_capacity;
-		     fam_idx++) {
-			struct vk_family_data *family_data =
-				&data->families[fam_idx];
-			vk_shtex_destroy_family_objects(data, family_data);
+		struct vk_queue_data *queue_data = queue_walk_begin(data);
+
+		while (queue_data) {
+			vk_shtex_destroy_frame_objects(data, queue_data);
+
+			queue_data = queue_walk_next(queue_data);
 		}
 
-		remove_free_queue_all(data, ac);
+		queue_walk_end(data);
 
-		vk_free(ac, data->families);
-		data->families = NULL;
-		data->family_capacity = 0;
+		remove_free_queue_all(data, ac);
 	}
 
 	PFN_vkDestroyDevice destroy_device = data->funcs.DestroyDevice;