X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_meta_copy.c;h=ddfb5c54673c8cdc08f4ae2d6fcd814b6c2e40c6;hb=5c0cff868a48202df1ddb30d1dca848101063cb6;hp=f3e41ff05692feeaa06881d1bdcd8a0dc4fcad7e;hpb=8860b39d9432216dd40b825fc5750d3601b6cf4e;p=mesa.git diff --git a/src/amd/vulkan/radv_meta_copy.c b/src/amd/vulkan/radv_meta_copy.c index f3e41ff0569..ddfb5c54673 100644 --- a/src/amd/vulkan/radv_meta_copy.c +++ b/src/amd/vulkan/radv_meta_copy.c @@ -37,10 +37,11 @@ meta_image_block_size(const struct radv_image *image) */ static struct VkExtent3D meta_region_extent_el(const struct radv_image *image, + const VkImageType imageType, const struct VkExtent3D *extent) { const VkExtent3D block = meta_image_block_size(image); - return radv_sanitize_image_extent(image->type, (VkExtent3D) { + return radv_sanitize_image_extent(imageType, (VkExtent3D) { .width = DIV_ROUND_UP(extent->width , block.width), .height = DIV_ROUND_UP(extent->height, block.height), .depth = DIV_ROUND_UP(extent->depth , block.depth), @@ -71,6 +72,7 @@ vk_format_for_size(int bs) case 2: return VK_FORMAT_R8G8_UINT; case 4: return VK_FORMAT_R8G8B8A8_UINT; case 8: return VK_FORMAT_R16G16B16A16_UINT; + case 12: return VK_FORMAT_R32G32B32_UINT; case 16: return VK_FORMAT_R32G32B32A32_UINT; default: unreachable("Invalid format block size"); @@ -79,6 +81,7 @@ vk_format_for_size(int bs) static struct radv_meta_blit2d_surf blit_surf_for_image_level_layer(struct radv_image *image, + VkImageLayout layout, const VkImageSubresourceLayers *subres) { VkFormat format = image->vk_format; @@ -87,9 +90,12 @@ blit_surf_for_image_level_layer(struct radv_image *image, else if (subres->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) format = vk_format_stencil_only(format); - if (!image->surface.dcc_size) + if (!radv_image_has_dcc(image) && + !(radv_image_is_tc_compat_htile(image))) format = vk_format_for_size(vk_format_get_blocksize(format)); + format = vk_format_no_srgb(format); + return (struct radv_meta_blit2d_surf) { .format = format, .bs = vk_format_get_blocksize(format), @@ -97,33 +103,38 @@ blit_surf_for_image_level_layer(struct radv_image *image, .layer = subres->baseArrayLayer, .image = image, .aspect_mask = subres->aspectMask, + .current_layout = layout, }; } -union meta_saved_state { - struct radv_meta_saved_state gfx; - struct radv_meta_saved_compute_state compute; -}; - static void meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, struct radv_buffer* buffer, struct radv_image* image, + VkImageLayout layout, uint32_t regionCount, const VkBufferImageCopy* pRegions) { bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE; - union meta_saved_state saved_state; + struct radv_meta_saved_state saved_state; + bool old_predicating; /* The Vulkan 1.0 spec says "dstImage must have a sample count equal to * VK_SAMPLE_COUNT_1_BIT." */ assert(image->info.samples == 1); - if (cs) - radv_meta_save_compute(&saved_state.compute, cmd_buffer, 12); - else - radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state.gfx, cmd_buffer); + radv_meta_save(&saved_state, cmd_buffer, + (cs ? RADV_META_SAVE_COMPUTE_PIPELINE : + RADV_META_SAVE_GRAPHICS_PIPELINE) | + RADV_META_SAVE_CONSTANTS | + RADV_META_SAVE_DESCRIPTORS); + + /* VK_EXT_conditional_rendering says that copy commands should not be + * affected by conditional rendering. + */ + old_predicating = cmd_buffer->state.predicating; + cmd_buffer->state.predicating = false; for (unsigned r = 0; r < regionCount; r++) { @@ -146,11 +157,11 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, pRegions[r].bufferImageHeight : pRegions[r].imageExtent.height, }; const VkExtent3D buf_extent_el = - meta_region_extent_el(image, &bufferExtent); + meta_region_extent_el(image, image->type, &bufferExtent); /* Start creating blit rect */ const VkExtent3D img_extent_el = - meta_region_extent_el(image, &pRegions[r].imageExtent); + meta_region_extent_el(image, image->type, &pRegions[r].imageExtent); struct radv_meta_blit2d_rect rect = { .width = img_extent_el.width, .height = img_extent_el.height, @@ -159,6 +170,7 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, /* Create blit surfaces */ struct radv_meta_blit2d_surf img_bsurf = blit_surf_for_image_level_layer(image, + layout, &pRegions[r].imageSubresource); struct radv_meta_blit2d_buffer buf_bsurf = { @@ -183,10 +195,14 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, /* Perform Blit */ - if (cs) + if (cs || + (img_bsurf.image->vk_format == VK_FORMAT_R32G32B32_UINT || + img_bsurf.image->vk_format == VK_FORMAT_R32G32B32_SINT || + img_bsurf.image->vk_format == VK_FORMAT_R32G32B32_SFLOAT)) { radv_meta_buffer_to_image_cs(cmd_buffer, &buf_bsurf, &img_bsurf, 1, &rect); - else + } else { radv_meta_blit2d(cmd_buffer, NULL, &buf_bsurf, &img_bsurf, 1, &rect); + } /* Once we've done the blit, all of the actual information about * the image is embedded in the command buffer so we can just @@ -202,10 +218,11 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, slice_array++; } } - if (cs) - radv_meta_restore_compute(&saved_state.compute, cmd_buffer); - else - radv_meta_restore(&saved_state.gfx, cmd_buffer); + + /* Restore conditional rendering. */ + cmd_buffer->state.predicating = old_predicating; + + radv_meta_restore(&saved_state, cmd_buffer); } void radv_CmdCopyBufferToImage( @@ -220,7 +237,7 @@ void radv_CmdCopyBufferToImage( RADV_FROM_HANDLE(radv_image, dest_image, destImage); RADV_FROM_HANDLE(radv_buffer, src_buffer, srcBuffer); - meta_copy_buffer_to_image(cmd_buffer, src_buffer, dest_image, + meta_copy_buffer_to_image(cmd_buffer, src_buffer, dest_image, destImageLayout, regionCount, pRegions); } @@ -228,12 +245,23 @@ static void meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer, struct radv_buffer* buffer, struct radv_image* image, + VkImageLayout layout, uint32_t regionCount, const VkBufferImageCopy* pRegions) { - struct radv_meta_saved_compute_state saved_state; + struct radv_meta_saved_state saved_state; + bool old_predicating; - radv_meta_save_compute(&saved_state, cmd_buffer, 12); + radv_meta_save(&saved_state, cmd_buffer, + RADV_META_SAVE_COMPUTE_PIPELINE | + RADV_META_SAVE_CONSTANTS | + RADV_META_SAVE_DESCRIPTORS); + + /* VK_EXT_conditional_rendering says that copy commands should not be + * affected by conditional rendering. + */ + old_predicating = cmd_buffer->state.predicating; + cmd_buffer->state.predicating = false; for (unsigned r = 0; r < regionCount; r++) { @@ -256,11 +284,11 @@ meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer, pRegions[r].bufferImageHeight : pRegions[r].imageExtent.height, }; const VkExtent3D buf_extent_el = - meta_region_extent_el(image, &bufferExtent); + meta_region_extent_el(image, image->type, &bufferExtent); /* Start creating blit rect */ const VkExtent3D img_extent_el = - meta_region_extent_el(image, &pRegions[r].imageExtent); + meta_region_extent_el(image, image->type, &pRegions[r].imageExtent); struct radv_meta_blit2d_rect rect = { .width = img_extent_el.width, .height = img_extent_el.height, @@ -269,6 +297,7 @@ meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer, /* Create blit surfaces */ struct radv_meta_blit2d_surf img_info = blit_surf_for_image_level_layer(image, + layout, &pRegions[r].imageSubresource); struct radv_meta_blit2d_buffer buf_info = { @@ -304,7 +333,11 @@ meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer, slice_array++; } } - radv_meta_restore_compute(&saved_state, cmd_buffer); + + /* Restore conditional rendering. */ + cmd_buffer->state.predicating = old_predicating; + + radv_meta_restore(&saved_state, cmd_buffer); } void radv_CmdCopyImageToBuffer( @@ -320,18 +353,22 @@ void radv_CmdCopyImageToBuffer( RADV_FROM_HANDLE(radv_buffer, dst_buffer, destBuffer); meta_copy_image_to_buffer(cmd_buffer, dst_buffer, src_image, + srcImageLayout, regionCount, pRegions); } static void meta_copy_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image, + VkImageLayout src_image_layout, struct radv_image *dest_image, + VkImageLayout dest_image_layout, uint32_t regionCount, const VkImageCopy *pRegions) { bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE; - union meta_saved_state saved_state; + struct radv_meta_saved_state saved_state; + bool old_predicating; /* From the Vulkan 1.0 spec: * @@ -339,10 +376,18 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, * images, but both images must have the same number of samples. */ assert(src_image->info.samples == dest_image->info.samples); - if (cs) - radv_meta_save_compute(&saved_state.compute, cmd_buffer, 16); - else - radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state.gfx, cmd_buffer); + + radv_meta_save(&saved_state, cmd_buffer, + (cs ? RADV_META_SAVE_COMPUTE_PIPELINE : + RADV_META_SAVE_GRAPHICS_PIPELINE) | + RADV_META_SAVE_CONSTANTS | + RADV_META_SAVE_DESCRIPTORS); + + /* VK_EXT_conditional_rendering says that copy commands should not be + * affected by conditional rendering. + */ + old_predicating = cmd_buffer->state.predicating; + cmd_buffer->state.predicating = false; for (unsigned r = 0; r < regionCount; r++) { assert(pRegions[r].srcSubresource.aspectMask == @@ -351,14 +396,39 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, /* Create blit surfaces */ struct radv_meta_blit2d_surf b_src = blit_surf_for_image_level_layer(src_image, + src_image_layout, &pRegions[r].srcSubresource); struct radv_meta_blit2d_surf b_dst = blit_surf_for_image_level_layer(dest_image, + dest_image_layout, &pRegions[r].dstSubresource); - /* for DCC */ - b_src.format = b_dst.format; + uint32_t dst_queue_mask = radv_image_queue_family_mask(dest_image, + cmd_buffer->queue_family_index, + cmd_buffer->queue_family_index); + bool dst_compressed = radv_layout_dcc_compressed(dest_image, dest_image_layout, dst_queue_mask); + uint32_t src_queue_mask = radv_image_queue_family_mask(src_image, + cmd_buffer->queue_family_index, + cmd_buffer->queue_family_index); + bool src_compressed = radv_layout_dcc_compressed(src_image, src_image_layout, src_queue_mask); + + if (!src_compressed || radv_dcc_formats_compatible(b_src.format, b_dst.format)) { + b_src.format = b_dst.format; + } else if (!dst_compressed) { + b_dst.format = b_src.format; + } else { + radv_decompress_dcc(cmd_buffer, dest_image, &(VkImageSubresourceRange) { + .aspectMask = pRegions[r].dstSubresource.aspectMask, + .baseMipLevel = pRegions[r].dstSubresource.mipLevel, + .levelCount = 1, + .baseArrayLayer = pRegions[r].dstSubresource.baseArrayLayer, + .layerCount = pRegions[r].dstSubresource.layerCount, + }); + b_dst.format = b_src.format; + b_dst.current_layout = VK_IMAGE_LAYOUT_GENERAL; + } + /** * From the Vulkan 1.0.6 spec: 18.4 Copying Data Between Buffers and Images @@ -373,8 +443,18 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, meta_region_offset_el(dest_image, &pRegions[r].dstOffset); const VkOffset3D src_offset_el = meta_region_offset_el(src_image, &pRegions[r].srcOffset); + + /* + * From Vulkan 1.0.68, "Copying Data Between Images": + * "When copying between compressed and uncompressed formats + * the extent members represent the texel dimensions of the + * source image and not the destination." + * However, we must use the destination image type to avoid + * clamping depth when copying multiple layers of a 2D image to + * a 3D image. + */ const VkExtent3D img_extent_el = - meta_region_extent_el(dest_image, &pRegions[r].extent); + meta_region_extent_el(src_image, dest_image->type, &pRegions[r].extent); /* Start creating blit rect */ struct radv_meta_blit2d_rect rect = { @@ -382,6 +462,9 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, .height = img_extent_el.height, }; + if (src_image->type == VK_IMAGE_TYPE_3D) + b_src.layer = src_offset_el.z; + if (dest_image->type == VK_IMAGE_TYPE_3D) b_dst.layer = dst_offset_el.z; @@ -399,10 +482,14 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, rect.src_y = src_offset_el.y; /* Perform Blit */ - if (cs) + if (cs || + (b_src.format == VK_FORMAT_R32G32B32_UINT || + b_src.format == VK_FORMAT_R32G32B32_SINT || + b_src.format == VK_FORMAT_R32G32B32_SFLOAT)) { radv_meta_image_to_image_cs(cmd_buffer, &b_src, &b_dst, 1, &rect); - else + } else { radv_meta_blit2d(cmd_buffer, &b_src, NULL, &b_dst, 1, &rect); + } b_src.layer++; b_dst.layer++; @@ -413,10 +500,10 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, } } - if (cs) - radv_meta_restore_compute(&saved_state.compute, cmd_buffer); - else - radv_meta_restore(&saved_state.gfx, cmd_buffer); + /* Restore conditional rendering. */ + cmd_buffer->state.predicating = old_predicating; + + radv_meta_restore(&saved_state, cmd_buffer); } void radv_CmdCopyImage( @@ -432,26 +519,8 @@ void radv_CmdCopyImage( RADV_FROM_HANDLE(radv_image, src_image, srcImage); RADV_FROM_HANDLE(radv_image, dest_image, destImage); - meta_copy_image(cmd_buffer, src_image, dest_image, + meta_copy_image(cmd_buffer, + src_image, srcImageLayout, + dest_image, destImageLayout, regionCount, pRegions); } - -void radv_blit_to_prime_linear(struct radv_cmd_buffer *cmd_buffer, - struct radv_image *image, - struct radv_image *linear_image) -{ - struct VkImageCopy image_copy = { 0 }; - - image_copy.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - image_copy.srcSubresource.layerCount = 1; - - image_copy.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - image_copy.dstSubresource.layerCount = 1; - - image_copy.extent.width = image->info.width; - image_copy.extent.height = image->info.height; - image_copy.extent.depth = 1; - - meta_copy_image(cmd_buffer, image, linear_image, - 1, &image_copy); -}