*/
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),
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");
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),
{
bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE;
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."
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++) {
/**
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,
/* 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
}
}
+ /* Restore conditional rendering. */
+ cmd_buffer->state.predicating = old_predicating;
+
radv_meta_restore(&saved_state, cmd_buffer);
}
const VkBufferImageCopy* pRegions)
{
struct radv_meta_saved_state saved_state;
+ bool old_predicating;
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++) {
/**
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,
}
}
+ /* Restore conditional rendering. */
+ cmd_buffer->state.predicating = old_predicating;
+
radv_meta_restore(&saved_state, cmd_buffer);
}
{
bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE;
struct radv_meta_saved_state saved_state;
+ bool old_predicating;
/* From the Vulkan 1.0 spec:
*
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 ==
pRegions[r].dstSubresource.aspectMask);
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
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 = {
.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;
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++;
}
}
+ /* Restore conditional rendering. */
+ cmd_buffer->state.predicating = old_predicating;
+
radv_meta_restore(&saved_state, cmd_buffer);
}
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, VK_IMAGE_LAYOUT_GENERAL, linear_image,
- VK_IMAGE_LAYOUT_GENERAL,
- 1, &image_copy);
-}