diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index 238741fa..168cd6b9 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -108,7 +108,7 @@ namespace dxvk { } 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, this); + m_sparsePageTable = DxvkSparsePageTable(device, info, m_image.image); // Allocate memory for sparse metadata if necessary auto properties = m_sparsePageTable.getProperties(); diff --git a/src/dxvk/dxvk_sparse.cpp b/src/dxvk/dxvk_sparse.cpp index 5d61301b..48867689 100644 --- a/src/dxvk/dxvk_sparse.cpp +++ b/src/dxvk/dxvk_sparse.cpp @@ -192,16 +192,17 @@ namespace dxvk { DxvkSparsePageTable::DxvkSparsePageTable( DxvkDevice* device, - const DxvkImage* image) - : m_image(image) { + const VkImageCreateInfo& imageInfo, + VkImage imageHandle) + : m_image(imageHandle) { auto vk = device->vkd(); // Query sparse memory requirements uint32_t reqCount = 0; - vk->vkGetImageSparseMemoryRequirements(vk->device(), image->handle(), &reqCount, nullptr); + vk->vkGetImageSparseMemoryRequirements(vk->device(), imageHandle, &reqCount, nullptr); std::vector req(reqCount); - vk->vkGetImageSparseMemoryRequirements(vk->device(), image->handle(), &reqCount, req.data()); + vk->vkGetImageSparseMemoryRequirements(vk->device(), imageHandle, &reqCount, req.data()); // Find first non-metadata struct and use it to fill in the image properties bool foundMainAspect = false; @@ -211,52 +212,53 @@ namespace dxvk { VkDeviceSize metadataSize = r.imageMipTailSize; if (!(r.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT)) - metadataSize *= m_image->info().numLayers; + metadataSize *= imageInfo.arrayLayers; m_properties.metadataPageCount += uint32_t(metadataSize / SparseMemoryPageSize); } else if (!foundMainAspect) { m_properties.flags = r.formatProperties.flags; m_properties.pageRegionExtent = r.formatProperties.imageGranularity; - if (r.imageMipTailFirstLod < image->info().mipLevels && r.imageMipTailSize) { + if (r.imageMipTailFirstLod < imageInfo.mipLevels && r.imageMipTailSize) { m_properties.pagedMipCount = r.imageMipTailFirstLod; m_properties.mipTailOffset = r.imageMipTailOffset; m_properties.mipTailSize = r.imageMipTailSize; m_properties.mipTailStride = r.imageMipTailStride; } else { - m_properties.pagedMipCount = image->info().mipLevels; + m_properties.pagedMipCount = imageInfo.mipLevels; } foundMainAspect = true; } else { Logger::err(str::format("Found multiple aspects for sparse image:" - "\n Type: ", image->info().type, - "\n Format: ", image->info().format, - "\n Flags: ", image->info().flags, - "\n Extent: ", "(", image->info().extent.width, - ",", image->info().extent.height, - ",", image->info().extent.depth, ")", - "\n Mip levels: ", image->info().mipLevels, - "\n Array layers: ", image->info().numLayers, - "\n Samples: ", image->info().sampleCount, - "\n Usage: ", image->info().usage, - "\n Tiling: ", image->info().tiling)); + "\n Type: ", imageInfo.imageType, + "\n Format: ", imageInfo.format, + "\n Flags: ", imageInfo.flags, + "\n Extent: ", "(", imageInfo.extent.width, + ",", imageInfo.extent.height, + ",", imageInfo.extent.depth, ")", + "\n Mip levels: ", imageInfo.mipLevels, + "\n Array layers: ", imageInfo.arrayLayers, + "\n Samples: ", imageInfo.samples, + "\n Usage: ", imageInfo.usage, + "\n Tiling: ", imageInfo.tiling)); } } // Fill in subresource metadata and compute page count uint32_t totalPageCount = 0; - uint32_t subresourceCount = image->info().numLayers * image->info().mipLevels; + uint32_t subresourceCount = imageInfo.arrayLayers * imageInfo.mipLevels; m_subresources.reserve(subresourceCount); - for (uint32_t l = 0; l < image->info().numLayers; l++) { - for (uint32_t m = 0; m < image->info().mipLevels; m++) { + for (uint32_t l = 0; l < imageInfo.arrayLayers; l++) { + for (uint32_t m = 0; m < imageInfo.mipLevels; m++) { if (m < m_properties.pagedMipCount) { // Compute block count for current mip based on image properties + VkExtent3D mipExtent = util::computeMipLevelExtent(imageInfo.extent, m); + DxvkSparseImageSubresourceProperties subresourceInfo; subresourceInfo.isMipTail = VK_FALSE; - subresourceInfo.pageCount = util::computeBlockCount( - image->mipLevelExtent(m), m_properties.pageRegionExtent); + subresourceInfo.pageCount = util::computeBlockCount(mipExtent, m_properties.pageRegionExtent); // Advance total page count by number of pages in the subresource subresourceInfo.pageIndex = totalPageCount; @@ -280,7 +282,7 @@ namespace dxvk { uint32_t mipTailPageCount = m_properties.mipTailSize / SparseMemoryPageSize; if (!(m_properties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT)) - mipTailPageCount *= m_image->info().numLayers; + mipTailPageCount *= imageInfo.arrayLayers; totalPageCount += mipTailPageCount; } @@ -289,9 +291,11 @@ namespace dxvk { m_metadata.reserve(totalPageCount); m_mappings.resize(totalPageCount); - for (uint32_t l = 0; l < image->info().numLayers; l++) { + const DxvkFormatInfo* formatInfo = lookupFormatInfo(imageInfo.format); + + for (uint32_t l = 0; l < imageInfo.arrayLayers; l++) { for (uint32_t m = 0; m < m_properties.pagedMipCount; m++) { - VkExtent3D mipExtent = image->mipLevelExtent(m); + VkExtent3D mipExtent = util::computeMipLevelExtent(imageInfo.extent, m); VkExtent3D pageCount = util::computeBlockCount(mipExtent, m_properties.pageRegionExtent); for (uint32_t z = 0; z < pageCount.depth; z++) { @@ -299,7 +303,7 @@ namespace dxvk { for (uint32_t x = 0; x < pageCount.width; x++) { DxvkSparsePageInfo pageInfo; pageInfo.type = DxvkSparsePageType::Image; - pageInfo.image.subresource.aspectMask = image->formatInfo()->aspectMask; + pageInfo.image.subresource.aspectMask = formatInfo->aspectMask; pageInfo.image.subresource.mipLevel = m; pageInfo.image.subresource.arrayLayer = l; pageInfo.image.offset.x = x * m_properties.pageRegionExtent.width; @@ -320,7 +324,7 @@ namespace dxvk { uint32_t layerCount = 1; if (!(m_properties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT)) - layerCount = image->info().numLayers; + layerCount = imageInfo.arrayLayers; for (uint32_t i = 0; i < layerCount; i++) { for (uint32_t j = 0; j < pageCount; j++) { @@ -343,7 +347,7 @@ namespace dxvk { VkImage DxvkSparsePageTable::getImageHandle() const { - return m_image ? m_image->handle() : VK_NULL_HANDLE; + return m_image; } diff --git a/src/dxvk/dxvk_sparse.h b/src/dxvk/dxvk_sparse.h index 0333ea5f..3f4a9764 100644 --- a/src/dxvk/dxvk_sparse.h +++ b/src/dxvk/dxvk_sparse.h @@ -292,7 +292,8 @@ namespace dxvk { DxvkSparsePageTable( DxvkDevice* device, - const DxvkImage* image); + const VkImageCreateInfo& imageInfo, + VkImage imageHandle); /** * \brief Checks whether page table is defined @@ -413,8 +414,7 @@ namespace dxvk { private: VkBuffer m_buffer = VK_NULL_HANDLE; - - const DxvkImage* m_image = nullptr; + VkImage m_image = VK_NULL_HANDLE; DxvkSparseImageProperties m_properties = { }; std::vector m_subresources;