radv: cleanup selecting the hardware resolve path
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Tue, 22 Sep 2020 09:24:22 +0000 (11:24 +0200)
committerMarge Bot <eric+marge@anholt.net>
Wed, 23 Sep 2020 07:14:15 +0000 (07:14 +0000)
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6813>

src/amd/vulkan/radv_meta_resolve.c

index 0a03e62..9d5a306 100644 (file)
@@ -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);
 }
 
 /**