1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 19:54:19 +01:00

[dxvk] Rework image creation

Uses DxvkResourceAllocation to manage image backing storage,
which will allow invalidating images in the future.
This commit is contained in:
Philip Rebohle 2024-09-26 01:35:34 +02:00 committed by Philip Rebohle
parent d7e1794e29
commit 713b76bea5
8 changed files with 235 additions and 237 deletions

View File

@ -95,7 +95,9 @@ namespace dxvk {
D3D11CommonTexture* texture = GetCommonTexture(m_resource);
Rc<DxvkDevice> dxvkDevice = m_device->GetDXVKDevice();
VkResult vr = dxvkDevice->vkd()->wine_vkAcquireKeyedMutex(dxvkDevice->handle(), texture->GetImage()->memory().memory(), Key, dwMilliseconds);
VkResult vr = dxvkDevice->vkd()->wine_vkAcquireKeyedMutex(
dxvkDevice->handle(), texture->GetImage()->getMemoryInfo().memory, Key, dwMilliseconds);
switch (vr) {
case VK_SUCCESS: return S_OK;
case VK_TIMEOUT: return WAIT_TIMEOUT;
@ -123,9 +125,10 @@ namespace dxvk {
context->WaitForResource(texture->GetImage(), DxvkCsThread::SynchronizeAll, D3D11_MAP_READ_WRITE, 0);
}
return dxvkDevice->vkd()->wine_vkReleaseKeyedMutex(dxvkDevice->handle(), texture->GetImage()->memory().memory(), Key) == VK_SUCCESS
? S_OK
: DXGI_ERROR_INVALID_CALL;
VkResult vr = dxvkDevice->vkd()->wine_vkReleaseKeyedMutex(
dxvkDevice->handle(), texture->GetImage()->getMemoryInfo().memory, Key);
return vr == VK_SUCCESS ? S_OK : DXGI_ERROR_INVALID_CALL;
}
D3D11DXGIResource::D3D11DXGIResource(

View File

@ -556,9 +556,8 @@ namespace dxvk {
for (uint32_t i = 0; i < info.imageCount; i++) {
VkImage imageHandle = m_presenter->getImage(i).image;
Rc<DxvkImage> image = new DxvkImage(
m_device.ptr(), imageInfo, imageHandle,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
Rc<DxvkImage> image = m_device->importImage(imageInfo,
imageHandle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
m_imageViews[i] = new DxvkImageView(
m_device->vkd(), image, viewInfo);

View File

@ -76,7 +76,7 @@ namespace dxvk {
CreateSampleView(0);
if (!IsManaged()) {
m_size = m_image->memory().length();
m_size = m_image->getMemoryInfo().size;
if (!m_device->ChangeReportedMemory(-m_size))
throw DxvkError("D3D9: Reporting out of memory from tracking.");
}

View File

@ -983,9 +983,8 @@ namespace dxvk {
for (uint32_t i = 0; i < info.imageCount; i++) {
VkImage imageHandle = m_wctx->presenter->getImage(i).image;
Rc<DxvkImage> image = new DxvkImage(
m_device.ptr(), imageInfo, imageHandle,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
Rc<DxvkImage> image = m_device->importImage(imageInfo,
imageHandle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
m_wctx->imageViews[i] = new DxvkImageView(
m_device->vkd(), image, viewInfo);

View File

@ -1542,8 +1542,7 @@ namespace dxvk {
// Bind metadata aspects. Since the image was just created,
// we do not need to interrupt our command list for that.
VkDeviceMemory imageMemory = image->memory().memory();
VkDeviceSize imageOffset = image->memory().offset();
DxvkResourceMemoryInfo memoryInfo = image->getMemoryInfo();
for (const auto& r : req) {
if (!(r.formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT))
@ -1560,13 +1559,13 @@ namespace dxvk {
key.flags = VK_SPARSE_MEMORY_BIND_METADATA_BIT;
DxvkResourceMemoryInfo page;
page.memory = imageMemory;
page.offset = imageOffset;
page.memory = memoryInfo.memory;
page.offset = memoryInfo.offset;
page.size = r.imageMipTailSize;
m_cmd->bindImageOpaqueMemory(key, page);
imageOffset += r.imageMipTailSize;
memoryInfo.offset += r.imageMipTailSize;
}
}

View File

@ -227,7 +227,8 @@ namespace dxvk {
const DxvkImageCreateInfo& createInfo,
VkImage image,
VkMemoryPropertyFlags memoryType) {
return new DxvkImage(this, createInfo, image, memoryType);
return new DxvkImage(this, createInfo, image,
m_objects.memoryManager(), memoryType);
}

View File

@ -9,159 +9,153 @@ namespace dxvk {
const DxvkImageCreateInfo& createInfo,
DxvkMemoryAllocator& memAlloc,
VkMemoryPropertyFlags memFlags)
: m_vkd(device->vkd()), m_device(device), m_info(createInfo), m_memFlags(memFlags) {
: m_vkd(device->vkd()), m_allocator(&memAlloc), m_properties(memFlags), m_info(createInfo) {
copyFormatList(createInfo.viewFormatCount, createInfo.viewFormats);
// Copy the compatible view formats to a persistent array
m_viewFormats.resize(createInfo.viewFormatCount);
for (uint32_t i = 0; i < createInfo.viewFormatCount; i++)
m_viewFormats[i] = createInfo.viewFormats[i];
m_info.viewFormats = m_viewFormats.data();
// Determine whether the image is shareable before creating the resource
VkImageCreateInfo imageInfo = getImageCreateInfo();
m_shared = canShareImage(device, imageInfo, m_info.sharing);
// If defined, we should provide a format list, which
// allows some drivers to enable image compression
VkImageFormatListCreateInfo formatList = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO };
formatList.viewFormatCount = createInfo.viewFormatCount;
formatList.pViewFormats = createInfo.viewFormats;
VkExternalMemoryImageCreateInfo externalInfo = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO };
externalInfo.handleTypes = createInfo.sharing.type;
VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, &formatList };
info.flags = createInfo.flags;
info.imageType = createInfo.type;
info.format = createInfo.format;
info.extent = createInfo.extent;
info.mipLevels = createInfo.mipLevels;
info.arrayLayers = createInfo.numLayers;
info.samples = createInfo.sampleCount;
info.tiling = createInfo.tiling;
info.usage = createInfo.usage;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.initialLayout = createInfo.initialLayout;
if ((m_shared = canShareImage(info, createInfo.sharing)))
externalInfo.pNext = std::exchange(info.pNext, &externalInfo);
if (m_vkd->vkCreateImage(m_vkd->device(), &info, nullptr, &m_image.image)) {
throw DxvkError(str::format(
"DxvkImage: Failed to create image:",
"\n Type: ", info.imageType,
"\n Format: ", info.format,
"\n Flags: ", info.flags,
"\n Extent: ", "(", info.extent.width,
",", info.extent.height,
",", info.extent.depth, ")",
"\n Mip levels: ", info.mipLevels,
"\n Array layers: ", info.arrayLayers,
"\n Samples: ", info.samples,
"\n Usage: ", info.usage,
"\n Tiling: ", info.tiling));
}
VkImageMemoryRequirementsInfo2 memoryRequirementInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 };
memoryRequirementInfo.image = m_image.image;
if (!(info.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
// Get memory requirements for the image and ask driver
// whether we need to use a dedicated allocation.
DxvkMemoryRequirements memoryRequirements = { };
memoryRequirements.tiling = info.tiling;
memoryRequirements.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS };
memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &memoryRequirements.dedicated };
m_vkd->vkGetImageMemoryRequirements2(m_vkd->device(),
&memoryRequirementInfo, &memoryRequirements.core);
// Fill in desired memory properties
DxvkMemoryProperties memoryProperties = { };
memoryProperties.flags = m_memFlags;
if (memoryRequirements.dedicated.prefersDedicatedAllocation || m_shared) {
memoryProperties.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO };
memoryProperties.dedicated.image = m_image.image;
}
if (m_shared) {
memoryRequirements.dedicated.prefersDedicatedAllocation = VK_TRUE;
memoryRequirements.dedicated.requiresDedicatedAllocation = VK_TRUE;
if (createInfo.sharing.mode == DxvkSharedHandleMode::Export) {
memoryProperties.sharedExport = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO };
memoryProperties.sharedExport.pNext = std::exchange(memoryProperties.dedicated.pNext, &memoryProperties.sharedExport);
memoryProperties.sharedExport.handleTypes = createInfo.sharing.type;
}
if (createInfo.sharing.mode == DxvkSharedHandleMode::Import) {
memoryProperties.sharedImportWin32 = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR };
memoryProperties.sharedImportWin32.pNext = std::exchange(memoryProperties.dedicated.pNext, &memoryProperties.sharedImportWin32);
memoryProperties.sharedImportWin32.handleType = createInfo.sharing.type;
memoryProperties.sharedImportWin32.handle = createInfo.sharing.handle;
}
}
m_image.memory = memAlloc.alloc(memoryRequirements, memoryProperties);
// Try to bind the allocated memory slice to the image
if (m_vkd->vkBindImageMemory(m_vkd->device(), m_image.image,
m_image.memory.memory(), m_image.memory.offset()) != VK_SUCCESS)
throw DxvkError("DxvkImage::DxvkImage: Failed to bind device memory");
} else {
// Initialize sparse info. We do not immediately bind the metadata
// aspects of the image here, the caller needs to explicitly do that.
m_sparsePageTable = DxvkSparsePageTable(device, info, m_image.image);
// Allocate memory for sparse metadata if necessary
auto properties = m_sparsePageTable.getProperties();
if (properties.metadataPageCount) {
DxvkMemoryRequirements memoryRequirements = { };
memoryRequirements.tiling = VK_IMAGE_TILING_OPTIMAL;
memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 };
m_vkd->vkGetImageMemoryRequirements2(m_vkd->device(),
&memoryRequirementInfo, &memoryRequirements.core);
DxvkMemoryProperties memoryProperties = { };
memoryProperties.flags = m_memFlags;
// Set size and alignment to match the metadata requirements
auto& core = memoryRequirements.core.memoryRequirements;
core.size = SparseMemoryPageSize * properties.metadataPageCount;
core.alignment = SparseMemoryPageSize;
m_image.memory = memAlloc.alloc(memoryRequirements, memoryProperties);
}
}
assignResource(createResource());
}
DxvkImage::DxvkImage(
DxvkDevice* device,
const DxvkImageCreateInfo& info,
VkImage image,
VkImage imageHandle,
DxvkMemoryAllocator& memAlloc,
VkMemoryPropertyFlags memFlags)
: m_vkd(device->vkd()), m_device(device), m_info(info), m_memFlags(memFlags), m_image({ image }) {
m_viewFormats.resize(info.viewFormatCount);
for (uint32_t i = 0; i < info.viewFormatCount; i++)
m_viewFormats[i] = info.viewFormats[i];
: m_vkd(device->vkd()), m_allocator(&memAlloc), m_properties(memFlags), m_info(info) {
copyFormatList(info.viewFormatCount, info.viewFormats);
// Create backing storage for existing image resource
VkImageCreateInfo imageInfo = getImageCreateInfo();
assignResource(m_allocator->importImageResource(imageInfo, imageHandle));
}
DxvkImage::~DxvkImage() {
}
VkSubresourceLayout DxvkImage::querySubresourceLayout(
const VkImageSubresource& subresource) const {
VkSubresourceLayout result = { };
m_vkd->vkGetImageSubresourceLayout(m_vkd->device(),
m_imageInfo.image, &subresource, &result);
return result;
}
HANDLE DxvkImage::sharedHandle() const {
HANDLE handle = INVALID_HANDLE_VALUE;
if (!m_shared)
return INVALID_HANDLE_VALUE;
#ifdef _WIN32
DxvkResourceMemoryInfo memoryInfo = m_storage->getMemoryInfo();
VkMemoryGetWin32HandleInfoKHR handleInfo = { VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR };
handleInfo.handleType = m_info.sharing.type;
handleInfo.memory = memoryInfo.memory;
if (m_vkd->vkGetMemoryWin32HandleKHR(m_vkd->device(), &handleInfo, &handle) != VK_SUCCESS)
Logger::warn("DxvkImage::DxvkImage: Failed to get shared handle for image");
#endif
return handle;
}
DxvkSparsePageTable* DxvkImage::getSparsePageTable() {
return m_storage->getSparsePageTable();
}
Rc<DxvkResourceAllocation> DxvkImage::createResource() {
const DxvkFormatInfo* formatInfo = lookupFormatInfo(m_info.format);
VkImageCreateInfo imageInfo = getImageCreateInfo();
// Set up view format list so that drivers can better enable
// compression. Skip for planar formats due to validation errors.
VkImageFormatListCreateInfo formatList = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO };
if (!(formatInfo->aspectMask & VK_IMAGE_ASPECT_PLANE_0_BIT)) {
formatList.viewFormatCount = m_info.viewFormatCount;
formatList.pViewFormats = m_info.viewFormats;
}
if ((m_info.flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && formatList.viewFormatCount)
formatList.pNext = std::exchange(imageInfo.pNext, &formatList);
// Set up external memory parameters for shared images
VkExternalMemoryImageCreateInfo externalInfo = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO };
if (m_shared) {
externalInfo.pNext = std::exchange(imageInfo.pNext, &externalInfo);
externalInfo.handleTypes = m_info.sharing.type;
}
// Set up shared memory properties
void* sharedMemoryInfo = nullptr;
VkExportMemoryAllocateInfo sharedExport = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO };
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);
sharedExport.handleTypes = m_info.sharing.type;
}
if (m_shared && m_info.sharing.mode == DxvkSharedHandleMode::Import) {
sharedImportWin32.pNext = std::exchange(sharedMemoryInfo, &sharedImportWin32);
sharedImportWin32.handleType = m_info.sharing.type;
sharedImportWin32.handle = m_info.sharing.handle;
}
return m_allocator->createImageResource(imageInfo, m_properties, sharedMemoryInfo);
}
VkImageCreateInfo DxvkImage::getImageCreateInfo() const {
VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
info.flags = m_info.flags;
info.imageType = m_info.type;
info.format = m_info.format;
info.extent = m_info.extent;
info.mipLevels = m_info.mipLevels;
info.arrayLayers = m_info.numLayers;
info.samples = m_info.sampleCount;
info.tiling = m_info.tiling;
info.usage = m_info.usage;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.initialLayout = m_info.initialLayout;
return info;
}
void DxvkImage::copyFormatList(uint32_t formatCount, const VkFormat* formats) {
m_viewFormats.resize(formatCount);
for (uint32_t i = 0; i < formatCount; i++)
m_viewFormats[i] = formats[i];
m_info.viewFormats = m_viewFormats.data();
}
DxvkImage::~DxvkImage() {
// This is a bit of a hack to determine whether
// the image is implementation-handled or not
if ((m_image.memory.memory())
|| (m_info.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT))
m_vkd->vkDestroyImage(m_vkd->device(), m_image.image, nullptr);
}
bool DxvkImage::canShareImage(const VkImageCreateInfo& createInfo, const DxvkSharedHandleInfo& sharingInfo) const {
bool DxvkImage::canShareImage(DxvkDevice* device, const VkImageCreateInfo& createInfo, const DxvkSharedHandleInfo& sharingInfo) const {
if (sharingInfo.mode == DxvkSharedHandleMode::None)
return false;
if (!m_device->features().khrExternalMemoryWin32) {
if (!device->features().khrExternalMemoryWin32) {
Logger::err("Failed to create shared resource: VK_KHR_EXTERNAL_MEMORY_WIN32 not supported");
return false;
}
@ -179,7 +173,7 @@ namespace dxvk {
formatQuery.flags = createInfo.flags;
formatQuery.handleType = sharingInfo.type;
auto limits = m_device->getFormatLimits(formatQuery);
auto limits = device->getFormatLimits(formatQuery);
if (!limits)
return false;
@ -197,27 +191,7 @@ namespace dxvk {
}
HANDLE DxvkImage::sharedHandle() const {
HANDLE handle = INVALID_HANDLE_VALUE;
if (!m_shared)
return INVALID_HANDLE_VALUE;
#ifdef _WIN32
VkMemoryGetWin32HandleInfoKHR handleInfo = { VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR };
handleInfo.handleType = m_info.sharing.type;
handleInfo.memory = m_image.memory.memory();
if (m_vkd->vkGetMemoryWin32HandleKHR(m_vkd->device(), &handleInfo, &handle) != VK_SUCCESS)
Logger::warn("DxvkImage::DxvkImage: Failed to get shared handle for image");
#endif
return handle;
}
DxvkSparsePageTable* DxvkImage::getSparsePageTable() {
return &m_sparsePageTable;
}
DxvkImageView::DxvkImageView(

View File

@ -19,41 +19,41 @@ namespace dxvk {
*/
struct DxvkImageCreateInfo {
/// Image dimension
VkImageType type;
VkImageType type = VK_IMAGE_TYPE_2D;
/// Pixel format
VkFormat format;
VkFormat format = VK_FORMAT_UNDEFINED;
/// Flags
VkImageCreateFlags flags;
VkImageCreateFlags flags = 0u;
/// Sample count for MSAA
VkSampleCountFlagBits sampleCount;
VkSampleCountFlagBits sampleCount = VkSampleCountFlagBits(0u);
/// Image size, in texels
VkExtent3D extent;
VkExtent3D extent = { };
/// Number of image array layers
uint32_t numLayers;
uint32_t numLayers = 0u;
/// Number of mip levels
uint32_t mipLevels;
uint32_t mipLevels = 0u;
/// Image usage flags
VkImageUsageFlags usage;
VkImageUsageFlags usage = 0u;
/// Pipeline stages that can access
/// the contents of the image
VkPipelineStageFlags stages;
VkPipelineStageFlags stages = 0u;
/// Allowed access pattern
VkAccessFlags access;
VkAccessFlags access = 0u;
/// Image tiling mode
VkImageTiling tiling;
VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
/// Common image layout
VkImageLayout layout;
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
// Initial image layout
VkImageLayout initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
@ -64,11 +64,11 @@ namespace dxvk {
// Image view formats that can
// be used with this image
uint32_t viewFormatCount = 0;
const VkFormat* viewFormats = nullptr;
uint32_t viewFormatCount = 0;
const VkFormat* viewFormats = nullptr;
// Shared handle info
DxvkSharedHandleInfo sharing;
DxvkSharedHandleInfo sharing = { };
};
@ -104,19 +104,10 @@ namespace dxvk {
VK_COMPONENT_SWIZZLE_IDENTITY,
};
};
/**
* \brief Stores an image and its memory slice.
*/
struct DxvkPhysicalImage {
VkImage image = VK_NULL_HANDLE;
DxvkMemory memory;
};
/**
* \brief DXVK image
* \brief Virtual image resource
*
* An image resource consisting of various subresources.
* Can be accessed by the host if allocated on a suitable
@ -143,8 +134,9 @@ namespace dxvk {
*/
DxvkImage(
DxvkDevice* device,
const DxvkImageCreateInfo& info,
VkImage image,
const DxvkImageCreateInfo& createInfo,
VkImage imageHandle,
DxvkMemoryAllocator& memAlloc,
VkMemoryPropertyFlags memFlags);
/**
@ -162,7 +154,7 @@ namespace dxvk {
* \returns Image handle
*/
VkImage handle() const {
return m_image.image;
return m_imageInfo.image;
}
/**
@ -183,7 +175,7 @@ namespace dxvk {
* \returns Vulkan memory flags
*/
VkMemoryPropertyFlags memFlags() const {
return m_memFlags;
return m_properties;
}
/**
@ -196,7 +188,7 @@ namespace dxvk {
* \returns Pointer to mapped memory region
*/
void* mapPtr(VkDeviceSize offset) const {
return m_image.memory.mapPtr(offset);
return reinterpret_cast<char*>(m_imageInfo.mapPtr) + offset;
}
/**
@ -227,23 +219,6 @@ namespace dxvk {
return util::computeMipLevelExtent(m_info.extent, level, m_info.format, aspect);
}
/**
* \brief Queries memory layout of a subresource
*
* Can be used to retrieve the exact pointer to a
* subresource of a mapped image with linear tiling.
* \param [in] subresource The image subresource
* \returns Memory layout of that subresource
*/
VkSubresourceLayout querySubresourceLayout(
const VkImageSubresource& subresource) const {
VkSubresourceLayout result;
m_vkd->vkGetImageSubresourceLayout(
m_vkd->device(), m_image.image,
&subresource, &result);
return result;
}
/**
* \brief Picks a compatible layout
*
@ -306,8 +281,8 @@ namespace dxvk {
* \brief Memory object
* \returns Backing memory
*/
const DxvkMemory& memory() const {
return m_image.memory;
DxvkResourceMemoryInfo getMemoryInfo() const {
return m_storage->getMemoryInfo();
}
/**
@ -325,6 +300,17 @@ namespace dxvk {
return result;
}
/**
* \brief Queries memory layout of a subresource
*
* Can be used to retrieve the exact pointer to a
* subresource of a mapped image with linear tiling.
* \param [in] subresource The image subresource
* \returns Memory layout of that subresource
*/
VkSubresourceLayout querySubresourceLayout(
const VkImageSubresource& subresource) const;
/**
* \brief Create a new shared handle to dedicated memory backing the image
* \returns The shared handle with the type given by DxvkSharedHandleInfo::type
@ -337,21 +323,58 @@ namespace dxvk {
*/
DxvkSparsePageTable* getSparsePageTable();
/**
* \brief Creates image resource
*
* The returned image can be used as backing storage.
* \returns New underlying image resource
*/
Rc<DxvkResourceAllocation> createResource();
/**
* \brief Assigns backing storage to the image
*
* Implicitly invalidates all image views.
* \param [in] resource New backing storage
* \returns Previous backing storage
*/
Rc<DxvkResourceAllocation> assignResource(Rc<DxvkResourceAllocation>&& resource) {
Rc<DxvkResourceAllocation> old = std::move(m_storage);
m_storage = std::move(resource);
m_imageInfo = m_storage->getImageInfo();
m_version += 1u;
return old;
}
private:
Rc<vk::DeviceFn> m_vkd;
const DxvkDevice* m_device;
DxvkImageCreateInfo m_info;
VkMemoryPropertyFlags m_memFlags;
DxvkPhysicalImage m_image;
DxvkSparsePageTable m_sparsePageTable;
Rc<vk::DeviceFn> m_vkd;
DxvkMemoryAllocator* m_allocator = nullptr;
VkMemoryPropertyFlags m_properties = 0u;
bool m_shared = false;
DxvkImageCreateInfo m_info = { };
small_vector<VkFormat, 4> m_viewFormats;
bool canShareImage(const VkImageCreateInfo& createInfo, const DxvkSharedHandleInfo& sharingInfo) const;
uint32_t m_version = 0u;
VkBool32 m_shared = VK_FALSE;
DxvkResourceImageInfo m_imageInfo = { };
Rc<DxvkResourceAllocation> m_storage = nullptr;
small_vector<VkFormat, 4> m_viewFormats;
VkImageCreateInfo getImageCreateInfo() const;
void copyFormatList(
uint32_t formatCount,
const VkFormat* formats);
bool canShareImage(
DxvkDevice* device,
const VkImageCreateInfo& createInfo,
const DxvkSharedHandleInfo& sharingInfo) const;
};