diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 464b1a1f8..9662b4e30 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -6525,6 +6525,46 @@ namespace dxvk { } + Rc DxvkContext::ensureImageViewCompatibility( + const Rc& view, + VkImageUsageFlagBits usage) { + // Return existing view if it already compatible with the image + VkFormat viewFormat = view->info().format; + + bool isFormatCompatible = view->image()->isViewCompatible(viewFormat); + bool isUsageCompatible = (view->image()->info().usage & usage) == usage; + + if (isFormatCompatible && isUsageCompatible) { + if (view->info().usage & usage) + return view; + + // Just create a new view with the correct usage flag + DxvkImageViewKey viewInfo = view->info(); + viewInfo.usage = usage; + return view->image()->createView(viewInfo); + } else { + // Actually need to relocate the image + DxvkImageUsageInfo usageInfo = { }; + usageInfo.usage = usage; + + if (!isFormatCompatible) { + usageInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT + | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT; + + usageInfo.viewFormatCount = 1u; + usageInfo.viewFormats = &viewFormat; + } + + if (!ensureImageCompatibility(view->image(), usageInfo)) + return nullptr; + + DxvkImageViewKey viewInfo = view->info(); + viewInfo.usage = usage; + return view->image()->createView(viewInfo); + } + } + + void DxvkContext::relocateResources( size_t bufferCount, const DxvkRelocateBufferInfo* bufferInfos, diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 830642f79..a29581b9f 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1751,6 +1751,10 @@ namespace dxvk { const Rc& buffer, VkDeviceSize copySize); + Rc ensureImageViewCompatibility( + const Rc& view, + VkImageUsageFlagBits usage); + void relocateResources( size_t bufferCount, const DxvkRelocateBufferInfo* bufferInfos,