anv: fix incorrect VMA alignment for CCS main surfaces
[mesa.git] / src / intel / vulkan / anv_device.c
index 9db62ef919ecdfcd1fc19053e28bd1711da1cc42..ca71cc6d24522ee07e40b86f9c94f5b4d08d36d1 100644 (file)
@@ -2972,6 +2972,14 @@ bool
 anv_vma_alloc(struct anv_device *device, struct anv_bo *bo,
               uint64_t client_address)
 {
+   const struct anv_physical_device *pdevice = &device->instance->physicalDevice;
+   const struct gen_device_info *devinfo = &pdevice->info;
+   /* Gen12 CCS surface addresses need to be 64K aligned. We have no way of
+    * telling what this allocation is for so pick the largest alignment.
+    */
+   const uint32_t vma_alignment =
+      devinfo->gen >= 12 ? (64 * 1024) : (4 * 1024);
+
    if (!(bo->flags & EXEC_OBJECT_PINNED)) {
       assert(!(bo->has_client_visible_address));
       return true;
@@ -2989,7 +2997,8 @@ anv_vma_alloc(struct anv_device *device, struct anv_bo *bo,
             bo->offset = gen_canonical_address(client_address);
          }
       } else {
-         uint64_t addr = util_vma_heap_alloc(&device->vma_cva, bo->size, 4096);
+         uint64_t addr =
+            util_vma_heap_alloc(&device->vma_cva, bo->size, vma_alignment);
          if (addr) {
             bo->offset = gen_canonical_address(addr);
             assert(addr == gen_48b_address(bo->offset));
@@ -3002,7 +3011,8 @@ anv_vma_alloc(struct anv_device *device, struct anv_bo *bo,
    assert(client_address == 0);
 
    if (bo->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) {
-      uint64_t addr = util_vma_heap_alloc(&device->vma_hi, bo->size, 4096);
+      uint64_t addr =
+         util_vma_heap_alloc(&device->vma_hi, bo->size, vma_alignment);
       if (addr) {
          bo->offset = gen_canonical_address(addr);
          assert(addr == gen_48b_address(bo->offset));
@@ -3010,7 +3020,8 @@ anv_vma_alloc(struct anv_device *device, struct anv_bo *bo,
    }
 
    if (bo->offset == 0) {
-      uint64_t addr = util_vma_heap_alloc(&device->vma_lo, bo->size, 4096);
+      uint64_t addr =
+         util_vma_heap_alloc(&device->vma_lo, bo->size, vma_alignment);
       if (addr) {
          bo->offset = gen_canonical_address(addr);
          assert(addr == gen_48b_address(bo->offset));
@@ -3139,19 +3150,6 @@ VkResult anv_AllocateMemory(
          break;
       }
 
-      case VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA: {
-         const struct wsi_memory_allocate_info *wsi_info = (void *)ext;
-         if (wsi_info->implicit_sync) {
-            /* We need to set the WRITE flag on window system buffers so that
-             * GEM will know we're writing to them and synchronize uses on
-             * other rings (eg if the display server uses the blitter ring).
-             */
-            alloc_flags |= ANV_BO_ALLOC_IMPLICIT_SYNC |
-                           ANV_BO_ALLOC_IMPLICIT_WRITE;
-         }
-         break;
-      }
-
       default:
          anv_debug_ignored_stype(ext->sType);
          break;
@@ -3925,8 +3923,17 @@ VkResult anv_CreateBuffer(
     VkBuffer*                                   pBuffer)
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_physical_device *pdevice = &device->instance->physicalDevice;
    struct anv_buffer *buffer;
 
+   /* Don't allow creating buffers bigger than our address space.  The real
+    * issue here is that we may align up the buffer size and we don't want
+    * doing so to cause roll-over.  However, no one has any business
+    * allocating a buffer larger than our GTT size.
+    */
+   if (pCreateInfo->size > pdevice->gtt_size)
+      return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
+
    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
 
    buffer = vk_alloc2(&device->alloc, pAllocator, sizeof(*buffer), 8,