Vulkan: use one barrier if we can for non-pass operations
When we do transition barriers for a texture view outside of a pass (say copy, clear, initialization), if the texture view can cover all subresources, and its old usages across all subresources are the same, then we can use one transition barrier. We don't need to use separate barrier per each subresource. This patch can reduce barrier we delivered, and improve performance for particular situations. Bug: dawn:441 Change-Id: I2ae9b39793915553cbaaceacaf58bf87c9ba3bc6 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/23129 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Yunchao He <yunchao.he@intel.com>
This commit is contained in:
parent
f87b62a904
commit
4fd4aa1f19
|
@ -807,22 +807,41 @@ namespace dawn_native { namespace vulkan {
|
||||||
const Format& format = GetFormat();
|
const Format& format = GetFormat();
|
||||||
|
|
||||||
wgpu::TextureUsage allLastUsages = wgpu::TextureUsage::None;
|
wgpu::TextureUsage allLastUsages = wgpu::TextureUsage::None;
|
||||||
|
uint32_t subresourceCount = GetSubresourceCount();
|
||||||
|
|
||||||
// This transitions assume it is a 2D texture
|
// This transitions assume it is a 2D texture
|
||||||
ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
|
ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
|
||||||
|
|
||||||
for (uint32_t layer = baseArrayLayer; layer < baseArrayLayer + layerCount; ++layer) {
|
// If the usages transitions can cover all subresources, and old usages of all subresources
|
||||||
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) {
|
// are the same, then we can use one barrier to do state transition for all subresources.
|
||||||
uint32_t index = GetSubresourceIndex(level, layer);
|
// Note that if the texture has only one mip level and one array slice, it will fall into
|
||||||
|
// this category.
|
||||||
|
bool isAllSubresourcesCovered = levelCount * layerCount == subresourceCount;
|
||||||
|
if (mSameLastUsagesAcrossSubresources && isAllSubresourcesCovered) {
|
||||||
|
ASSERT(baseMipLevel == 0 && baseArrayLayer == 0);
|
||||||
|
if (CanReuseWithoutBarrier(mSubresourceLastUsages[0], usage)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
barriers.push_back(BuildMemoryBarrier(format, mHandle, mSubresourceLastUsages[0], usage,
|
||||||
|
0, levelCount, 0, layerCount));
|
||||||
|
allLastUsages = mSubresourceLastUsages[0];
|
||||||
|
for (uint32_t i = 0; i < subresourceCount; ++i) {
|
||||||
|
mSubresourceLastUsages[i] = usage;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (uint32_t layer = baseArrayLayer; layer < baseArrayLayer + layerCount; ++layer) {
|
||||||
|
for (uint32_t level = baseMipLevel; level < baseMipLevel + levelCount; ++level) {
|
||||||
|
uint32_t index = GetSubresourceIndex(level, layer);
|
||||||
|
|
||||||
if (CanReuseWithoutBarrier(mSubresourceLastUsages[index], usage)) {
|
if (CanReuseWithoutBarrier(mSubresourceLastUsages[index], usage)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
barriers.push_back(BuildMemoryBarrier(
|
||||||
|
format, mHandle, mSubresourceLastUsages[index], usage, level, 1, layer, 1));
|
||||||
|
allLastUsages |= mSubresourceLastUsages[index];
|
||||||
|
mSubresourceLastUsages[index] = usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
barriers.push_back(BuildMemoryBarrier(
|
|
||||||
format, mHandle, mSubresourceLastUsages[index], usage, level, 1, layer, 1));
|
|
||||||
allLastUsages |= mSubresourceLastUsages[index];
|
|
||||||
mSubresourceLastUsages[index] = usage;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,9 +855,7 @@ namespace dawn_native { namespace vulkan {
|
||||||
->fn.CmdPipelineBarrier(recordingContext->commandBuffer, srcStages, dstStages, 0, 0,
|
->fn.CmdPipelineBarrier(recordingContext->commandBuffer, srcStages, dstStages, 0, 0,
|
||||||
nullptr, 0, nullptr, barriers.size(), barriers.data());
|
nullptr, 0, nullptr, barriers.size(), barriers.data());
|
||||||
|
|
||||||
// TODO(yunchao.he@intel.com): do the optimization to combine all barriers into a single one
|
mSameLastUsagesAcrossSubresources = isAllSubresourcesCovered;
|
||||||
// for a texture if possible.
|
|
||||||
mSameLastUsagesAcrossSubresources = levelCount * layerCount == GetSubresourceCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError Texture::ClearTexture(CommandRecordingContext* recordingContext,
|
MaybeError Texture::ClearTexture(CommandRecordingContext* recordingContext,
|
||||||
|
|
Loading…
Reference in New Issue