Commit 68591eff by Jamie Madill Committed by Commit Bot

Vulkan: Store ImageView access in the graph.

This will ensure we don't destroy the image views when they are still in use by other Contexts. Bug: angleproject:2464 Change-Id: I1d3ba2ad241250e31ea32873446c4cb23971750d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1843236Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent f939cb63
...@@ -717,7 +717,9 @@ ANGLE_INLINE bool CommandGraphResource::hasChildlessWritingNode() const ...@@ -717,7 +717,9 @@ ANGLE_INLINE bool CommandGraphResource::hasChildlessWritingNode() const
// CommandGraph inlines. // CommandGraph inlines.
ANGLE_INLINE void CommandGraph::onResourceUse(const SharedResourceUse &resourceUse) ANGLE_INLINE void CommandGraph::onResourceUse(const SharedResourceUse &resourceUse)
{ {
ASSERT(!empty()); // Disabled the assert because of difficulties with ImageView references.
// TODO(jmadill): Clean up with graph redesign. http://anglebug.com/4029
// ASSERT(!empty());
SharedResourceUse newUse; SharedResourceUse newUse;
newUse.set(resourceUse); newUse.set(resourceUse);
mResourceUses.emplace_back(std::move(newUse)); mResourceUses.emplace_back(std::move(newUse));
......
...@@ -2959,6 +2959,7 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context, ...@@ -2959,6 +2959,7 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context,
image.changeLayout(aspectFlags, textureLayout, srcLayoutChange); image.changeLayout(aspectFlags, textureLayout, srcLayoutChange);
} }
textureVk->onImageViewGraphAccess(&mCommandGraph);
image.addReadDependency(this, recorder); image.addReadDependency(this, recorder);
mActiveTextures[textureUnit].texture = textureVk; mActiveTextures[textureUnit].texture = textureVk;
......
...@@ -823,6 +823,7 @@ angle::Result FramebufferVk::blit(const gl::Context *context, ...@@ -823,6 +823,7 @@ angle::Result FramebufferVk::blit(const gl::Context *context,
{ {
const vk::ImageView *readImageView = nullptr; const vk::ImageView *readImageView = nullptr;
ANGLE_TRY(readRenderTarget->getImageView(contextVk, &readImageView)); ANGLE_TRY(readRenderTarget->getImageView(contextVk, &readImageView));
readRenderTarget->onImageViewGraphAccess(contextVk);
ANGLE_TRY(utilsVk.colorBlitResolve(contextVk, this, &readRenderTarget->getImage(), ANGLE_TRY(utilsVk.colorBlitResolve(contextVk, this, &readRenderTarget->getImage(),
readImageView, params)); readImageView, params));
} }
...@@ -1578,10 +1579,12 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk, ...@@ -1578,10 +1579,12 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk,
gl::Extents FramebufferVk::getReadImageExtents() const gl::Extents FramebufferVk::getReadImageExtents() const
{ {
ASSERT(getColorReadRenderTarget()->getExtents().width == mState.getDimensions().width); RenderTargetVk *readRenderTarget = mRenderTargetCache.getColorRead(mState);
ASSERT(getColorReadRenderTarget()->getExtents().height == mState.getDimensions().height);
return getColorReadRenderTarget()->getExtents(); ASSERT(readRenderTarget->getExtents().width == mState.getDimensions().width);
ASSERT(readRenderTarget->getExtents().height == mState.getDimensions().height);
return readRenderTarget->getExtents();
} }
gl::Rectangle FramebufferVk::getCompleteRenderArea() const gl::Rectangle FramebufferVk::getCompleteRenderArea() const
......
...@@ -1648,16 +1648,23 @@ angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk) ...@@ -1648,16 +1648,23 @@ angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
VkDescriptorImageInfo &imageInfo = descriptorImageInfo[writeCount]; VkDescriptorImageInfo &imageInfo = descriptorImageInfo[writeCount];
// Use bound sampler object if one present, otherwise use texture's sampler // Use bound sampler object if one present, otherwise use texture's sampler
imageInfo.sampler = (samplerVk != nullptr) ? samplerVk->getSampler().getHandle() const vk::Sampler &sampler =
: textureVk->getSampler().getHandle(); (samplerVk != nullptr) ? samplerVk->getSampler() : textureVk->getSampler();
imageInfo.imageView = textureVk->getReadImageView().getHandle();
imageInfo.sampler = sampler.getHandle();
imageInfo.imageLayout = image.getCurrentLayout(); imageInfo.imageLayout = image.getCurrentLayout();
if (emulateSeamfulCubeMapSampling) if (emulateSeamfulCubeMapSampling)
{ {
// If emulating seamful cubemapping, use the fetch image view. This is basically // If emulating seamful cubemapping, use the fetch image view. This is basically
// the same image view as read, except it's a 2DArray view for cube maps. // the same image view as read, except it's a 2DArray view for cube maps.
imageInfo.imageView = textureVk->getFetchImageView().getHandle(); imageInfo.imageView =
textureVk->getFetchImageViewAndRecordUse(contextVk).getHandle();
}
else
{
imageInfo.imageView =
textureVk->getReadImageViewAndRecordUse(contextVk).getHandle();
} }
VkWriteDescriptorSet &writeInfo = writeDescriptorInfo[writeCount]; VkWriteDescriptorSet &writeInfo = writeDescriptorInfo[writeCount];
......
...@@ -28,7 +28,12 @@ RenderTargetVk::RenderTargetVk(RenderTargetVk &&other) ...@@ -28,7 +28,12 @@ RenderTargetVk::RenderTargetVk(RenderTargetVk &&other)
mImageViews(other.mImageViews), mImageViews(other.mImageViews),
mLevelIndex(other.mLevelIndex), mLevelIndex(other.mLevelIndex),
mLayerIndex(other.mLayerIndex) mLayerIndex(other.mLayerIndex)
{} {
other.mImage = nullptr;
other.mImageViews = nullptr;
other.mLevelIndex = 0;
other.mLayerIndex = 0;
}
void RenderTargetVk::init(vk::ImageHelper *image, void RenderTargetVk::init(vk::ImageHelper *image,
vk::ImageViewHelper *imageViews, vk::ImageViewHelper *imageViews,
...@@ -63,6 +68,8 @@ angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk, ...@@ -63,6 +68,8 @@ angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk,
// Set up dependencies between the RT resource and the Framebuffer. // Set up dependencies between the RT resource and the Framebuffer.
mImage->addWriteDependency(contextVk, framebufferVk); mImage->addWriteDependency(contextVk, framebufferVk);
onImageViewGraphAccess(contextVk);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -82,6 +89,8 @@ angle::Result RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk, ...@@ -82,6 +89,8 @@ angle::Result RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk,
// Set up dependencies between the RT resource and the Framebuffer. // Set up dependencies between the RT resource and the Framebuffer.
mImage->addWriteDependency(contextVk, framebufferVk); mImage->addWriteDependency(contextVk, framebufferVk);
onImageViewGraphAccess(contextVk);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -147,9 +156,8 @@ vk::ImageHelper *RenderTargetVk::getImageForRead(ContextVk *contextVk, ...@@ -147,9 +156,8 @@ vk::ImageHelper *RenderTargetVk::getImageForRead(ContextVk *contextVk,
// However, this needs context to be available here, or all call sites changed // However, this needs context to be available here, or all call sites changed
// to perform the layout transition and set the dependency. // to perform the layout transition and set the dependency.
mImage->addWriteDependency(contextVk, readingResource); mImage->addWriteDependency(contextVk, readingResource);
mImage->changeLayout(mImage->getAspectFlags(), layout, commandBuffer); mImage->changeLayout(mImage->getAspectFlags(), layout, commandBuffer);
onImageViewGraphAccess(contextVk);
return mImage; return mImage;
} }
...@@ -158,6 +166,7 @@ vk::ImageHelper *RenderTargetVk::getImageForWrite(ContextVk *contextVk, ...@@ -158,6 +166,7 @@ vk::ImageHelper *RenderTargetVk::getImageForWrite(ContextVk *contextVk,
{ {
ASSERT(mImage && mImage->valid()); ASSERT(mImage && mImage->valid());
mImage->addWriteDependency(contextVk, writingResource); mImage->addWriteDependency(contextVk, writingResource);
onImageViewGraphAccess(contextVk);
return mImage; return mImage;
} }
...@@ -173,4 +182,8 @@ angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk) ...@@ -173,4 +182,8 @@ angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk)
mLayerIndex + 1, commandBuffer); mLayerIndex + 1, commandBuffer);
} }
void RenderTargetVk::onImageViewGraphAccess(ContextVk *contextVk) const
{
mImageViews->onGraphAccess(contextVk->getCommandGraph());
}
} // namespace rx } // namespace rx
...@@ -82,6 +82,8 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget ...@@ -82,6 +82,8 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
angle::Result flushStagedUpdates(ContextVk *contextVk); angle::Result flushStagedUpdates(ContextVk *contextVk);
void onImageViewGraphAccess(ContextVk *contextVk) const;
private: private:
vk::ImageHelper *mImage; vk::ImageHelper *mImage;
vk::ImageViewHelper *mImageViews; vk::ImageViewHelper *mImageViews;
......
...@@ -210,10 +210,10 @@ void RenderbufferVk::releaseAndDeleteImage(ContextVk *contextVk) ...@@ -210,10 +210,10 @@ void RenderbufferVk::releaseAndDeleteImage(ContextVk *contextVk)
void RenderbufferVk::releaseImage(ContextVk *contextVk) void RenderbufferVk::releaseImage(ContextVk *contextVk)
{ {
RendererVk *renderer = contextVk->getRenderer();
if (mImage && mOwnsImage) if (mImage && mOwnsImage)
{ {
RendererVk *renderer = contextVk->getRenderer();
mImage->releaseImage(renderer); mImage->releaseImage(renderer);
mImage->releaseStagingBuffer(renderer); mImage->releaseStagingBuffer(renderer);
} }
...@@ -222,7 +222,7 @@ void RenderbufferVk::releaseImage(ContextVk *contextVk) ...@@ -222,7 +222,7 @@ void RenderbufferVk::releaseImage(ContextVk *contextVk)
mImage = nullptr; mImage = nullptr;
} }
mImageViews.release(contextVk); mImageViews.release(renderer);
} }
} // namespace rx } // namespace rx
...@@ -170,7 +170,7 @@ class RendererVk : angle::NonCopyable ...@@ -170,7 +170,7 @@ class RendererVk : angle::NonCopyable
CollectGarbage(&sharedGarbage, garbageIn...); CollectGarbage(&sharedGarbage, garbageIn...);
if (!sharedGarbage.empty()) if (!sharedGarbage.empty())
{ {
mSharedGarbage.emplace_back(std::move(*use), std::move(sharedGarbage)); collectGarbage(std::move(*use), std::move(sharedGarbage));
} }
else else
{ {
...@@ -181,6 +181,11 @@ class RendererVk : angle::NonCopyable ...@@ -181,6 +181,11 @@ class RendererVk : angle::NonCopyable
use->init(); use->init();
} }
void collectGarbage(vk::SharedResourceUse &&use, std::vector<vk::GarbageObject> &&sharedGarbage)
{
mSharedGarbage.emplace_back(std::move(use), std::move(sharedGarbage));
}
static constexpr size_t kMaxExtensionNames = 200; static constexpr size_t kMaxExtensionNames = 200;
using ExtensionNameList = angle::FixedVector<const char *, kMaxExtensionNames>; using ExtensionNameList = angle::FixedVector<const char *, kMaxExtensionNames>;
......
...@@ -171,7 +171,11 @@ OffscreenSurfaceVk::OffscreenSurfaceVk(const egl::SurfaceState &surfaceState, ...@@ -171,7 +171,11 @@ OffscreenSurfaceVk::OffscreenSurfaceVk(const egl::SurfaceState &surfaceState,
EGLint width, EGLint width,
EGLint height) EGLint height)
: SurfaceVk(surfaceState), mWidth(width), mHeight(height) : SurfaceVk(surfaceState), mWidth(width), mHeight(height)
{} {
mColorRenderTarget.init(&mColorAttachment.image, &mColorAttachment.imageViews, 0, 0);
mDepthStencilRenderTarget.init(&mDepthStencilAttachment.image,
&mDepthStencilAttachment.imageViews, 0, 0);
}
OffscreenSurfaceVk::~OffscreenSurfaceVk() {} OffscreenSurfaceVk::~OffscreenSurfaceVk() {}
...@@ -399,7 +403,12 @@ WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState, ...@@ -399,7 +403,12 @@ WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState,
mCompositeAlpha(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR), mCompositeAlpha(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR),
mCurrentSwapHistoryIndex(0), mCurrentSwapHistoryIndex(0),
mCurrentSwapchainImageIndex(0) mCurrentSwapchainImageIndex(0)
{} {
// Initialize the color render target with the multisampled targets. If not multisampled, the
// render target will be updated to refer to a swapchain image on every acquire.
mColorRenderTarget.init(&mColorImageMS, &mColorImageMSViews, 0, 0);
mDepthStencilRenderTarget.init(&mDepthStencilImage, &mDepthStencilImageViews, 0, 0);
}
WindowSurfaceVk::~WindowSurfaceVk() WindowSurfaceVk::~WindowSurfaceVk()
{ {
...@@ -871,14 +880,14 @@ void WindowSurfaceVk::releaseSwapchainImages(ContextVk *contextVk) ...@@ -871,14 +880,14 @@ void WindowSurfaceVk::releaseSwapchainImages(ContextVk *contextVk)
{ {
mDepthStencilImage.releaseImage(renderer); mDepthStencilImage.releaseImage(renderer);
mDepthStencilImage.releaseStagingBuffer(renderer); mDepthStencilImage.releaseStagingBuffer(renderer);
mDepthStencilImageViews.release(contextVk); mDepthStencilImageViews.release(renderer);
} }
if (mColorImageMS.valid()) if (mColorImageMS.valid())
{ {
mColorImageMS.releaseImage(renderer); mColorImageMS.releaseImage(renderer);
mColorImageMS.releaseStagingBuffer(renderer); mColorImageMS.releaseStagingBuffer(renderer);
mColorImageMSViews.release(contextVk); mColorImageMSViews.release(renderer);
contextVk->addGarbage(&mFramebufferMS); contextVk->addGarbage(&mFramebufferMS);
} }
...@@ -888,7 +897,7 @@ void WindowSurfaceVk::releaseSwapchainImages(ContextVk *contextVk) ...@@ -888,7 +897,7 @@ void WindowSurfaceVk::releaseSwapchainImages(ContextVk *contextVk)
swapchainImage.image.resetImageWeakReference(); swapchainImage.image.resetImageWeakReference();
swapchainImage.image.destroy(contextVk->getDevice()); swapchainImage.image.destroy(contextVk->getDevice());
swapchainImage.imageViews.release(contextVk); swapchainImage.imageViews.release(renderer);
contextVk->addGarbage(&swapchainImage.framebuffer); contextVk->addGarbage(&swapchainImage.framebuffer);
// present history must have already been taken care of. // present history must have already been taken care of.
......
...@@ -403,6 +403,7 @@ angle::Result TextureVk::copySubImageImpl(const gl::Context *context, ...@@ -403,6 +403,7 @@ angle::Result TextureVk::copySubImageImpl(const gl::Context *context,
const vk::ImageView *readImageView = nullptr; const vk::ImageView *readImageView = nullptr;
ANGLE_TRY(colorReadRT->getImageView(contextVk, &readImageView)); ANGLE_TRY(colorReadRT->getImageView(contextVk, &readImageView));
colorReadRT->onImageViewGraphAccess(contextVk);
return copySubImageImplWithDraw(contextVk, offsetImageIndex, modifiedDestOffset, destFormat, return copySubImageImplWithDraw(contextVk, offsetImageIndex, modifiedDestOffset, destFormat,
0, clippedSourceArea, isViewportFlipY, false, false, false, 0, clippedSourceArea, isViewportFlipY, false, false, false,
...@@ -452,10 +453,10 @@ angle::Result TextureVk::copySubTextureImpl(ContextVk *contextVk, ...@@ -452,10 +453,10 @@ angle::Result TextureVk::copySubTextureImpl(ContextVk *contextVk,
// If it's possible to perform the copy with a draw call, do that. // If it's possible to perform the copy with a draw call, do that.
if (CanCopyWithDraw(renderer, sourceVkFormat, destVkFormat) && !forceCPUPath) if (CanCopyWithDraw(renderer, sourceVkFormat, destVkFormat) && !forceCPUPath)
{ {
return copySubImageImplWithDraw(contextVk, offsetImageIndex, destOffset, destVkFormat, return copySubImageImplWithDraw(
sourceLevel, sourceArea, false, unpackFlipY, contextVk, offsetImageIndex, destOffset, destVkFormat, sourceLevel, sourceArea, false,
unpackPremultiplyAlpha, unpackUnmultiplyAlpha, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha, &source->getImage(),
&source->getImage(), &source->getFetchImageView()); &source->getFetchImageViewAndRecordUse(contextVk));
} }
if (sourceLevel != 0) if (sourceLevel != 0)
...@@ -1362,7 +1363,7 @@ angle::Result TextureVk::syncState(const gl::Context *context, ...@@ -1362,7 +1363,7 @@ angle::Result TextureVk::syncState(const gl::Context *context,
uint32_t layerCount = uint32_t layerCount =
mState.getType() == gl::TextureType::_2D ? 1 : mImage->getLayerCount(); mState.getType() == gl::TextureType::_2D ? 1 : mImage->getLayerCount();
mImageViews.release(contextVk); mImageViews.release(contextVk->getRenderer());
const gl::ImageDesc &baseLevelDesc = mState.getBaseLevelDesc(); const gl::ImageDesc &baseLevelDesc = mState.getBaseLevelDesc();
ANGLE_TRY(initImageViews(contextVk, mImage->getFormat(), ANGLE_TRY(initImageViews(contextVk, mImage->getFormat(),
...@@ -1457,11 +1458,13 @@ void TextureVk::releaseOwnershipOfImage(const gl::Context *context) ...@@ -1457,11 +1458,13 @@ void TextureVk::releaseOwnershipOfImage(const gl::Context *context)
releaseAndDeleteImage(contextVk); releaseAndDeleteImage(contextVk);
} }
const vk::ImageView &TextureVk::getReadImageView() const const vk::ImageView &TextureVk::getReadImageViewAndRecordUse(ContextVk *contextVk) const
{ {
ASSERT(mImage->valid()); ASSERT(mImage->valid());
if (mState.isStencilMode() && mImageViews.getStencilReadImageView().valid()) mImageViews.onGraphAccess(contextVk->getCommandGraph());
if (mState.isStencilMode() && mImageViews.hasStencilReadImageView())
{ {
return mImageViews.getStencilReadImageView(); return mImageViews.getStencilReadImageView();
} }
...@@ -1469,18 +1472,19 @@ const vk::ImageView &TextureVk::getReadImageView() const ...@@ -1469,18 +1472,19 @@ const vk::ImageView &TextureVk::getReadImageView() const
return mImageViews.getReadImageView(); return mImageViews.getReadImageView();
} }
const vk::ImageView &TextureVk::getFetchImageView() const const vk::ImageView &TextureVk::getFetchImageViewAndRecordUse(ContextVk *contextVk) const
{ {
ASSERT(mImage->valid()); ASSERT(mImage->valid());
mImageViews.onGraphAccess(contextVk->getCommandGraph());
// We don't currently support fetch for depth/stencil cube map textures. // We don't currently support fetch for depth/stencil cube map textures.
ASSERT(!mImageViews.getStencilReadImageView().valid() || ASSERT(!mImageViews.hasStencilReadImageView() || !mImageViews.hasFetchImageView());
!mImageViews.getFetchImageView().valid()); return (mImageViews.hasFetchImageView() ? mImageViews.getFetchImageView()
return (mImageViews.getFetchImageView().valid() ? mImageViews.getFetchImageView() : mImageViews.getReadImageView());
: mImageViews.getReadImageView());
} }
angle::Result TextureVk::getLevelLayerImageView(vk::Context *context, angle::Result TextureVk::getLevelLayerImageView(ContextVk *contextVk,
size_t level, size_t level,
size_t layer, size_t layer,
const vk::ImageView **imageViewOut) const vk::ImageView **imageViewOut)
...@@ -1490,7 +1494,7 @@ angle::Result TextureVk::getLevelLayerImageView(vk::Context *context, ...@@ -1490,7 +1494,7 @@ angle::Result TextureVk::getLevelLayerImageView(vk::Context *context,
uint32_t nativeLevel = getNativeImageLevel(static_cast<uint32_t>(level)); uint32_t nativeLevel = getNativeImageLevel(static_cast<uint32_t>(level));
uint32_t nativeLayer = getNativeImageLayer(static_cast<uint32_t>(layer)); uint32_t nativeLayer = getNativeImageLayer(static_cast<uint32_t>(layer));
return mImageViews.getLevelLayerDrawImageView(context, *mImage, nativeLevel, nativeLayer, return mImageViews.getLevelLayerDrawImageView(contextVk, *mImage, nativeLevel, nativeLayer,
imageViewOut); imageViewOut);
} }
...@@ -1602,11 +1606,13 @@ angle::Result TextureVk::initImageViews(ContextVk *contextVk, ...@@ -1602,11 +1606,13 @@ angle::Result TextureVk::initImageViews(ContextVk *contextVk,
void TextureVk::releaseImage(ContextVk *contextVk) void TextureVk::releaseImage(ContextVk *contextVk)
{ {
RendererVk *renderer = contextVk->getRenderer();
if (mImage) if (mImage)
{ {
if (mOwnsImage) if (mOwnsImage)
{ {
mImage->releaseImage(contextVk->getRenderer()); mImage->releaseImage(renderer);
} }
else else
{ {
...@@ -1614,7 +1620,7 @@ void TextureVk::releaseImage(ContextVk *contextVk) ...@@ -1614,7 +1620,7 @@ void TextureVk::releaseImage(ContextVk *contextVk)
} }
} }
mImageViews.release(contextVk); mImageViews.release(renderer);
for (RenderTargetVector &renderTargetLevels : mRenderTargets) for (RenderTargetVector &renderTargetLevels : mRenderTargets)
{ {
......
...@@ -152,12 +152,17 @@ class TextureVk : public TextureImpl ...@@ -152,12 +152,17 @@ class TextureVk : public TextureImpl
return *mImage; return *mImage;
} }
void onImageViewGraphAccess(vk::CommandGraph *commandGraph)
{
mImageViews.onGraphAccess(commandGraph);
}
void releaseOwnershipOfImage(const gl::Context *context); void releaseOwnershipOfImage(const gl::Context *context);
const vk::ImageView &getReadImageView() const; const vk::ImageView &getReadImageViewAndRecordUse(ContextVk *contextVk) const;
// A special view for cube maps as a 2D array, used with shaders that do texelFetch() and for // A special view for cube maps as a 2D array, used with shaders that do texelFetch() and for
// seamful cube map emulation. // seamful cube map emulation.
const vk::ImageView &getFetchImageView() const; const vk::ImageView &getFetchImageViewAndRecordUse(ContextVk *contextVk) const;
angle::Result getStorageImageView(ContextVk *contextVk, angle::Result getStorageImageView(ContextVk *contextVk,
bool allLayers, bool allLayers,
size_t level, size_t level,
...@@ -295,7 +300,7 @@ class TextureVk : public TextureImpl ...@@ -295,7 +300,7 @@ class TextureVk : public TextureImpl
uint32_t levelCount, uint32_t levelCount,
uint32_t layerCount); uint32_t layerCount);
angle::Result initRenderTargets(ContextVk *contextVk, GLuint layerCount, GLuint levelIndex); angle::Result initRenderTargets(ContextVk *contextVk, GLuint layerCount, GLuint levelIndex);
angle::Result getLevelLayerImageView(vk::Context *context, angle::Result getLevelLayerImageView(ContextVk *contextVk,
size_t level, size_t level,
size_t layer, size_t layer,
const vk::ImageView **imageViewOut); const vk::ImageView **imageViewOut);
......
...@@ -2507,6 +2507,8 @@ angle::Result ImageHelper::stageSubresourceUpdateFromFramebuffer( ...@@ -2507,6 +2507,8 @@ angle::Result ImageHelper::stageSubresourceUpdateFromFramebuffer(
PackPixelsParams params(clippedRectangle, copyFormat, static_cast<GLuint>(outputRowPitch), PackPixelsParams params(clippedRectangle, copyFormat, static_cast<GLuint>(outputRowPitch),
isViewportFlipEnabled, nullptr, 0); isViewportFlipEnabled, nullptr, 0);
RenderTargetVk *readRenderTarget = framebufferVk->getColorReadRenderTarget();
// 2- copy the source image region to the pixel buffer using a cpu readback // 2- copy the source image region to the pixel buffer using a cpu readback
if (loadFunction.requiresConversion) if (loadFunction.requiresConversion)
{ {
...@@ -2518,9 +2520,9 @@ angle::Result ImageHelper::stageSubresourceUpdateFromFramebuffer( ...@@ -2518,9 +2520,9 @@ angle::Result ImageHelper::stageSubresourceUpdateFromFramebuffer(
ANGLE_VK_CHECK_ALLOC(contextVk, context->getScratchBuffer(bufferSize, &memoryBuffer)); ANGLE_VK_CHECK_ALLOC(contextVk, context->getScratchBuffer(bufferSize, &memoryBuffer));
// Read into the scratch buffer // Read into the scratch buffer
ANGLE_TRY(framebufferVk->readPixelsImpl( ANGLE_TRY(framebufferVk->readPixelsImpl(contextVk, clippedRectangle, params,
contextVk, clippedRectangle, params, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT, readRenderTarget,
framebufferVk->getColorReadRenderTarget(), memoryBuffer->data())); memoryBuffer->data()));
// Load from scratch buffer to our pixel buffer // Load from scratch buffer to our pixel buffer
loadFunction.loadFunction(clippedRectangle.width, clippedRectangle.height, 1, loadFunction.loadFunction(clippedRectangle.width, clippedRectangle.height, 1,
...@@ -2530,9 +2532,9 @@ angle::Result ImageHelper::stageSubresourceUpdateFromFramebuffer( ...@@ -2530,9 +2532,9 @@ angle::Result ImageHelper::stageSubresourceUpdateFromFramebuffer(
else else
{ {
// We read directly from the framebuffer into our pixel buffer. // We read directly from the framebuffer into our pixel buffer.
ANGLE_TRY(framebufferVk->readPixelsImpl( ANGLE_TRY(framebufferVk->readPixelsImpl(contextVk, clippedRectangle, params,
contextVk, clippedRectangle, params, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT, readRenderTarget,
framebufferVk->getColorReadRenderTarget(), stagingPointer)); stagingPointer));
} }
// 3- enqueue the destination image subresource update // 3- enqueue the destination image subresource update
...@@ -2931,7 +2933,10 @@ void FramebufferHelper::release(ContextVk *contextVk) ...@@ -2931,7 +2933,10 @@ void FramebufferHelper::release(ContextVk *contextVk)
} }
// ImageViewHelper implementation. // ImageViewHelper implementation.
ImageViewHelper::ImageViewHelper() = default; ImageViewHelper::ImageViewHelper()
{
mUse.init();
}
ImageViewHelper::ImageViewHelper(ImageViewHelper &&other) ImageViewHelper::ImageViewHelper(ImageViewHelper &&other)
{ {
...@@ -2942,17 +2947,22 @@ ImageViewHelper::ImageViewHelper(ImageViewHelper &&other) ...@@ -2942,17 +2947,22 @@ ImageViewHelper::ImageViewHelper(ImageViewHelper &&other)
std::swap(mLayerLevelDrawImageViews, other.mLayerLevelDrawImageViews); std::swap(mLayerLevelDrawImageViews, other.mLayerLevelDrawImageViews);
} }
ImageViewHelper::~ImageViewHelper() = default; ImageViewHelper::~ImageViewHelper()
{
mUse.release();
}
void ImageViewHelper::release(ContextVk *contextVk) void ImageViewHelper::release(RendererVk *renderer)
{ {
contextVk->addGarbage(&mReadImageView); std::vector<GarbageObject> garbage;
contextVk->addGarbage(&mFetchImageView);
contextVk->addGarbage(&mStencilReadImageView); garbage.emplace_back(GetGarbage(&mReadImageView));
garbage.emplace_back(GetGarbage(&mFetchImageView));
garbage.emplace_back(GetGarbage(&mStencilReadImageView));
for (vk::ImageView &imageView : mLevelDrawImageViews) for (vk::ImageView &imageView : mLevelDrawImageViews)
{ {
contextVk->addGarbage(&imageView); garbage.emplace_back(GetGarbage(&imageView));
} }
mLevelDrawImageViews.clear(); mLevelDrawImageViews.clear();
...@@ -2960,10 +2970,15 @@ void ImageViewHelper::release(ContextVk *contextVk) ...@@ -2960,10 +2970,15 @@ void ImageViewHelper::release(ContextVk *contextVk)
{ {
for (vk::ImageView &imageView : layerViews) for (vk::ImageView &imageView : layerViews)
{ {
contextVk->addGarbage(&imageView); garbage.emplace_back(GetGarbage(&imageView));
} }
} }
mLayerLevelDrawImageViews.clear(); mLayerLevelDrawImageViews.clear();
renderer->collectGarbage(std::move(mUse), std::move(garbage));
// Ensure the resource use is always valid.
mUse.init();
} }
void ImageViewHelper::destroy(VkDevice device) void ImageViewHelper::destroy(VkDevice device)
...@@ -3036,6 +3051,8 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk, ...@@ -3036,6 +3051,8 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk,
uint32_t layer, uint32_t layer,
const ImageView **imageViewOut) const ImageView **imageViewOut)
{ {
onGraphAccess(contextVk->getCommandGraph());
// TODO(http://anglebug.com/4008): Possibly incorrect level count. // TODO(http://anglebug.com/4008): Possibly incorrect level count.
ImageView *imageView = GetLevelImageView(&mLevelDrawImageViews, level, 1); ImageView *imageView = GetLevelImageView(&mLevelDrawImageViews, level, 1);
...@@ -3050,7 +3067,7 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk, ...@@ -3050,7 +3067,7 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk,
imageView, level, 1, layer, image.getLayerCount()); imageView, level, 1, layer, image.getLayerCount());
} }
angle::Result ImageViewHelper::getLevelLayerDrawImageView(Context *context, angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk,
const ImageHelper &image, const ImageHelper &image,
uint32_t level, uint32_t level,
uint32_t layer, uint32_t layer,
...@@ -3059,6 +3076,8 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(Context *context, ...@@ -3059,6 +3076,8 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(Context *context,
ASSERT(image.valid()); ASSERT(image.valid());
ASSERT(!image.getFormat().actualImageFormat().isBlock); ASSERT(!image.getFormat().actualImageFormat().isBlock);
onGraphAccess(contextVk->getCommandGraph());
uint32_t layerCount = GetImageLayerCountForView(image); uint32_t layerCount = GetImageLayerCountForView(image);
// Lazily allocate the storage for image views // Lazily allocate the storage for image views
...@@ -3081,7 +3100,7 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(Context *context, ...@@ -3081,7 +3100,7 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(Context *context,
// Note that these views are specifically made to be used as color attachments, and therefore // Note that these views are specifically made to be used as color attachments, and therefore
// don't have swizzle. // don't have swizzle.
gl::TextureType viewType = vk::Get2DTextureType(1, image.getSamples()); gl::TextureType viewType = vk::Get2DTextureType(1, image.getSamples());
return image.initLayerImageView(context, viewType, image.getAspectFlags(), gl::SwizzleState(), return image.initLayerImageView(contextVk, viewType, image.getAspectFlags(), gl::SwizzleState(),
imageView, level, 1, layer, 1); imageView, level, 1, layer, 1);
} }
......
...@@ -997,13 +997,21 @@ class ImageViewHelper : angle::NonCopyable ...@@ -997,13 +997,21 @@ class ImageViewHelper : angle::NonCopyable
ImageViewHelper(ImageViewHelper &&other); ImageViewHelper(ImageViewHelper &&other);
~ImageViewHelper(); ~ImageViewHelper();
void release(ContextVk *contextVk); void release(RendererVk *renderer);
void destroy(VkDevice device); void destroy(VkDevice device);
const ImageView &getReadImageView() const { return mReadImageView; } const ImageView &getReadImageView() const { return mReadImageView; }
const ImageView &getFetchImageView() const { return mFetchImageView; } const ImageView &getFetchImageView() const { return mFetchImageView; }
const ImageView &getStencilReadImageView() const { return mStencilReadImageView; } const ImageView &getStencilReadImageView() const { return mStencilReadImageView; }
// Used when initialized RenderTargets.
bool hasStencilReadImageView() const { return mStencilReadImageView.valid(); }
bool hasFetchImageView() const { return mFetchImageView.valid(); }
// Store reference to usage in graph.
void onGraphAccess(CommandGraph *commandGraph) const { commandGraph->onResourceUse(mUse); }
// Creates views with multiple layers and levels. // Creates views with multiple layers and levels.
angle::Result initReadViews(ContextVk *contextVk, angle::Result initReadViews(ContextVk *contextVk,
gl::TextureType viewType, gl::TextureType viewType,
...@@ -1024,13 +1032,16 @@ class ImageViewHelper : angle::NonCopyable ...@@ -1024,13 +1032,16 @@ class ImageViewHelper : angle::NonCopyable
const ImageView **imageViewOut); const ImageView **imageViewOut);
// Creates a view with a single layer of the level. // Creates a view with a single layer of the level.
angle::Result getLevelLayerDrawImageView(Context *context, angle::Result getLevelLayerDrawImageView(ContextVk *contextVk,
const ImageHelper &image, const ImageHelper &image,
uint32_t level, uint32_t level,
uint32_t layer, uint32_t layer,
const ImageView **imageViewOut); const ImageView **imageViewOut);
private: private:
// Lifetime.
SharedResourceUse mUse;
// Read views. // Read views.
ImageView mReadImageView; ImageView mReadImageView;
ImageView mFetchImageView; ImageView mFetchImageView;
......
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