Commit d77e85a8 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Store image updates per level

This optimization allows iterating only over updates of a certain level or range of levels, instead of having to iterate over every update and filter out the ones matching the desired level(s). Bug: angleproject:4891 Change-Id: Ied04f4b28f05d37b9add61c7f4d54cc328c0be86 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2519095Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent d30f0114
......@@ -253,11 +253,12 @@ angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk,
// below will either flush all staged updates to the resolve image, or if the only staged update
// is a clear, it will accumulate it in the |deferredClears| array. Later, when the render pass
// is started, the deferred clears are applied to the transient multisampled image.
ASSERT(!isResolveImageOwnerOfData() || !mImage->isUpdateStaged(mLevelIndexGL, layerIndex));
ASSERT(!isResolveImageOwnerOfData() ||
!mImage->hasStagedUpdatesForSubresource(mLevelIndexGL, layerIndex));
ASSERT(isResolveImageOwnerOfData() || mResolveImage == nullptr ||
!mResolveImage->isUpdateStaged(mLevelIndexGL, layerIndex));
!mResolveImage->hasStagedUpdatesForSubresource(mLevelIndexGL, layerIndex));
if (!image->isUpdateStaged(mLevelIndexGL, layerIndex))
if (!image->hasStagedUpdatesForSubresource(mLevelIndexGL, layerIndex))
{
return angle::Result::Continue;
}
......
......@@ -140,7 +140,8 @@ angle::Result SemaphoreVk::wait(gl::Context *context,
// Image should not be accessed while unowned. Emulated formats may have staged updates
// to clear the image after initialization.
ASSERT(!image.hasStagedUpdates() || image.getFormat().hasEmulatedImageChannels());
ASSERT(!image.hasStagedUpdatesInAllocatedLevels() ||
image.getFormat().hasEmulatedImageChannels());
// Queue ownership transfer and layout transition.
image.acquireFromExternal(contextVk, VK_QUEUE_FAMILY_EXTERNAL, rendererQueueFamilyIndex,
......
......@@ -1550,7 +1550,7 @@ VkResult WindowSurfaceVk::acquireNextSwapchainImage(vk::Context *context)
}
// Notify the owning framebuffer there may be staged updates.
if (image.image.hasStagedUpdates())
if (image.image.hasStagedUpdatesInAllocatedLevels())
{
onStateChange(angle::SubjectMessage::SubjectChanged);
}
......
......@@ -1841,7 +1841,7 @@ angle::Result TextureVk::respecifyImageStorageAndLevels(ContextVk *contextVk,
{
// Recreate the image to reflect new base or max levels.
// First, flush any pending updates so we have good data in the existing vkImage
if (mImage->valid() && mImage->hasStagedUpdates())
if (mImage->valid() && mImage->hasStagedUpdatesInAllocatedLevels())
{
ANGLE_TRY(flushImageStagedUpdates(contextVk));
}
......@@ -1873,11 +1873,11 @@ angle::Result TextureVk::respecifyImageStorageAndLevels(ContextVk *contextVk,
{
// Note: if this level is incompatibly redefined, there will necessarily be a staged
// update, and the contents of the image are to be thrown away.
ASSERT(mImage->isUpdateStaged(levelGL, layer));
ASSERT(mImage->hasStagedUpdatesForSubresource(levelGL, layer));
continue;
}
ASSERT(!mImage->isUpdateStaged(levelGL, layer));
ASSERT(!mImage->hasStagedUpdatesForSubresource(levelGL, layer));
// Pull data from the current image and stage it as an update for the new image
......@@ -1987,7 +1987,7 @@ angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context,
angle::Result TextureVk::ensureImageInitialized(ContextVk *contextVk, ImageMipLevels mipLevels)
{
if (mImage->valid() && !mImage->hasStagedUpdates())
if (mImage->valid() && !mImage->hasStagedUpdatesInAllocatedLevels())
{
return angle::Result::Continue;
}
......
......@@ -1537,8 +1537,8 @@ class ImageHelper final : public Resource, public angle::Subject
// as with renderbuffers or surface images.
angle::Result flushAllStagedUpdates(ContextVk *contextVk);
bool isUpdateStaged(gl::LevelIndex levelGL, uint32_t layer);
bool hasStagedUpdates() const { return !mSubresourceUpdates.empty(); }
bool hasStagedUpdatesForSubresource(gl::LevelIndex levelGL, uint32_t layer) const;
bool hasStagedUpdatesInAllocatedLevels() const;
void recordWriteBarrier(VkImageAspectFlags aspectMask,
ImageLayout newLayout,
......@@ -1717,9 +1717,8 @@ class ImageHelper final : public Resource, public angle::Subject
void release(RendererVk *renderer);
bool isUpdateToLayerLevel(uint32_t layerIndex, gl::LevelIndex levelIndexGL) const;
bool isUpdateToLayer(uint32_t layerIndex) const;
void getDestSubresource(uint32_t imageLayerCount,
gl::LevelIndex *levelIndexGLOut,
uint32_t *baseLayerOut,
uint32_t *layerCountOut) const;
VkImageAspectFlags getDestAspectFlags() const;
......@@ -1771,8 +1770,14 @@ class ImageHelper final : public Resource, public angle::Subject
angle::Result initializeNonZeroMemory(Context *context, VkDeviceSize size);
void appendSubresourceUpdate(SubresourceUpdate &&update);
void prependSubresourceUpdate(SubresourceUpdate &&update);
std::vector<SubresourceUpdate> *getLevelUpdates(gl::LevelIndex level);
const std::vector<SubresourceUpdate> *getLevelUpdates(gl::LevelIndex level) const;
void appendSubresourceUpdate(gl::LevelIndex level, SubresourceUpdate &&update);
void prependSubresourceUpdate(gl::LevelIndex level, SubresourceUpdate &&update);
// Whether there are any updates in [start, end).
bool hasStagedUpdatesInLevels(gl::LevelIndex levelStart, gl::LevelIndex levelEnd) const;
void resetCachedProperties();
void setEntireContentDefined();
void setEntireContentUndefined();
......@@ -1846,7 +1851,7 @@ class ImageHelper final : public Resource, public angle::Subject
// Staging buffer
DynamicBuffer mStagingBuffer;
std::vector<SubresourceUpdate> mSubresourceUpdates;
std::vector<std::vector<SubresourceUpdate>> mSubresourceUpdates;
// Optimization for repeated clear with the same value. If this pointer is not null, the entire
// image it has been cleared to the specified clear value. If another clear call is made with
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment