radv: cleanup selecting the hardware resolve path

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>
This commit is contained in:
Samuel Pitoiset
2020-09-22 11:24:22 +02:00
committed by Marge Bot
parent fe819710ad
commit 9a700af65c

View File

@@ -420,66 +420,16 @@ fail:
return result; return result;
} }
void radv_CmdResolveImage( static void
VkCommandBuffer cmd_buffer_h, radv_meta_resolve_hardware_image(struct radv_cmd_buffer *cmd_buffer,
VkImage src_image_h, struct radv_image *src_image,
VkImageLayout src_image_layout, VkImageLayout src_image_layout,
VkImage dest_image_h, struct radv_image *dst_image,
VkImageLayout dest_image_layout, VkImageLayout dst_image_layout,
uint32_t region_count, const VkImageResolve *region)
const VkImageResolve* regions)
{ {
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_device *device = cmd_buffer->device;
struct radv_meta_saved_state saved_state; 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) {
if (regions[0].srcOffset.x ||
regions[0].srcOffset.y ||
regions[0].srcOffset.z)
resolve_method = RESOLVE_COMPUTE;
if (regions[0].dstOffset.x ||
regions[0].dstOffset.y ||
regions[0].dstOffset.z)
resolve_method = RESOLVE_COMPUTE;
if (regions[0].extent.width != src_image->info.width ||
regions[0].extent.height != src_image->info.height ||
regions[0].extent.depth != src_image->info.depth)
resolve_method = RESOLVE_COMPUTE;
} else
resolve_method = RESOLVE_COMPUTE;
radv_pick_resolve_method_images(cmd_buffer->device, src_image,
src_image->vk_format, dest_image,
dest_image_layout, false, cmd_buffer,
&resolve_method);
if (resolve_method == 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) {
radv_meta_resolve_compute_image(cmd_buffer,
src_image,
src_image->vk_format,
src_image_layout,
dest_image,
dest_image->vk_format,
dest_image_layout,
region_count, regions);
return;
}
radv_meta_save(&saved_state, cmd_buffer, radv_meta_save(&saved_state, cmd_buffer,
RADV_META_SAVE_GRAPHICS_PIPELINE); RADV_META_SAVE_GRAPHICS_PIPELINE);
@@ -490,14 +440,12 @@ void radv_CmdResolveImage(
fprintf(stderr, "radv: Illegal resolve operation (src not multisampled), will hang GPU."); fprintf(stderr, "radv: Illegal resolve operation (src not multisampled), will hang GPU.");
return; return;
} }
assert(dest_image->info.samples == 1); assert(dst_image->info.samples == 1);
if (src_image->info.array_size > 1) if (src_image->info.array_size > 1)
radv_finishme("vkCmdResolveImage: multisample array images"); radv_finishme("vkCmdResolveImage: multisample array images");
unsigned fs_key = radv_format_meta_fs_key(dest_image->vk_format); unsigned fs_key = radv_format_meta_fs_key(dst_image->vk_format);
for (uint32_t r = 0; r < region_count; ++r) {
const VkImageResolve *region = &regions[r];
/* From the Vulkan 1.0 spec: /* From the Vulkan 1.0 spec:
* *
@@ -516,8 +464,8 @@ void radv_CmdResolveImage(
radv_meta_get_iview_layer(src_image, &region->srcSubresource, radv_meta_get_iview_layer(src_image, &region->srcSubresource,
&region->srcOffset); &region->srcOffset);
const uint32_t dest_base_layer = const uint32_t dst_base_layer =
radv_meta_get_iview_layer(dest_image, &region->dstSubresource, radv_meta_get_iview_layer(dst_image, &region->dstSubresource,
&region->dstOffset); &region->dstOffset);
/** /**
@@ -536,18 +484,18 @@ void radv_CmdResolveImage(
const struct VkExtent3D extent = const struct VkExtent3D extent =
radv_sanitize_image_extent(src_image->type, region->extent); radv_sanitize_image_extent(src_image->type, region->extent);
const struct VkOffset3D dstOffset = const struct VkOffset3D dstOffset =
radv_sanitize_image_offset(dest_image->type, region->dstOffset); radv_sanitize_image_offset(dst_image->type, region->dstOffset);
if (radv_dcc_enabled(dest_image, region->dstSubresource.mipLevel)) { if (radv_dcc_enabled(dst_image, region->dstSubresource.mipLevel)) {
VkImageSubresourceRange range = { VkImageSubresourceRange range = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = region->dstSubresource.mipLevel, .baseMipLevel = region->dstSubresource.mipLevel,
.levelCount = 1, .levelCount = 1,
.baseArrayLayer = dest_base_layer, .baseArrayLayer = dst_base_layer,
.layerCount = region->dstSubresource.layerCount, .layerCount = region->dstSubresource.layerCount,
}; };
radv_initialize_dcc(cmd_buffer, dest_image, &range, 0xffffffff); radv_initialize_dcc(cmd_buffer, dst_image, &range, 0xffffffff);
} }
for (uint32_t layer = 0; layer < region->srcSubresource.layerCount; for (uint32_t layer = 0; layer < region->srcSubresource.layerCount;
@@ -563,7 +511,7 @@ void radv_CmdResolveImage(
radv_image_view_init(&src_iview, cmd_buffer->device, radv_image_view_init(&src_iview, cmd_buffer->device,
&(VkImageViewCreateInfo) { &(VkImageViewCreateInfo) {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = src_image_h, .image = radv_image_to_handle(src_image),
.viewType = radv_meta_get_view_type(src_image), .viewType = radv_meta_get_view_type(src_image),
.format = src_image->vk_format, .format = src_image->vk_format,
.subresourceRange = { .subresourceRange = {
@@ -575,34 +523,34 @@ void radv_CmdResolveImage(
}, },
}, NULL); }, NULL);
struct radv_image_view dest_iview; struct radv_image_view dst_iview;
radv_image_view_init(&dest_iview, cmd_buffer->device, radv_image_view_init(&dst_iview, cmd_buffer->device,
&(VkImageViewCreateInfo) { &(VkImageViewCreateInfo) {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = dest_image_h, .image = radv_image_to_handle(dst_image),
.viewType = radv_meta_get_view_type(dest_image), .viewType = radv_meta_get_view_type(dst_image),
.format = dest_image->vk_format, .format = dst_image->vk_format,
.subresourceRange = { .subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = region->dstSubresource.mipLevel, .baseMipLevel = region->dstSubresource.mipLevel,
.levelCount = 1, .levelCount = 1,
.baseArrayLayer = dest_base_layer + layer, .baseArrayLayer = dst_base_layer + layer,
.layerCount = 1, .layerCount = 1,
}, },
}, NULL); }, NULL);
VkFramebuffer fb_h; VkFramebuffer fb_h;
radv_CreateFramebuffer(device_h, radv_CreateFramebuffer(radv_device_to_handle(device),
&(VkFramebufferCreateInfo) { &(VkFramebufferCreateInfo) {
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.attachmentCount = 2, .attachmentCount = 2,
.pAttachments = (VkImageView[]) { .pAttachments = (VkImageView[]) {
radv_image_view_to_handle(&src_iview), radv_image_view_to_handle(&src_iview),
radv_image_view_to_handle(&dest_iview), radv_image_view_to_handle(&dst_iview),
}, },
.width = radv_minify(dest_image->info.width, .width = radv_minify(dst_image->info.width,
region->dstSubresource.mipLevel), region->dstSubresource.mipLevel),
.height = radv_minify(dest_image->info.height, .height = radv_minify(dst_image->info.height,
region->dstSubresource.mipLevel), region->dstSubresource.mipLevel),
.layers = 1 .layers = 1
}, },
@@ -632,7 +580,7 @@ void radv_CmdResolveImage(
&cmd_buffer->state.pass->subpasses[0]); &cmd_buffer->state.pass->subpasses[0]);
emit_resolve(cmd_buffer, emit_resolve(cmd_buffer,
dest_iview.vk_format, dst_iview.vk_format,
&(VkOffset2D) { &(VkOffset2D) {
.x = dstOffset.x, .x = dstOffset.x,
.y = dstOffset.y, .y = dstOffset.y,
@@ -644,14 +592,82 @@ void radv_CmdResolveImage(
radv_cmd_buffer_end_render_pass(cmd_buffer); radv_cmd_buffer_end_render_pass(cmd_buffer);
radv_DestroyFramebuffer(device_h, fb_h, radv_DestroyFramebuffer(radv_device_to_handle(device),
&cmd_buffer->pool->alloc); fb_h, &cmd_buffer->pool->alloc);
}
} }
radv_meta_restore(&saved_state, cmd_buffer); radv_meta_restore(&saved_state, cmd_buffer);
} }
void radv_CmdResolveImage(
VkCommandBuffer cmd_buffer_h,
VkImage src_image_h,
VkImageLayout src_image_layout,
VkImage dest_image_h,
VkImageLayout dest_image_layout,
uint32_t region_count,
const VkImageResolve* regions)
{
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);
enum radv_resolve_method resolve_method = RESOLVE_HW;
/* we can use the hw resolve only for single full resolves */
if (region_count == 1) {
if (regions[0].srcOffset.x ||
regions[0].srcOffset.y ||
regions[0].srcOffset.z)
resolve_method = RESOLVE_COMPUTE;
if (regions[0].dstOffset.x ||
regions[0].dstOffset.y ||
regions[0].dstOffset.z)
resolve_method = RESOLVE_COMPUTE;
if (regions[0].extent.width != src_image->info.width ||
regions[0].extent.height != src_image->info.height ||
regions[0].extent.depth != src_image->info.depth)
resolve_method = RESOLVE_COMPUTE;
} else
resolve_method = RESOLVE_COMPUTE;
radv_pick_resolve_method_images(cmd_buffer->device, src_image,
src_image->vk_format, dest_image,
dest_image_layout, false, cmd_buffer,
&resolve_method);
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);
break;
case RESOLVE_COMPUTE:
radv_meta_resolve_compute_image(cmd_buffer,
src_image,
src_image->vk_format,
src_image_layout,
dest_image,
dest_image->vk_format,
dest_image_layout,
region_count, regions);
break;
default:
assert(!"Invalid resolve method selected");
}
}
/** /**
* Emit any needed resolves for the current subpass. * Emit any needed resolves for the current subpass.
*/ */