radv: fix flipped blits

This fixes:
dEQP-VK.api.copy_and_blit.blit_image.simple_tests.mirror*

Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Dave Airlie 2016-11-15 04:54:28 +00:00
parent b06568873d
commit 3b6893b678
1 changed files with 111 additions and 57 deletions

View File

@ -226,12 +226,13 @@ static void
meta_emit_blit(struct radv_cmd_buffer *cmd_buffer, meta_emit_blit(struct radv_cmd_buffer *cmd_buffer,
struct radv_image *src_image, struct radv_image *src_image,
struct radv_image_view *src_iview, struct radv_image_view *src_iview,
VkOffset3D src_offset, VkOffset3D src_offset_0,
VkExtent3D src_extent, VkOffset3D src_offset_1,
struct radv_image *dest_image, struct radv_image *dest_image,
struct radv_image_view *dest_iview, struct radv_image_view *dest_iview,
VkOffset3D dest_offset, VkOffset3D dest_offset_0,
VkExtent3D dest_extent, VkOffset3D dest_offset_1,
VkRect2D dest_box,
VkFilter blit_filter) VkFilter blit_filter)
{ {
struct radv_device *device = cmd_buffer->device; struct radv_device *device = cmd_buffer->device;
@ -245,38 +246,37 @@ meta_emit_blit(struct radv_cmd_buffer *cmd_buffer,
unsigned vb_size = 3 * sizeof(*vb_data); unsigned vb_size = 3 * sizeof(*vb_data);
vb_data[0] = (struct blit_vb_data) { vb_data[0] = (struct blit_vb_data) {
.pos = { .pos = {
dest_offset.x, dest_offset_0.x,
dest_offset.y, dest_offset_0.y,
}, },
.tex_coord = { .tex_coord = {
(float)(src_offset.x) / (float)src_iview->extent.width, (float)src_offset_0.x / (float)src_iview->extent.width,
(float)(src_offset.y) / (float)src_iview->extent.height, (float)src_offset_0.y / (float)src_iview->extent.height,
(float)src_offset.z / (float)src_iview->extent.depth, (float)src_offset_0.z / (float)src_iview->extent.depth,
}, },
}; };
vb_data[1] = (struct blit_vb_data) { vb_data[1] = (struct blit_vb_data) {
.pos = { .pos = {
dest_offset.x, dest_offset_0.x,
dest_offset.y + dest_extent.height, dest_offset_1.y,
}, },
.tex_coord = { .tex_coord = {
(float)src_offset.x / (float)src_iview->extent.width, (float)src_offset_0.x / (float)src_iview->extent.width,
(float)(src_offset.y + src_extent.height) / (float)src_offset_1.y / (float)src_iview->extent.height,
(float)src_iview->extent.height, (float)src_offset_0.z / (float)src_iview->extent.depth,
(float)src_offset.z / (float)src_iview->extent.depth,
}, },
}; };
vb_data[2] = (struct blit_vb_data) { vb_data[2] = (struct blit_vb_data) {
.pos = { .pos = {
dest_offset.x + dest_extent.width, dest_offset_1.x,
dest_offset.y, dest_offset_0.y,
}, },
.tex_coord = { .tex_coord = {
(float)(src_offset.x + src_extent.width) / (float)src_iview->extent.width, (float)src_offset_1.x / (float)src_iview->extent.width,
(float)src_offset.y / (float)src_iview->extent.height, (float)src_offset_0.y / (float)src_iview->extent.height,
(float)src_offset.z / (float)src_iview->extent.depth, (float)src_offset_0.z / (float)src_iview->extent.depth,
}, },
}; };
radv_cmd_buffer_upload_data(cmd_buffer, vb_size, 16, vb_data, &offset); radv_cmd_buffer_upload_data(cmd_buffer, vb_size, 16, vb_data, &offset);
@ -355,8 +355,8 @@ meta_emit_blit(struct radv_cmd_buffer *cmd_buffer,
.renderPass = device->meta_state.blit.render_pass[fs_key], .renderPass = device->meta_state.blit.render_pass[fs_key],
.framebuffer = fb, .framebuffer = fb,
.renderArea = { .renderArea = {
.offset = { dest_offset.x, dest_offset.y }, .offset = { dest_box.offset.x, dest_box.offset.y },
.extent = { dest_extent.width, dest_extent.height }, .extent = { dest_box.extent.width, dest_box.extent.height },
}, },
.clearValueCount = 0, .clearValueCount = 0,
.pClearValues = NULL, .pClearValues = NULL,
@ -383,8 +383,8 @@ meta_emit_blit(struct radv_cmd_buffer *cmd_buffer,
.renderPass = device->meta_state.blit.depth_only_rp, .renderPass = device->meta_state.blit.depth_only_rp,
.framebuffer = fb, .framebuffer = fb,
.renderArea = { .renderArea = {
.offset = { dest_offset.x, dest_offset.y }, .offset = { dest_box.offset.x, dest_box.offset.y },
.extent = { dest_extent.width, dest_extent.height }, .extent = { dest_box.extent.width, dest_box.extent.height },
}, },
.clearValueCount = 0, .clearValueCount = 0,
.pClearValues = NULL, .pClearValues = NULL,
@ -410,8 +410,8 @@ meta_emit_blit(struct radv_cmd_buffer *cmd_buffer,
.renderPass = device->meta_state.blit.stencil_only_rp, .renderPass = device->meta_state.blit.stencil_only_rp,
.framebuffer = fb, .framebuffer = fb,
.renderArea = { .renderArea = {
.offset = { dest_offset.x, dest_offset.y }, .offset = { dest_box.offset.x, dest_box.offset.y },
.extent = { dest_extent.width, dest_extent.height }, .extent = { dest_box.extent.width, dest_box.extent.height },
}, },
.clearValueCount = 0, .clearValueCount = 0,
.pClearValues = NULL, .pClearValues = NULL,
@ -461,6 +461,26 @@ meta_emit_blit(struct radv_cmd_buffer *cmd_buffer,
&cmd_buffer->pool->alloc); &cmd_buffer->pool->alloc);
} }
static bool
flip_coords(unsigned *src0, unsigned *src1, unsigned *dst0, unsigned *dst1)
{
bool flip = false;
if (*src0 > *src1) {
unsigned tmp = *src0;
*src0 = *src1;
*src1 = tmp;
flip = !flip;
}
if (*dst0 > *dst1) {
unsigned tmp = *dst0;
*dst0 = *dst1;
*dst1 = tmp;
flip = !flip;
}
return flip;
}
void radv_CmdBlitImage( void radv_CmdBlitImage(
VkCommandBuffer commandBuffer, VkCommandBuffer commandBuffer,
VkImage srcImage, VkImage srcImage,
@ -507,27 +527,50 @@ void radv_CmdBlitImage(
}, },
cmd_buffer, VK_IMAGE_USAGE_SAMPLED_BIT); cmd_buffer, VK_IMAGE_USAGE_SAMPLED_BIT);
if (pRegions[r].dstOffsets[1].x < pRegions[r].dstOffsets[0].x || unsigned dst_start, dst_end;
pRegions[r].dstOffsets[1].y < pRegions[r].dstOffsets[0].y || if (dest_image->type == VK_IMAGE_TYPE_3D) {
pRegions[r].srcOffsets[1].x < pRegions[r].srcOffsets[0].x || assert(dst_res->baseArrayLayer == 0);
pRegions[r].srcOffsets[1].y < pRegions[r].srcOffsets[0].y) dst_start = pRegions[r].dstOffsets[0].z;
radv_finishme("FINISHME: Allow flipping in blits"); dst_end = pRegions[r].dstOffsets[1].z;
} else {
dst_start = dst_res->baseArrayLayer;
dst_end = dst_start + dst_res->layerCount;
}
const VkExtent3D dest_extent = { unsigned src_start, src_end;
.width = pRegions[r].dstOffsets[1].x - pRegions[r].dstOffsets[0].x, if (src_image->type == VK_IMAGE_TYPE_3D) {
.height = pRegions[r].dstOffsets[1].y - pRegions[r].dstOffsets[0].y, assert(src_res->baseArrayLayer == 0);
.depth = 1, 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;
}
const VkExtent3D src_extent = { bool flip_z = flip_coords(&src_start, &src_end, &dst_start, &dst_end);
.width = pRegions[r].srcOffsets[1].x - pRegions[r].srcOffsets[0].x, float src_z_step = (float)(src_end + 1 - src_start) /
.height = pRegions[r].srcOffsets[1].y - pRegions[r].srcOffsets[0].y, (float)(dst_end + 1 - dst_start);
.depth = pRegions[r].srcOffsets[1].z - pRegions[r].srcOffsets[0].z,
};
if (flip_z) {
src_start = src_end;
src_z_step *= -1;
}
if (src_res->layerCount > 1) unsigned src_x0 = pRegions[r].srcOffsets[0].x;
radv_finishme("FINISHME: copy multiple array layers"); 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 = abs(dst_x1 - dst_x0);
dest_box.extent.height = abs(dst_y1 - dst_y0);
struct radv_image_view dest_iview; struct radv_image_view dest_iview;
unsigned usage; unsigned usage;
@ -536,21 +579,31 @@ void radv_CmdBlitImage(
else else
usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
for (unsigned i = pRegions[r].dstOffsets[0].z; i < pRegions[r].dstOffsets[1].z; i++) { const unsigned num_layers = dst_end - dst_start;
for (unsigned i = 0; i < num_layers; i++) {
const VkOffset3D dest_offset = { const VkOffset3D dest_offset_0 = {
.x = pRegions[r].dstOffsets[0].x, .x = dst_x0,
.y = pRegions[r].dstOffsets[0].y, .y = dst_y0,
.z = i, .z = dst_start + i ,
}; };
VkOffset3D src_offset = { const VkOffset3D dest_offset_1 = {
.x = pRegions[r].srcOffsets[0].x, .x = dst_x1,
.y = pRegions[r].srcOffsets[0].y, .y = dst_y1,
.z = i, .z = dst_start + i ,
};
VkOffset3D src_offset_0 = {
.x = src_x0,
.y = src_y0,
.z = src_start + i * src_z_step,
};
VkOffset3D src_offset_1 = {
.x = src_x1,
.y = src_y1,
.z = src_start + i * src_z_step,
}; };
const uint32_t dest_array_slice = const uint32_t dest_array_slice =
radv_meta_get_iview_layer(dest_image, dst_res, radv_meta_get_iview_layer(dest_image, dst_res,
&dest_offset); &dest_offset_0);
radv_image_view_init(&dest_iview, cmd_buffer->device, radv_image_view_init(&dest_iview, cmd_buffer->device,
&(VkImageViewCreateInfo) { &(VkImageViewCreateInfo) {
@ -569,9 +622,10 @@ void radv_CmdBlitImage(
cmd_buffer, usage); cmd_buffer, usage);
meta_emit_blit(cmd_buffer, meta_emit_blit(cmd_buffer,
src_image, &src_iview, src_image, &src_iview,
src_offset, src_extent, src_offset_0, src_offset_1,
dest_image, &dest_iview, dest_image, &dest_iview,
dest_offset, dest_extent, dest_offset_0, dest_offset_1,
dest_box,
filter); filter);
} }
} }