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>
This commit is contained in:
Samuel Pitoiset 2020-09-22 08:46:43 +02:00 committed by Marge Bot
parent cc709a07f2
commit eccc73ff78

View file

@ -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 (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 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 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;
}
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;
}
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 = 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_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 = 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;
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 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;
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 dst_iview, src_iview;
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 dst_offset_0 = {
.x = dst_x0,
.y = dst_y0,
};
const VkOffset2D dst_offset_1 = {
.x = dst_x1,
.y = dst_y1,
};
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 dst_array_slice = dst_start + i;
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;
/* 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);
}
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)
{