summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>2020-09-22 08:46:43 +0200
committerMarge Bot <eric+marge@anholt.net>2020-09-23 07:14:15 +0000
commiteccc73ff780da0380067690f81ca9db93d67b66c (patch)
tree4de482f37af570f21283bb32f083bffd8c5198d1
parentcc709a07f27c6d0ac2b8a8c98a15fb00014a8efc (diff)
radv: add support for CmdBlitImage2KHR()
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>
-rw-r--r--src/amd/vulkan/radv_meta_blit.c304
1 files changed, 175 insertions, 129 deletions
diff --git a/src/amd/vulkan/radv_meta_blit.c b/src/amd/vulkan/radv_meta_blit.c
index 71cea3b0a31..b31af3b2bfc 100644
--- a/src/amd/vulkan/radv_meta_blit.c
+++ b/src/amd/vulkan/radv_meta_blit.c
@@ -526,20 +526,17 @@ flip_coords(unsigned *src0, unsigned *src1, unsigned *dst0, unsigned *dst1)
return flip;
}
-void radv_CmdBlitImage(
- VkCommandBuffer commandBuffer,
- VkImage srcImage,
- VkImageLayout srcImageLayout,
- VkImage destImage,
- VkImageLayout destImageLayout,
- uint32_t regionCount,
- const VkImageBlit* pRegions,
- VkFilter filter)
-
+static void
+blit_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 VkImageBlit2KHR *region,
+ VkFilter filter)
{
- RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
- RADV_FROM_HANDLE(radv_image, src_image, srcImage);
- RADV_FROM_HANDLE(radv_image, dest_image, destImage);
+ const VkImageSubresourceLayers *src_res = &region->srcSubresource;
+ const VkImageSubresourceLayers *dst_res = &region->dstSubresource;
struct radv_device *device = cmd_buffer->device;
struct radv_meta_saved_state saved_state;
bool old_predicating;
@@ -551,7 +548,7 @@ void radv_CmdBlitImage(
* destination images. Use vkCmdResolveImage for this purpose.
*/
assert(src_image->info.samples == 1);
- assert(dest_image->info.samples == 1);
+ assert(dst_image->info.samples == 1);
radv_CreateSampler(radv_device_to_handle(device),
&(VkSamplerCreateInfo) {
@@ -574,126 +571,121 @@ void radv_CmdBlitImage(
old_predicating = cmd_buffer->state.predicating;
cmd_buffer->state.predicating = false;
- for (unsigned r = 0; r < regionCount; r++) {
- const VkImageSubresourceLayers *src_res = &pRegions[r].srcSubresource;
- const VkImageSubresourceLayers *dst_res = &pRegions[r].dstSubresource;
-
- unsigned dst_start, dst_end;
- if (dest_image->type == VK_IMAGE_TYPE_3D) {
- assert(dst_res->baseArrayLayer == 0);
- dst_start = pRegions[r].dstOffsets[0].z;
- dst_end = pRegions[r].dstOffsets[1].z;
- } else {
- dst_start = dst_res->baseArrayLayer;
- dst_end = dst_start + dst_res->layerCount;
- }
+ unsigned dst_start, dst_end;
+ if (dst_image->type == VK_IMAGE_TYPE_3D) {
+ assert(dst_res->baseArrayLayer == 0);
+ dst_start = region->dstOffsets[0].z;
+ dst_end = region->dstOffsets[1].z;
+ } else {
+ dst_start = dst_res->baseArrayLayer;
+ dst_end = dst_start + dst_res->layerCount;
+ }
- unsigned src_start, src_end;
- if (src_image->type == VK_IMAGE_TYPE_3D) {
- assert(src_res->baseArrayLayer == 0);
- src_start = pRegions[r].srcOffsets[0].z;
- src_end = pRegions[r].srcOffsets[1].z;
- } else {
- src_start = src_res->baseArrayLayer;
- src_end = src_start + src_res->layerCount;
- }
+ unsigned src_start, src_end;
+ if (src_image->type == VK_IMAGE_TYPE_3D) {
+ assert(src_res->baseArrayLayer == 0);
+ src_start = region->srcOffsets[0].z;
+ src_end = region->srcOffsets[1].z;
+ } else {
+ src_start = src_res->baseArrayLayer;
+ src_end = src_start + src_res->layerCount;
+ }
- bool flip_z = flip_coords(&src_start, &src_end, &dst_start, &dst_end);
- float src_z_step = (float)(src_end - src_start) /
- (float)(dst_end - dst_start);
+ bool flip_z = flip_coords(&src_start, &src_end, &dst_start, &dst_end);
+ float src_z_step = (float)(src_end - src_start) /
+ (float)(dst_end - dst_start);
- /* There is no interpolation to the pixel center during
- * rendering, so add the 0.5 offset ourselves here. */
- float depth_center_offset = 0;
- if (src_image->type == VK_IMAGE_TYPE_3D)
- depth_center_offset = 0.5 / (dst_end - dst_start) * (src_end - src_start);
+ /* There is no interpolation to the pixel center during
+ * rendering, so add the 0.5 offset ourselves here. */
+ float depth_center_offset = 0;
+ if (src_image->type == VK_IMAGE_TYPE_3D)
+ depth_center_offset = 0.5 / (dst_end - dst_start) * (src_end - src_start);
- if (flip_z) {
- src_start = src_end;
- src_z_step *= -1;
- depth_center_offset *= -1;
- }
+ if (flip_z) {
+ src_start = src_end;
+ src_z_step *= -1;
+ depth_center_offset *= -1;
+ }
- unsigned src_x0 = pRegions[r].srcOffsets[0].x;
- unsigned src_x1 = pRegions[r].srcOffsets[1].x;
- unsigned dst_x0 = pRegions[r].dstOffsets[0].x;
- unsigned dst_x1 = pRegions[r].dstOffsets[1].x;
-
- unsigned src_y0 = pRegions[r].srcOffsets[0].y;
- unsigned src_y1 = pRegions[r].srcOffsets[1].y;
- unsigned dst_y0 = pRegions[r].dstOffsets[0].y;
- unsigned dst_y1 = pRegions[r].dstOffsets[1].y;
-
- VkRect2D dest_box;
- dest_box.offset.x = MIN2(dst_x0, dst_x1);
- dest_box.offset.y = MIN2(dst_y0, dst_y1);
- dest_box.extent.width = dst_x1 - dst_x0;
- dest_box.extent.height = dst_y1 - dst_y0;
-
- const unsigned num_layers = dst_end - dst_start;
- for (unsigned i = 0; i < num_layers; i++) {
- struct radv_image_view dest_iview, src_iview;
-
- const VkOffset2D dest_offset_0 = {
- .x = dst_x0,
- .y = dst_y0,
- };
- const VkOffset2D dest_offset_1 = {
- .x = dst_x1,
- .y = dst_y1,
- };
-
- float src_offset_0[3] = {
- src_x0,
- src_y0,
- src_start + i * src_z_step + depth_center_offset,
- };
- float src_offset_1[3] = {
- src_x1,
- src_y1,
- src_start + i * src_z_step + depth_center_offset,
- };
- const uint32_t dest_array_slice = dst_start + i;
-
- /* 3D images have just 1 layer */
- const uint32_t src_array_slice = src_image->type == VK_IMAGE_TYPE_3D ? 0 : src_start + i;
-
- radv_image_view_init(&dest_iview, cmd_buffer->device,
- &(VkImageViewCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
- .image = destImage,
- .viewType = radv_meta_get_view_type(dest_image),
- .format = dest_image->vk_format,
- .subresourceRange = {
- .aspectMask = dst_res->aspectMask,
- .baseMipLevel = dst_res->mipLevel,
- .levelCount = 1,
- .baseArrayLayer = dest_array_slice,
- .layerCount = 1
- },
- }, NULL);
- radv_image_view_init(&src_iview, cmd_buffer->device,
- &(VkImageViewCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
- .image = srcImage,
- .viewType = radv_meta_get_view_type(src_image),
- .format = src_image->vk_format,
- .subresourceRange = {
- .aspectMask = src_res->aspectMask,
- .baseMipLevel = src_res->mipLevel,
- .levelCount = 1,
- .baseArrayLayer = src_array_slice,
- .layerCount = 1
- },
- }, NULL);
- meta_emit_blit(cmd_buffer,
- src_image, &src_iview, srcImageLayout,
- src_offset_0, src_offset_1,
- dest_image, &dest_iview, destImageLayout,
- dest_offset_0, dest_offset_1,
- dest_box,
- sampler);
- }
+ unsigned src_x0 = region->srcOffsets[0].x;
+ unsigned src_x1 = region->srcOffsets[1].x;
+ unsigned dst_x0 = region->dstOffsets[0].x;
+ unsigned dst_x1 = region->dstOffsets[1].x;
+
+ unsigned src_y0 = region->srcOffsets[0].y;
+ unsigned src_y1 = region->srcOffsets[1].y;
+ unsigned dst_y0 = region->dstOffsets[0].y;
+ unsigned dst_y1 = region->dstOffsets[1].y;
+
+ VkRect2D dst_box;
+ dst_box.offset.x = MIN2(dst_x0, dst_x1);
+ dst_box.offset.y = MIN2(dst_y0, dst_y1);
+ dst_box.extent.width = dst_x1 - dst_x0;
+ dst_box.extent.height = dst_y1 - dst_y0;
+
+ const unsigned num_layers = dst_end - dst_start;
+ for (unsigned i = 0; i < num_layers; i++) {
+ struct radv_image_view dst_iview, src_iview;
+
+ const VkOffset2D dst_offset_0 = {
+ .x = dst_x0,
+ .y = dst_y0,
+ };
+ const VkOffset2D dst_offset_1 = {
+ .x = dst_x1,
+ .y = dst_y1,
+ };
+
+ float src_offset_0[3] = {
+ src_x0,
+ src_y0,
+ src_start + i * src_z_step + depth_center_offset,
+ };
+ float src_offset_1[3] = {
+ src_x1,
+ src_y1,
+ src_start + i * src_z_step + depth_center_offset,
+ };
+ const uint32_t dst_array_slice = dst_start + i;
+
+ /* 3D images have just 1 layer */
+ const uint32_t src_array_slice = src_image->type == VK_IMAGE_TYPE_3D ? 0 : src_start + i;
+
+ 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 = dst_res->aspectMask,
+ .baseMipLevel = dst_res->mipLevel,
+ .levelCount = 1,
+ .baseArrayLayer = dst_array_slice,
+ .layerCount = 1
+ },
+ }, NULL);
+ 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 = src_res->aspectMask,
+ .baseMipLevel = src_res->mipLevel,
+ .levelCount = 1,
+ .baseArrayLayer = src_array_slice,
+ .layerCount = 1
+ },
+ }, NULL);
+ meta_emit_blit(cmd_buffer,
+ src_image, &src_iview, src_image_layout,
+ src_offset_0, src_offset_1,
+ dst_image, &dst_iview, dst_image_layout,
+ dst_offset_0, dst_offset_1,
+ dst_box,
+ sampler);
}
/* Restore conditional rendering. */
@@ -705,6 +697,60 @@ void radv_CmdBlitImage(
&cmd_buffer->pool->alloc);
}
+void radv_CmdBlitImage(
+ VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkImageBlit* pRegions,
+ VkFilter filter)
+
+{
+ RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+ RADV_FROM_HANDLE(radv_image, src_image, srcImage);
+ RADV_FROM_HANDLE(radv_image, dst_image, dstImage);
+
+ for (unsigned r = 0; r < regionCount; r++) {
+ VkImageBlit2KHR blit = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR,
+ .srcSubresource = pRegions[r].srcSubresource,
+ .srcOffsets = {
+ pRegions[r].srcOffsets[0],
+ pRegions[r].srcOffsets[1],
+ },
+ .dstSubresource = pRegions[r].dstSubresource,
+ .dstOffsets = {
+ pRegions[r].dstOffsets[0],
+ pRegions[r].dstOffsets[1],
+ },
+ };
+
+ blit_image(cmd_buffer,
+ src_image, srcImageLayout,
+ dst_image, dstImageLayout,
+ &blit, filter);
+ }
+}
+
+void radv_CmdBlitImage2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkBlitImageInfo2KHR* pBlitImageInfo)
+{
+ RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+ RADV_FROM_HANDLE(radv_image, src_image, pBlitImageInfo->srcImage);
+ RADV_FROM_HANDLE(radv_image, dst_image, pBlitImageInfo->dstImage);
+
+ for (unsigned r = 0; r < pBlitImageInfo->regionCount; r++) {
+ blit_image(cmd_buffer,
+ src_image, pBlitImageInfo->srcImageLayout,
+ dst_image, pBlitImageInfo->dstImageLayout,
+ &pBlitImageInfo->pRegions[r],
+ pBlitImageInfo->filter);
+ }
+}
+
void
radv_device_finish_meta_blit_state(struct radv_device *device)
{