Module: Mesa
Branch: main
Commit: 7f6d3b82c8a2120e525cef5ff69e6e5f732f85c2
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=7f6d3b82c8a2120e525cef5ff69e6e5f732f85c2

Author: Faith Ekstrand <faith.ekstr...@collabora.com>
Date:   Thu Nov 16 17:24:42 2023 -0600

nvk: Implement bufferDeviceAddressCaptureReplay

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10158
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26242>

---

 src/nouveau/vulkan/nvk_buffer.c          | 62 +++++++++++++++++++++++++++++---
 src/nouveau/vulkan/nvk_physical_device.c |  4 +--
 2 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/src/nouveau/vulkan/nvk_buffer.c b/src/nouveau/vulkan/nvk_buffer.c
index 487f771fb34..d2d8862f51e 100644
--- a/src/nouveau/vulkan/nvk_buffer.c
+++ b/src/nouveau/vulkan/nvk_buffer.c
@@ -26,12 +26,53 @@ nvk_get_buffer_alignment(UNUSED const struct nv_device_info 
*info,
                       VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT_KHR))
       alignment = MAX2(alignment, NVK_MIN_UBO_ALIGNMENT);
 
-   if (create_flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)
+   if (create_flags & (VK_BUFFER_CREATE_SPARSE_BINDING_BIT |
+                       VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT))
       alignment = MAX2(alignment, 4096);
 
    return alignment;
 }
 
+static uint64_t
+nvk_get_bda_replay_addr(const VkBufferCreateInfo *pCreateInfo)
+{
+   uint64_t addr = 0;
+   vk_foreach_struct_const(ext, pCreateInfo->pNext) {
+      switch (ext->sType) {
+      case VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO: {
+         const VkBufferOpaqueCaptureAddressCreateInfo *bda = (void *)ext;
+         if (bda->opaqueCaptureAddress != 0) {
+#ifdef NDEBUG
+            return bda->opaqueCaptureAddress;
+#else
+            assert(addr == 0 || bda->opaqueCaptureAddress == addr);
+            addr = bda->opaqueCaptureAddress;
+#endif
+         }
+         break;
+      }
+
+      case VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT: {
+         const VkBufferDeviceAddressCreateInfoEXT *bda = (void *)ext;
+         if (bda->deviceAddress != 0) {
+#ifdef NDEBUG
+            return bda->deviceAddress;
+#else
+            assert(addr == 0 || bda->deviceAddress == addr);
+            addr = bda->deviceAddress;
+#endif
+         }
+         break;
+      }
+
+      default:
+         break;
+      }
+   }
+
+   return addr;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL
 nvk_CreateBuffer(VkDevice device,
                  const VkBufferCreateInfo *pCreateInfo,
@@ -50,7 +91,8 @@ nvk_CreateBuffer(VkDevice device,
       return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY);
 
    if (buffer->vk.size > 0 &&
-       (buffer->vk.create_flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)) {
+       (buffer->vk.create_flags & (VK_BUFFER_CREATE_SPARSE_BINDING_BIT |
+                                   
VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT))) {
       const uint32_t alignment =
          nvk_get_buffer_alignment(&nvk_device_physical(dev)->info,
                                   buffer->vk.usage,
@@ -60,9 +102,17 @@ nvk_CreateBuffer(VkDevice device,
 
       const bool sparse_residency =
          buffer->vk.create_flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT;
+      const bool bda_capture_replay =
+         buffer->vk.create_flags & 
VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT;
+
+      uint64_t bda_replay_addr = 0;
+      if (bda_capture_replay)
+         bda_replay_addr = nvk_get_bda_replay_addr(pCreateInfo);
 
-      buffer->addr = nouveau_ws_alloc_vma(dev->ws_dev, 0, buffer->vma_size_B,
-                                          alignment, false, sparse_residency);
+      buffer->addr = nouveau_ws_alloc_vma(dev->ws_dev, bda_replay_addr,
+                                          buffer->vma_size_B,
+                                          alignment, bda_capture_replay,
+                                          sparse_residency);
       if (buffer->addr == 0) {
          vk_buffer_destroy(&dev->vk, pAllocator, &buffer->vk);
          return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY,
@@ -89,10 +139,12 @@ nvk_DestroyBuffer(VkDevice device,
    if (buffer->vma_size_B > 0) {
       const bool sparse_residency =
          buffer->vk.create_flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT;
+      const bool bda_capture_replay =
+         buffer->vk.create_flags & 
VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT;
 
       nouveau_ws_bo_unbind_vma(dev->ws_dev, buffer->addr, buffer->vma_size_B);
       nouveau_ws_free_vma(dev->ws_dev, buffer->addr, buffer->vma_size_B,
-                          false, sparse_residency);
+                          bda_capture_replay, sparse_residency);
    }
 
    vk_buffer_destroy(&dev->vk, pAllocator, &buffer->vk);
diff --git a/src/nouveau/vulkan/nvk_physical_device.c 
b/src/nouveau/vulkan/nvk_physical_device.c
index 86252246283..0acbb70dd18 100644
--- a/src/nouveau/vulkan/nvk_physical_device.c
+++ b/src/nouveau/vulkan/nvk_physical_device.c
@@ -237,7 +237,7 @@ nvk_get_device_features(const struct nv_device_info *info,
       .hostQueryReset = true,
       .timelineSemaphore = true,
       .bufferDeviceAddress = true,
-      .bufferDeviceAddressCaptureReplay = false,
+      .bufferDeviceAddressCaptureReplay = true,
       .bufferDeviceAddressMultiDevice = false,
       .shaderOutputViewportIndex = info->cls_eng3d >= MAXWELL_B,
       .shaderOutputLayer = info->cls_eng3d >= MAXWELL_B,
@@ -277,7 +277,7 @@ nvk_get_device_features(const struct nv_device_info *info,
       .borderColorSwizzleFromImage = false,
 
       /* VK_EXT_buffer_device_address */
-      .bufferDeviceAddressCaptureReplayEXT = false,
+      .bufferDeviceAddressCaptureReplayEXT = true,
 
       /* VK_EXT_conditional_rendering */
       .conditionalRendering = true,

Reply via email to