pvr: Transfer support flipped rectangle mapping
authorOskar Rundgren <oskar.rundgren@imgtec.com>
Sun, 7 May 2023 13:31:13 +0000 (14:31 +0100)
committerMarge Bot <emma+marge@anholt.net>
Wed, 17 May 2023 08:18:26 +0000 (08:18 +0000)
The rectangles in "struct pvr_rect_mapping" are unsigned so a
flipped rectangle mapping isn't possible. Add new struct members
flip_x and flip_y to specify flipped mapping.

Add support for flipped rectangles in transfer copy blit path.
Support for flipped rectangles in the clip blit path is not done
in this change.

The new booleans are false by default because transfer command
"struct pvr_transfer_cmd" is zeroed on allocation in
pvr_transfer_cmd_alloc (pvr_blit.c).

Fixes:
  dEQP test case: dEQP-VK.api.copy_and_blit.core.blit_image.simple_tests
    .mirror_xy.nearest

Signed-off-by: Oskar Rundgren <oskar.rundgren@imgtec.com>
Reviewed-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22958>

src/imagination/vulkan/pvr_blit.c
src/imagination/vulkan/pvr_job_transfer.c
src/imagination/vulkan/pvr_private.h

index 5943045..a9dc1f3 100644 (file)
@@ -206,15 +206,34 @@ void pvr_CmdBlitImage2KHR(VkCommandBuffer commandBuffer,
          region->srcOffsets[1].x - region->srcOffsets[0].x;
       const uint32_t src_height =
          region->srcOffsets[1].y - region->srcOffsets[0].y;
-      const uint32_t dst_width =
-         region->dstOffsets[1].x - region->dstOffsets[0].x;
-      const uint32_t dst_height =
-         region->dstOffsets[1].y - region->dstOffsets[0].y;
+      uint32_t dst_width;
+      uint32_t dst_height;
 
       float initial_depth_offset;
       VkExtent3D src_extent;
       VkExtent3D dst_extent;
+      VkOffset3D dst_offset = region->dstOffsets[0];
       float z_slice_stride;
+      bool flip_x;
+      bool flip_y;
+
+      if (region->dstOffsets[1].x > region->dstOffsets[0].x) {
+         dst_width = region->dstOffsets[1].x - region->dstOffsets[0].x;
+         flip_x = false;
+      } else {
+         dst_width = region->dstOffsets[0].x - region->dstOffsets[1].x;
+         flip_x = true;
+         dst_offset.x = region->dstOffsets[1].x;
+      }
+
+      if (region->dstOffsets[1].y > region->dstOffsets[0].y) {
+         dst_height = region->dstOffsets[1].y - region->dstOffsets[0].y;
+         flip_y = false;
+      } else {
+         dst_height = region->dstOffsets[0].y - region->dstOffsets[1].y;
+         flip_y = true;
+         dst_offset.y = region->dstOffsets[1].y;
+      }
 
       /* If any of the extent regions is zero, then reject the blit and
        * continue.
@@ -311,7 +330,7 @@ void pvr_CmdBlitImage2KHR(VkCommandBuffer commandBuffer,
                                     dst,
                                     region->dstSubresource.baseArrayLayer + j,
                                     region->dstSubresource.mipLevel,
-                                    &region->dstOffsets[0],
+                                    &dst_offset,
                                     &dst_extent,
                                     min_dst_z,
                                     dst->vk.format,
@@ -328,6 +347,8 @@ void pvr_CmdBlitImage2KHR(VkCommandBuffer commandBuffer,
 
             transfer_cmd->sources[0].mappings[0].src_rect = src_rect;
             transfer_cmd->sources[0].mappings[0].dst_rect = dst_rect;
+            transfer_cmd->sources[0].mappings[0].flip_x = flip_x;
+            transfer_cmd->sources[0].mappings[0].flip_y = flip_y;
             transfer_cmd->sources[0].mapping_count++;
 
             transfer_cmd->sources[0].surface = src_surface;
index 7b60be8..cfbcc3e 100644 (file)
@@ -1443,7 +1443,9 @@ static void pvr_uv_space(const struct pvr_device_info *dev_info,
                     (src_rect->offset.y * dst_y1 !=
                      src_y1 * dst_rect->offset.y) ||
                     (src_rect->extent.width != dst_rect->extent.width) ||
-                    (src_rect->extent.height != dst_rect->extent.height)) {
+                    (src_rect->extent.height != dst_rect->extent.height) ||
+                    transfer_cmd->sources[0U].mappings[0U].flip_x ||
+                    transfer_cmd->sources[0U].mappings[0U].flip_y) {
             layer->layer_floats = PVR_INT_COORD_SET_FLOATS_4;
          } else {
             layer->layer_floats = PVR_INT_COORD_SET_FLOATS_0;
@@ -1798,17 +1800,27 @@ pvr_dma_texture_floats(const struct pvr_transfer_cmd *transfer_cmd,
          float offset = 0.0f;
          float tmp;
 
-         dst_x = dst_rect.extent.width;
-         dst_y = dst_rect.extent.height;
+         dst_x = mapping->flip_x ? -(int32_t)dst_rect.extent.width
+                                 : dst_rect.extent.width;
+         dst_y = mapping->flip_y ? -(int32_t)dst_rect.extent.height
+                                 : dst_rect.extent.height;
          src_x = src_rect.extent.width;
          src_y = src_rect.extent.height;
 
          nums[0U] = src_x;
          denom[0U] = dst_x;
-         consts[0U] = src_rect.offset.x * dst_x - src_x * dst_rect.offset.x;
+         consts[0U] =
+            mapping->flip_x
+               ? src_rect.offset.x * dst_x -
+                    src_x * (dst_rect.offset.x + dst_rect.extent.width)
+               : src_rect.offset.x * dst_x - src_x * dst_rect.offset.x;
          nums[1U] = src_y;
          denom[1U] = dst_y;
-         consts[1U] = src_rect.offset.y * dst_y - src_y * dst_rect.offset.y;
+         consts[1U] =
+            mapping->flip_y
+               ? src_rect.offset.y * dst_y -
+                    src_y * (dst_rect.offset.y + dst_rect.extent.height)
+               : src_rect.offset.y * dst_y - src_y * dst_rect.offset.y;
 
          for (uint32_t i = 0U; i < 2U; i++) {
             tmp = (float)(nums[i]) / (float)(denom[i]);
index 07aadaf..36e9ddf 100644 (file)
@@ -394,6 +394,8 @@ struct pvr_transfer_cmd_surface {
 struct pvr_rect_mapping {
    VkRect2D src_rect;
    VkRect2D dst_rect;
+   bool flip_x;
+   bool flip_y;
 };
 
 /* Describes an Alpha-Transparency configuration - for Transfer Queue Use. */