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:
parent
af4ec3c63d
commit
255e7b7d7a
@ -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 };
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user