1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-02 01:24:11 +01:00

[dxvk] Refactor sparse page table initialization for images

This commit is contained in:
Philip Rebohle 2024-09-25 22:26:23 +02:00 committed by Philip Rebohle
parent 0f23a17d8f
commit bcd12a5b56
3 changed files with 37 additions and 33 deletions

View File

@ -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();

View File

@ -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<VkSparseImageMemoryRequirements> 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;
}

View File

@ -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<DxvkSparseImageSubresourceProperties> m_subresources;