anv/meta_blit: Use unorm formats for 8 and 16-bit RGB and RGBA values
[mesa.git] / src / intel / vulkan / anv_meta_blit.c
index 07ebcbc06b1ad3ec403fd1ea24438aca906d99e9..96a3b7669acebde9f6998a0a0ae19c429e4b23eb 100644 (file)
@@ -165,7 +165,6 @@ meta_emit_blit(struct anv_cmd_buffer *cmd_buffer,
                VkFilter blit_filter)
 {
    struct anv_device *device = cmd_buffer->device;
-   VkDescriptorPool dummy_desc_pool = (VkDescriptorPool)1;
 
    struct blit_vb_data {
       float pos[2];
@@ -244,14 +243,31 @@ meta_emit_blit(struct anv_cmd_buffer *cmd_buffer,
          .minFilter = blit_filter,
       }, &cmd_buffer->pool->alloc, &sampler);
 
+   VkDescriptorPool desc_pool;
+   anv_CreateDescriptorPool(anv_device_to_handle(device),
+      &(const VkDescriptorPoolCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
+         .pNext = NULL,
+         .flags = 0,
+         .maxSets = 1,
+         .poolSizeCount = 1,
+         .pPoolSizes = (VkDescriptorPoolSize[]) {
+            {
+               .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+               .descriptorCount = 1
+            },
+         }
+      }, &cmd_buffer->pool->alloc, &desc_pool);
+
    VkDescriptorSet set;
    anv_AllocateDescriptorSets(anv_device_to_handle(device),
       &(VkDescriptorSetAllocateInfo) {
          .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
-         .descriptorPool = dummy_desc_pool,
+         .descriptorPool = desc_pool,
          .descriptorSetCount = 1,
          .pSetLayouts = &device->meta_state.blit.ds_layout
       }, &set);
+
    anv_UpdateDescriptorSets(anv_device_to_handle(device),
       1, /* writeCount */
       (VkWriteDescriptorSet[]) {
@@ -341,7 +357,8 @@ meta_emit_blit(struct anv_cmd_buffer *cmd_buffer,
    /* At the point where we emit the draw call, all data from the
     * descriptor sets, etc. has been used.  We are free to delete it.
     */
-   anv_descriptor_set_destroy(device, anv_descriptor_set_from_handle(set));
+   anv_DestroyDescriptorPool(anv_device_to_handle(device),
+                             desc_pool, &cmd_buffer->pool->alloc);
    anv_DestroySampler(anv_device_to_handle(device), sampler,
                       &cmd_buffer->pool->alloc);
    anv_DestroyFramebuffer(anv_device_to_handle(device), fb,
@@ -358,17 +375,26 @@ meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
 static VkFormat
 vk_format_for_size(int bs)
 {
-   /* Note: We intentionally use the 4-channel formats whenever we can.
-    * This is so that, when we do a RGB <-> RGBX copy, the two formats will
-    * line up even though one of them is 3/4 the size of the other.
+   /* The choice of UNORM and UINT formats is very intentional here.  Most of
+    * the time, we want to use a UINT format to avoid any rounding error in
+    * the blit.  For stencil blits, R8_UINT is required by the hardware.
+    * (It's the only format allowed in conjunction with W-tiling.)  Also we
+    * intentionally use the 4-channel formats whenever we can.  This is so
+    * that, when we do a RGB <-> RGBX copy, the two formats will line up even
+    * though one of them is 3/4 the size of the other.  The choice of UNORM
+    * vs. UINT is also very intentional because Haswell doesn't handle 8 or
+    * 16-bit RGB UINT formats at all so we have to use UNORM there.
+    * Fortunately, the only time we should ever use two different formats in
+    * the table below is for RGB -> RGBA blits and so we will never have any
+    * UNORM/UINT mismatch.
     */
    switch (bs) {
    case 1: return VK_FORMAT_R8_UINT;
    case 2: return VK_FORMAT_R8G8_UINT;
-   case 3: return VK_FORMAT_R8G8B8_UINT;
-   case 4: return VK_FORMAT_R8G8B8A8_UINT;
-   case 6: return VK_FORMAT_R16G16B16_UINT;
-   case 8: return VK_FORMAT_R16G16B16A16_UINT;
+   case 3: return VK_FORMAT_R8G8B8_UNORM;
+   case 4: return VK_FORMAT_R8G8B8A8_UNORM;
+   case 6: return VK_FORMAT_R16G16B16_UNORM;
+   case 8: return VK_FORMAT_R16G16B16A16_UNORM;
    case 12: return VK_FORMAT_R32G32B32_UINT;
    case 16: return VK_FORMAT_R32G32B32A32_UINT;
    default:
@@ -434,7 +460,7 @@ do_buffer_copy(struct anv_cmd_buffer *cmd_buffer,
             .layerCount = 1
          },
       },
-      cmd_buffer, 0);
+      cmd_buffer, 0, VK_IMAGE_USAGE_SAMPLED_BIT);
 
    struct anv_image_view dest_iview;
    anv_image_view_init(&dest_iview, cmd_buffer->device,
@@ -451,7 +477,7 @@ do_buffer_copy(struct anv_cmd_buffer *cmd_buffer,
             .layerCount = 1,
          },
       },
-      cmd_buffer, 0);
+      cmd_buffer, 0, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
 
    meta_emit_blit(cmd_buffer,
                   anv_image_from_handle(src_image),
@@ -694,33 +720,36 @@ void anv_CmdCopyImage(
                .layerCount = pRegions[r].dstSubresource.layerCount,
             },
          },
-         cmd_buffer, 0);
-
-      const VkOffset3D dest_offset = {
-         .x = pRegions[r].dstOffset.x,
-         .y = pRegions[r].dstOffset.y,
-         .z = 0,
-      };
-
-      unsigned num_slices;
-      if (src_image->type == VK_IMAGE_TYPE_3D) {
-         assert(pRegions[r].srcSubresource.layerCount == 1 &&
-                pRegions[r].dstSubresource.layerCount == 1);
-         num_slices = pRegions[r].extent.depth;
-      } else {
-         assert(pRegions[r].srcSubresource.layerCount ==
-                pRegions[r].dstSubresource.layerCount);
-         assert(pRegions[r].extent.depth == 1);
-         num_slices = pRegions[r].dstSubresource.layerCount;
-      }
+         cmd_buffer, 0, VK_IMAGE_USAGE_SAMPLED_BIT);
 
       const uint32_t dest_base_array_slice =
          anv_meta_get_iview_layer(dest_image, &pRegions[r].dstSubresource,
                                   &pRegions[r].dstOffset);
 
-      for (unsigned slice = 0; slice < num_slices; slice++) {
+
+      unsigned num_slices_3d = pRegions[r].extent.depth;
+      unsigned num_slices_array = pRegions[r].dstSubresource.layerCount;
+      unsigned slice_3d = 0;
+      unsigned slice_array = 0;
+      while (slice_3d < num_slices_3d && slice_array < num_slices_array) {
          VkOffset3D src_offset = pRegions[r].srcOffset;
-         src_offset.z += slice;
+         src_offset.z += slice_3d + slice_array;
+
+         uint32_t img_x = 0;
+         uint32_t img_y = 0;
+         uint32_t img_o = 0;
+         if (isl_format_is_compressed(dest_image->format->isl_format))
+            isl_surf_get_image_intratile_offset_el(&cmd_buffer->device->isl_dev,
+                                                   &dest_image->color_surface.isl,
+                                                   pRegions[r].dstSubresource.mipLevel,
+                                                   pRegions[r].dstSubresource.baseArrayLayer + slice_array,
+                                                   pRegions[r].dstOffset.z + slice_3d,
+                                                   &img_o, &img_x, &img_y);
+
+         VkOffset3D dest_offset_el = meta_region_offset_el(dest_image, &pRegions[r].dstOffset);
+         dest_offset_el.x += img_x;
+         dest_offset_el.y += img_y;
+         dest_offset_el.z = 0;
 
          struct anv_image_view dest_iview;
          anv_image_view_init(&dest_iview, cmd_buffer->device,
@@ -733,20 +762,29 @@ void anv_CmdCopyImage(
                   .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                   .baseMipLevel = pRegions[r].dstSubresource.mipLevel,
                   .levelCount = 1,
-                  .baseArrayLayer = dest_base_array_slice + slice,
+                  .baseArrayLayer = dest_base_array_slice +
+                                    slice_array + slice_3d,
                   .layerCount = 1
                },
             },
-            cmd_buffer, 0);
+            cmd_buffer, img_o, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
+
+         const VkExtent3D img_extent_el = meta_region_extent_el(dest_image->vk_format,
+                                                                &pRegions[r].extent);
 
          meta_emit_blit(cmd_buffer,
                         src_image, &src_iview,
                         src_offset,
-                        pRegions[r].extent,
+                        img_extent_el,
                         dest_image, &dest_iview,
-                        dest_offset,
-                        pRegions[r].extent,
+                        dest_offset_el,
+                        img_extent_el,
                         VK_FILTER_NEAREST);
+
+         if (dest_image->type == VK_IMAGE_TYPE_3D)
+            slice_3d++;
+         else
+            slice_array++;
       }
    }
 
@@ -797,7 +835,7 @@ void anv_CmdBlitImage(
                .layerCount = 1
             },
          },
-         cmd_buffer, 0);
+         cmd_buffer, 0, VK_IMAGE_USAGE_SAMPLED_BIT);
 
       const VkOffset3D dest_offset = {
          .x = pRegions[r].dstOffsets[0].x,
@@ -847,7 +885,7 @@ void anv_CmdBlitImage(
                .layerCount = 1
             },
          },
-         cmd_buffer, 0);
+         cmd_buffer, 0, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
 
       meta_emit_blit(cmd_buffer,
                      src_image, &src_iview,
@@ -962,7 +1000,7 @@ void anv_CmdCopyBufferToImage(
                   .layerCount = 1,
                },
             },
-            cmd_buffer, 0);
+            cmd_buffer, 0, VK_IMAGE_USAGE_SAMPLED_BIT);
 
          uint32_t img_x = 0;
          uint32_t img_y = 0;
@@ -996,7 +1034,7 @@ void anv_CmdCopyBufferToImage(
                   .layerCount = 1
                },
             },
-            cmd_buffer, img_o);
+            cmd_buffer, img_o, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
 
          const VkExtent3D img_extent_el = meta_region_extent_el(dest_image->vk_format,
                                                       &pRegions[r].imageExtent);
@@ -1075,7 +1113,7 @@ void anv_CmdCopyImageToBuffer(
                .layerCount = pRegions[r].imageSubresource.layerCount,
             },
          },
-         cmd_buffer, 0);
+         cmd_buffer, 0, VK_IMAGE_USAGE_SAMPLED_BIT);
 
       struct anv_image *dest_image =
          make_image_for_buffer(vk_device, destBuffer, src_image->vk_format,
@@ -1111,7 +1149,7 @@ void anv_CmdCopyImageToBuffer(
                   .layerCount = 1
                },
             },
-            cmd_buffer, 0);
+            cmd_buffer, 0, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
 
          meta_emit_blit(cmd_buffer,
                         anv_image_from_handle(srcImage),