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:
parent
0f23a17d8f
commit
bcd12a5b56
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user