1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-20 08:52:22 +01:00

[dxvk] Add functions for image subresource initialization tracking

This commit is contained in:
Philip Rebohle 2024-10-12 15:26:28 +02:00 committed by Philip Rebohle
parent af4ec3c63d
commit 255e7b7d7a
2 changed files with 74 additions and 0 deletions

View File

@ -26,6 +26,9 @@ namespace dxvk {
VkImageCreateInfo imageInfo = getImageCreateInfo(DxvkImageUsageInfo());
m_shared = canShareImage(device, imageInfo, m_info.sharing);
if (m_info.sharing.mode != DxvkSharedHandleMode::Import)
m_uninitializedSubresourceCount = m_info.numLayers * m_info.mipLevels;
assignResource(createResource());
}
@ -218,6 +221,56 @@ namespace dxvk {
}
void DxvkImage::trackInitialization(
const VkImageSubresourceRange& subresources) {
if (!m_uninitializedSubresourceCount)
return;
if (subresources.levelCount == m_info.mipLevels && subresources.layerCount == m_info.numLayers) {
// Trivial case, everything gets initialized at once
m_uninitializedSubresourceCount = 0u;
m_uninitializedMipsPerLayer.clear();
} else {
// Partial initialization. Track each layer individually.
if (m_uninitializedMipsPerLayer.empty()) {
m_uninitializedMipsPerLayer.resize(m_info.numLayers);
for (uint32_t i = 0; i < m_info.numLayers; i++)
m_uninitializedMipsPerLayer[i] = uint16_t(1u << m_info.mipLevels) - 1u;
}
uint16_t mipMask = ((1u << subresources.levelCount) - 1u) << subresources.baseMipLevel;
for (uint32_t i = subresources.baseArrayLayer; i < subresources.baseArrayLayer + subresources.layerCount; i++) {
m_uninitializedSubresourceCount -= bit::popcnt(m_uninitializedMipsPerLayer[i] & mipMask);
m_uninitializedMipsPerLayer[i] &= ~mipMask;
}
if (!m_uninitializedSubresourceCount)
m_uninitializedMipsPerLayer.clear();
}
}
bool DxvkImage::isInitialized(
const VkImageSubresourceRange& subresources) const {
if (likely(!m_uninitializedSubresourceCount))
return true;
if (m_uninitializedMipsPerLayer.empty())
return false;
uint16_t mipMask = ((1u << subresources.levelCount) - 1u) << subresources.baseMipLevel;
for (uint32_t i = 0; i < subresources.layerCount; i++) {
if (m_uninitializedMipsPerLayer[subresources.baseArrayLayer + i] & mipMask)
return false;
}
return true;
}
VkImageCreateInfo DxvkImage::getImageCreateInfo(
const DxvkImageUsageInfo& usageInfo) const {
VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };

View File

@ -583,6 +583,25 @@ namespace dxvk {
Rc<DxvkImageView> createView(
const DxvkImageViewKey& info);
/**
* \brief Tracks subresource initialization
*
* Initialization happens when transitioning the image
* away from \c PREINITIALIZED or \c UNDEFINED layouts.
* \param [in] subresources Subresource range
*/
void trackInitialization(
const VkImageSubresourceRange& subresources);
/**
* \brief Checks whether subresources are initialized
*
* \param [in] subresources Subresource range
* \returns \c true if the subresources are initialized
*/
bool isInitialized(
const VkImageSubresourceRange& subresources) const;
private:
Rc<vk::DeviceFn> m_vkd;
@ -601,6 +620,8 @@ namespace dxvk {
Rc<DxvkResourceAllocation> m_storage = nullptr;
small_vector<VkFormat, 4> m_viewFormats;
small_vector<uint16_t, 8> m_uninitializedMipsPerLayer = { };
uint32_t m_uninitializedSubresourceCount = 0u;
dxvk::mutex m_viewMutex;
std::unordered_map<DxvkImageViewKey,