diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b55a15ad..ac54e5b8 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1943,9 +1943,14 @@ namespace dxvk { && (image->info().access & usageInfo.access) == usageInfo.access && (usageInfo.layout && image->info().layout == usageInfo.layout); - // If everything matches already, no need to do anything. - if (isUsageAndFormatCompatible && isAccessAndLayoutCompatible) + // If everything matches already, no need to do anything. Only ensure + // that the stable adress bit is respected if set for the first time. + if (isUsageAndFormatCompatible && isAccessAndLayoutCompatible) { + if (usageInfo.stableGpuAddress && image->canRelocate()) + image->assignResourceWithUsage(image->getAllocation(), usageInfo); + return true; + } // Ensure the image is accessible and in its default layout this->spillRenderPass(true); diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index d7a46d1c..871ff3dd 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -49,7 +49,7 @@ namespace dxvk { bool DxvkImage::canRelocate() const { - return !m_imageInfo.mapPtr && !m_shared + return !m_imageInfo.mapPtr && !m_shared && !m_stableAddress && !m_storage->flags().test(DxvkAllocationFlag::Imported) && !(m_info.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT); } @@ -151,7 +151,7 @@ namespace dxvk { void* sharedMemoryInfo = nullptr; VkExportMemoryAllocateInfo sharedExport = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO }; - VkImportMemoryWin32HandleInfoKHR sharedImportWin32= { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR }; + VkImportMemoryWin32HandleInfoKHR sharedImportWin32 = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR }; if (m_shared && m_info.sharing.mode == DxvkSharedHandleMode::Export) { sharedExport.pNext = std::exchange(sharedMemoryInfo, &sharedExport); @@ -164,7 +164,8 @@ namespace dxvk { sharedImportWin32.handle = m_info.sharing.handle; } - return m_allocator->createImageResource(imageInfo, m_properties, sharedMemoryInfo); + return m_allocator->createImageResource(imageInfo, + m_properties, sharedMemoryInfo); } @@ -206,6 +207,7 @@ namespace dxvk { m_info.viewFormats = m_viewFormats.data(); } + m_stableAddress |= usageInfo.stableGpuAddress; return old; } diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index 51eacab7..b03eb468 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -91,6 +91,8 @@ namespace dxvk { uint32_t viewFormatCount = 0u; // View formats to add to the compatibility list const VkFormat* viewFormats = nullptr; + // Requtes the image to not be relocated in the future + VkBool32 stableGpuAddress = VK_FALSE; }; @@ -583,6 +585,7 @@ namespace dxvk { uint32_t m_version = 0u; VkBool32 m_shared = VK_FALSE; + VkBool32 m_stableAddress = VK_FALSE; DxvkResourceImageInfo m_imageInfo = { };