Mesa (master): radv: cleanup selecting the hardware resolve path

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Sep 23 07:26:03 UTC 2020


Module: Mesa
Branch: master
Commit: 9a700af65cf8d34b44dae1fbf2cef9d5a8f7d7d1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9a700af65cf8d34b44dae1fbf2cef9d5a8f7d7d1

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Tue Sep 22 11:24:22 2020 +0200

radv: cleanup selecting the hardware resolve path

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6813>

---

 src/amd/vulkan/radv_meta_resolve.c | 374 +++++++++++++++++++------------------
 1 file changed, 195 insertions(+), 179 deletions(-)

diff --git a/src/amd/vulkan/radv_meta_resolve.c b/src/amd/vulkan/radv_meta_resolve.c
index 0a03e62f9cb..9d5a306c1cc 100644
--- a/src/amd/vulkan/radv_meta_resolve.c
+++ b/src/amd/vulkan/radv_meta_resolve.c
@@ -420,6 +420,185 @@ fail:
 	return result;
 }
 
+static void
+radv_meta_resolve_hardware_image(struct radv_cmd_buffer *cmd_buffer,
+				 struct radv_image *src_image,
+				 VkImageLayout src_image_layout,
+				 struct radv_image *dst_image,
+				 VkImageLayout dst_image_layout,
+				 const VkImageResolve *region)
+{
+	struct radv_device *device = cmd_buffer->device;
+	struct radv_meta_saved_state saved_state;
+
+	radv_meta_save(&saved_state, cmd_buffer,
+		       RADV_META_SAVE_GRAPHICS_PIPELINE);
+
+	assert(src_image->info.samples > 1);
+	if (src_image->info.samples <= 1) {
+		/* this causes GPU hangs if we get past here */
+		fprintf(stderr, "radv: Illegal resolve operation (src not multisampled), will hang GPU.");
+		return;
+	}
+	assert(dst_image->info.samples == 1);
+
+	if (src_image->info.array_size > 1)
+		radv_finishme("vkCmdResolveImage: multisample array images");
+
+	unsigned fs_key = radv_format_meta_fs_key(dst_image->vk_format);
+
+	/* From the Vulkan 1.0 spec:
+	 *
+	 *    - The aspectMask member of srcSubresource and dstSubresource must
+	 *      only contain VK_IMAGE_ASPECT_COLOR_BIT
+	 *
+	 *    - The layerCount member of srcSubresource and dstSubresource must
+	 *      match
+	 */
+	assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
+	assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
+	assert(region->srcSubresource.layerCount ==
+	       region->dstSubresource.layerCount);
+
+	const uint32_t src_base_layer =
+		radv_meta_get_iview_layer(src_image, &region->srcSubresource,
+					  &region->srcOffset);
+
+	const uint32_t dst_base_layer =
+		radv_meta_get_iview_layer(dst_image, &region->dstSubresource,
+					  &region->dstOffset);
+
+	/**
+	 * From Vulkan 1.0.6 spec: 18.6 Resolving Multisample Images
+	 *
+	 *    extent is the size in texels of the source image to resolve in width,
+	 *    height and depth. 1D images use only x and width. 2D images use x, y,
+	 *    width and height. 3D images use x, y, z, width, height and depth.
+	 *
+	 *    srcOffset and dstOffset select the initial x, y, and z offsets in
+	 *    texels of the sub-regions of the source and destination image data.
+	 *    extent is the size in texels of the source image to resolve in width,
+	 *    height and depth. 1D images use only x and width. 2D images use x, y,
+	 *    width and height. 3D images use x, y, z, width, height and depth.
+	 */
+	const struct VkExtent3D extent =
+		radv_sanitize_image_extent(src_image->type, region->extent);
+	const struct VkOffset3D dstOffset =
+		radv_sanitize_image_offset(dst_image->type, region->dstOffset);
+
+	if (radv_dcc_enabled(dst_image, region->dstSubresource.mipLevel)) {
+		VkImageSubresourceRange range = {
+			.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+			.baseMipLevel = region->dstSubresource.mipLevel,
+			.levelCount = 1,
+			.baseArrayLayer = dst_base_layer,
+			.layerCount = region->dstSubresource.layerCount,
+		};
+
+		radv_initialize_dcc(cmd_buffer, dst_image, &range, 0xffffffff);
+	}
+
+	for (uint32_t layer = 0; layer < region->srcSubresource.layerCount;
+	     ++layer) {
+
+		VkResult ret = build_resolve_pipeline(device, fs_key);
+		if (ret != VK_SUCCESS) {
+			cmd_buffer->record_result = ret;
+			break;
+		}
+
+		struct radv_image_view src_iview;
+		radv_image_view_init(&src_iview, cmd_buffer->device,
+				     &(VkImageViewCreateInfo) {
+					     .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+						     .image = radv_image_to_handle(src_image),
+						     .viewType = radv_meta_get_view_type(src_image),
+						     .format = src_image->vk_format,
+						     .subresourceRange = {
+						     .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+						     .baseMipLevel = region->srcSubresource.mipLevel,
+						     .levelCount = 1,
+						     .baseArrayLayer = src_base_layer + layer,
+						     .layerCount = 1,
+					     },
+				     }, NULL);
+
+		struct radv_image_view dst_iview;
+		radv_image_view_init(&dst_iview, cmd_buffer->device,
+				     &(VkImageViewCreateInfo) {
+					     .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+						     .image = radv_image_to_handle(dst_image),
+						     .viewType = radv_meta_get_view_type(dst_image),
+						     .format = dst_image->vk_format,
+						     .subresourceRange = {
+						     .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+						     .baseMipLevel = region->dstSubresource.mipLevel,
+						     .levelCount = 1,
+						     .baseArrayLayer = dst_base_layer + layer,
+						     .layerCount = 1,
+					     },
+				      }, NULL);
+
+		VkFramebuffer fb_h;
+		radv_CreateFramebuffer(radv_device_to_handle(device),
+				       &(VkFramebufferCreateInfo) {
+					       .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+						       .attachmentCount = 2,
+						       .pAttachments = (VkImageView[]) {
+						       radv_image_view_to_handle(&src_iview),
+						       radv_image_view_to_handle(&dst_iview),
+					       },
+					       .width = radv_minify(dst_image->info.width,
+								    region->dstSubresource.mipLevel),
+					       .height = radv_minify(dst_image->info.height,
+								      region->dstSubresource.mipLevel),
+					       .layers = 1
+				       },
+				       &cmd_buffer->pool->alloc,
+				       &fb_h);
+
+		radv_cmd_buffer_begin_render_pass(cmd_buffer,
+						  &(VkRenderPassBeginInfo) {
+							.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+							.renderPass = device->meta_state.resolve.pass[fs_key],
+							.framebuffer = fb_h,
+							.renderArea = {
+								.offset = {
+									dstOffset.x,
+									dstOffset.y,
+								},
+								.extent = {
+									extent.width,
+									extent.height,
+							      }
+							},
+							.clearValueCount = 0,
+							.pClearValues = NULL,
+					      });
+
+		radv_cmd_buffer_set_subpass(cmd_buffer,
+					    &cmd_buffer->state.pass->subpasses[0]);
+
+		emit_resolve(cmd_buffer,
+			     dst_iview.vk_format,
+			     &(VkOffset2D) {
+				     .x = dstOffset.x,
+				     .y = dstOffset.y,
+			     },
+			     &(VkExtent2D) {
+				     .width = extent.width,
+				     .height = extent.height,
+			     });
+
+		radv_cmd_buffer_end_render_pass(cmd_buffer);
+
+		radv_DestroyFramebuffer(radv_device_to_handle(device),
+					fb_h, &cmd_buffer->pool->alloc);
+	}
+
+	radv_meta_restore(&saved_state, cmd_buffer);
+}
+
 void radv_CmdResolveImage(
 	VkCommandBuffer                             cmd_buffer_h,
 	VkImage                                     src_image_h,
@@ -432,9 +611,6 @@ void radv_CmdResolveImage(
 	RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, cmd_buffer_h);
 	RADV_FROM_HANDLE(radv_image, src_image, src_image_h);
 	RADV_FROM_HANDLE(radv_image, dest_image, dest_image_h);
-	struct radv_device *device = cmd_buffer->device;
-	struct radv_meta_saved_state saved_state;
-	VkDevice device_h = radv_device_to_handle(device);
 	enum radv_resolve_method resolve_method = RESOLVE_HW;
 	/* we can use the hw resolve only for single full resolves */
 	if (region_count == 1) {
@@ -459,17 +635,25 @@ void radv_CmdResolveImage(
 					dest_image_layout, false, cmd_buffer,
 					&resolve_method);
 
-	if (resolve_method == RESOLVE_FRAGMENT) {
+	switch (resolve_method) {
+	case RESOLVE_HW:
+		assert(region_count == 1);
+		radv_meta_resolve_hardware_image(cmd_buffer,
+						 src_image,
+						 src_image_layout,
+						 dest_image,
+						 dest_image_layout,
+						 &regions[0]);
+		break;
+	case RESOLVE_FRAGMENT:
 		radv_meta_resolve_fragment_image(cmd_buffer,
 						 src_image,
 						 src_image_layout,
 						 dest_image,
 						 dest_image_layout,
 						 region_count, regions);
-		return;
-	}
-
-	if (resolve_method == RESOLVE_COMPUTE) {
+		break;
+	case RESOLVE_COMPUTE:
 		radv_meta_resolve_compute_image(cmd_buffer,
 						src_image,
 						src_image->vk_format,
@@ -478,178 +662,10 @@ void radv_CmdResolveImage(
 						dest_image->vk_format,
 						dest_image_layout,
 						region_count, regions);
-		return;
+		break;
+	default:
+		assert(!"Invalid resolve method selected");
 	}
-
-	radv_meta_save(&saved_state, cmd_buffer,
-		       RADV_META_SAVE_GRAPHICS_PIPELINE);
-
-	assert(src_image->info.samples > 1);
-	if (src_image->info.samples <= 1) {
-		/* this causes GPU hangs if we get past here */
-		fprintf(stderr, "radv: Illegal resolve operation (src not multisampled), will hang GPU.");
-		return;
-	}
-	assert(dest_image->info.samples == 1);
-
-	if (src_image->info.array_size > 1)
-		radv_finishme("vkCmdResolveImage: multisample array images");
-
-	unsigned fs_key = radv_format_meta_fs_key(dest_image->vk_format);
-	for (uint32_t r = 0; r < region_count; ++r) {
-		const VkImageResolve *region = &regions[r];
-
-		/* From the Vulkan 1.0 spec:
-		 *
-		 *    - The aspectMask member of srcSubresource and dstSubresource must
-		 *      only contain VK_IMAGE_ASPECT_COLOR_BIT
-		 *
-		 *    - The layerCount member of srcSubresource and dstSubresource must
-		 *      match
-		 */
-		assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
-		assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
-		assert(region->srcSubresource.layerCount ==
-		       region->dstSubresource.layerCount);
-
-		const uint32_t src_base_layer =
-			radv_meta_get_iview_layer(src_image, &region->srcSubresource,
-						  &region->srcOffset);
-
-		const uint32_t dest_base_layer =
-			radv_meta_get_iview_layer(dest_image, &region->dstSubresource,
-						  &region->dstOffset);
-
-		/**
-		 * From Vulkan 1.0.6 spec: 18.6 Resolving Multisample Images
-		 *
-		 *    extent is the size in texels of the source image to resolve in width,
-		 *    height and depth. 1D images use only x and width. 2D images use x, y,
-		 *    width and height. 3D images use x, y, z, width, height and depth.
-		 *
-		 *    srcOffset and dstOffset select the initial x, y, and z offsets in
-		 *    texels of the sub-regions of the source and destination image data.
-		 *    extent is the size in texels of the source image to resolve in width,
-		 *    height and depth. 1D images use only x and width. 2D images use x, y,
-		 *    width and height. 3D images use x, y, z, width, height and depth.
-		 */
-		const struct VkExtent3D extent =
-			radv_sanitize_image_extent(src_image->type, region->extent);
-		const struct VkOffset3D dstOffset =
-			radv_sanitize_image_offset(dest_image->type, region->dstOffset);
-
-		if (radv_dcc_enabled(dest_image, region->dstSubresource.mipLevel)) {
-			VkImageSubresourceRange range = {
-				.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-				.baseMipLevel = region->dstSubresource.mipLevel,
-				.levelCount = 1,
-				.baseArrayLayer = dest_base_layer,
-				.layerCount = region->dstSubresource.layerCount,
-			};
-
-			radv_initialize_dcc(cmd_buffer, dest_image, &range, 0xffffffff);
-		}
-
-		for (uint32_t layer = 0; layer < region->srcSubresource.layerCount;
-		     ++layer) {
-
-			VkResult ret = build_resolve_pipeline(device, fs_key);
-			if (ret != VK_SUCCESS) {
-				cmd_buffer->record_result = ret;
-				break;
-			}
-
-			struct radv_image_view src_iview;
-			radv_image_view_init(&src_iview, cmd_buffer->device,
-					     &(VkImageViewCreateInfo) {
-						     .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-							     .image = src_image_h,
-							     .viewType = radv_meta_get_view_type(src_image),
-							     .format = src_image->vk_format,
-							     .subresourceRange = {
-							     .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-							     .baseMipLevel = region->srcSubresource.mipLevel,
-							     .levelCount = 1,
-							     .baseArrayLayer = src_base_layer + layer,
-							     .layerCount = 1,
-						     },
-					     }, NULL);
-
-			struct radv_image_view dest_iview;
-			radv_image_view_init(&dest_iview, cmd_buffer->device,
-					     &(VkImageViewCreateInfo) {
-						     .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-							     .image = dest_image_h,
-							     .viewType = radv_meta_get_view_type(dest_image),
-							     .format = dest_image->vk_format,
-							     .subresourceRange = {
-							     .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-							     .baseMipLevel = region->dstSubresource.mipLevel,
-							     .levelCount = 1,
-							     .baseArrayLayer = dest_base_layer + layer,
-							     .layerCount = 1,
-						     },
-					      }, NULL);
-
-			VkFramebuffer fb_h;
-			radv_CreateFramebuffer(device_h,
-					       &(VkFramebufferCreateInfo) {
-						       .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
-							       .attachmentCount = 2,
-							       .pAttachments = (VkImageView[]) {
-							       radv_image_view_to_handle(&src_iview),
-							       radv_image_view_to_handle(&dest_iview),
-						       },
-						       .width = radv_minify(dest_image->info.width,
-									    region->dstSubresource.mipLevel),
-						       .height = radv_minify(dest_image->info.height,
-									      region->dstSubresource.mipLevel),
-						       .layers = 1
-					       },
-					       &cmd_buffer->pool->alloc,
-					       &fb_h);
-
-			radv_cmd_buffer_begin_render_pass(cmd_buffer,
-							  &(VkRenderPassBeginInfo) {
-								.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
-								.renderPass = device->meta_state.resolve.pass[fs_key],
-								.framebuffer = fb_h,
-								.renderArea = {
-									.offset = {
-										dstOffset.x,
-										dstOffset.y,
-									},
-									.extent = {
-										extent.width,
-										extent.height,
-								      }
-								},
-								.clearValueCount = 0,
-								.pClearValues = NULL,
-						      });
-
-			radv_cmd_buffer_set_subpass(cmd_buffer,
-						    &cmd_buffer->state.pass->subpasses[0]);
-
-			emit_resolve(cmd_buffer,
-				     dest_iview.vk_format,
-				     &(VkOffset2D) {
-					     .x = dstOffset.x,
-					     .y = dstOffset.y,
-				     },
-				     &(VkExtent2D) {
-					     .width = extent.width,
-					     .height = extent.height,
-				     });
-
-			radv_cmd_buffer_end_render_pass(cmd_buffer);
-
-			radv_DestroyFramebuffer(device_h, fb_h,
-						&cmd_buffer->pool->alloc);
-		}
-	}
-
-	radv_meta_restore(&saved_state, cmd_buffer);
 }
 
 /**



More information about the mesa-commit mailing list