Commit f3e823db by Geoff Lang Committed by Commit Bot

Vulkan: Store ImageHelper as a pointer in TextureVk and RenderbufferVk

Storing ImageHelper as a pointer allows the storage to be swapped or shared with other objects. BUG=angleproject:2668 Change-Id: I2e51f24737be59ffe9f472e9b0b592774a792cd1 Reviewed-on: https://chromium-review.googlesource.com/c/1409404 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent eb67ca6e
......@@ -16,11 +16,8 @@
namespace rx
{
RenderTargetVk::RenderTargetVk(vk::ImageHelper *image,
vk::ImageView *imageView,
size_t layerIndex,
TextureVk *owner)
: mImage(image), mImageView(imageView), mLayerIndex(layerIndex), mOwner(owner)
RenderTargetVk::RenderTargetVk()
: mImage(nullptr), mImageView(nullptr), mLayerIndex(0), mOwner(nullptr)
{}
RenderTargetVk::~RenderTargetVk() {}
......@@ -32,6 +29,25 @@ RenderTargetVk::RenderTargetVk(RenderTargetVk &&other)
mOwner(other.mOwner)
{}
void RenderTargetVk::init(vk::ImageHelper *image,
vk::ImageView *imageView,
size_t layerIndex,
TextureVk *owner)
{
mImage = image;
mImageView = imageView;
mLayerIndex = layerIndex;
mOwner = owner;
}
void RenderTargetVk::reset()
{
mImage = nullptr;
mImageView = nullptr;
mLayerIndex = 0;
mOwner = nullptr;
}
void RenderTargetVk::onColorDraw(vk::FramebufferHelper *framebufferVk,
vk::CommandBuffer *commandBuffer,
vk::RenderPassDesc *renderPassDesc)
......
......@@ -37,15 +37,18 @@ class TextureVk;
class RenderTargetVk final : public FramebufferAttachmentRenderTarget
{
public:
RenderTargetVk(vk::ImageHelper *image,
vk::ImageView *imageView,
size_t layerIndex,
TextureVk *ownwer);
RenderTargetVk();
~RenderTargetVk() override;
// Used in std::vector initialization.
RenderTargetVk(RenderTargetVk &&other);
void init(vk::ImageHelper *image,
vk::ImageView *imageView,
size_t layerIndex,
TextureVk *owner);
void reset();
// Note: RenderTargets should be called in order, with the depth/stencil onRender last.
void onColorDraw(vk::FramebufferHelper *framebufferVk,
vk::CommandBuffer *commandBuffer,
......
......@@ -24,7 +24,7 @@ constexpr VkClearColorValue kBlackClearColorValue = {{0}};
} // anonymous namespace
RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state)
: RenderbufferImpl(state), mRenderTarget(&mImage, &mImageView, 0, nullptr)
: RenderbufferImpl(state), mImage(nullptr)
{}
RenderbufferVk::~RenderbufferVk() {}
......@@ -34,8 +34,12 @@ void RenderbufferVk::onDestroy(const gl::Context *context)
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
mImage.releaseImage(renderer);
mImage.releaseStagingBuffer(renderer);
if (mImage)
{
mImage->releaseImage(renderer);
mImage->releaseStagingBuffer(renderer);
SafeDelete(mImage);
}
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
}
......@@ -49,20 +53,25 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context,
RendererVk *renderer = contextVk->getRenderer();
const vk::Format &vkFormat = renderer->getFormat(internalformat);
if (mImage.valid())
if (mImage != nullptr && mImage->valid())
{
// Check against the state if we need to recreate the storage.
if (internalformat != mState.getFormat().info->internalFormat ||
static_cast<GLsizei>(width) != mState.getWidth() ||
static_cast<GLsizei>(height) != mState.getHeight())
{
mImage.releaseImage(renderer);
mImage->releaseImage(renderer);
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
}
}
if (!mImage.valid() && (width != 0 && height != 0))
if ((mImage == nullptr || !mImage->valid()) && (width != 0 && height != 0))
{
if (mImage == nullptr)
{
mImage = new vk::ImageHelper();
}
const angle::Format &textureFormat = vkFormat.textureFormat();
bool isDepthOrStencilFormat = textureFormat.depthBits > 0 || textureFormat.stencilBits > 0;
const VkImageUsageFlags usage =
......@@ -72,30 +81,33 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context,
(isDepthOrStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0);
gl::Extents extents(static_cast<int>(width), static_cast<int>(height), 1);
ANGLE_TRY(mImage.init(contextVk, gl::TextureType::_2D, extents, vkFormat, 1, usage, 1, 1));
ANGLE_TRY(mImage->init(contextVk, gl::TextureType::_2D, extents, vkFormat, 1, usage, 1, 1));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage.initMemory(contextVk, renderer->getMemoryProperties(), flags));
ANGLE_TRY(mImage->initMemory(contextVk, renderer->getMemoryProperties(), flags));
VkImageAspectFlags aspect = vk::GetFormatAspectFlags(textureFormat);
// Note that LUMA textures are not color-renderable, so a read-view with swizzle is not
// needed.
ANGLE_TRY(mImage.initImageView(contextVk, gl::TextureType::_2D, aspect, gl::SwizzleState(),
&mImageView, 1));
ANGLE_TRY(mImage->initImageView(contextVk, gl::TextureType::_2D, aspect, gl::SwizzleState(),
&mImageView, 1));
// TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(mImage.recordCommands(contextVk, &commandBuffer));
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
if (isDepthOrStencilFormat)
{
mImage.clearDepthStencil(aspect, aspect, kDefaultClearDepthStencilValue, commandBuffer);
mImage->clearDepthStencil(aspect, aspect, kDefaultClearDepthStencilValue,
commandBuffer);
}
else
{
mImage.clearColor(kBlackClearColorValue, 0, 1, commandBuffer);
mImage->clearColor(kBlackClearColorValue, 0, 1, commandBuffer);
}
mRenderTarget.init(mImage, &mImageView, 0, nullptr);
}
return angle::Result::Continue;
......@@ -123,7 +135,7 @@ angle::Result RenderbufferVk::getAttachmentRenderTarget(const gl::Context *conte
const gl::ImageIndex &imageIndex,
FramebufferAttachmentRenderTarget **rtOut)
{
ASSERT(mImage.valid());
ASSERT(mImage && mImage->valid());
*rtOut = &mRenderTarget;
return angle::Result::Continue;
}
......
......@@ -45,7 +45,7 @@ class RenderbufferVk : public RenderbufferImpl
const gl::ImageIndex &imageIndex) override;
private:
vk::ImageHelper mImage;
vk::ImageHelper *mImage;
vk::ImageView mImageView;
RenderTargetVk mRenderTarget;
};
......
......@@ -75,8 +75,9 @@ constexpr VkImageUsageFlags kSurfaceVKDepthStencilImageUsageFlags =
} // namespace
OffscreenSurfaceVk::AttachmentImage::AttachmentImage()
: renderTarget(&image, &imageView, 0, nullptr)
{}
{
renderTarget.init(&image, &imageView, 0, nullptr);
}
OffscreenSurfaceVk::AttachmentImage::~AttachmentImage() = default;
......@@ -273,11 +274,11 @@ WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState,
mInstance(VK_NULL_HANDLE),
mSwapchain(VK_NULL_HANDLE),
mSwapchainPresentMode(VK_PRESENT_MODE_FIFO_KHR),
mColorRenderTarget(nullptr, nullptr, 0, nullptr),
mDepthStencilRenderTarget(&mDepthStencilImage, &mDepthStencilImageView, 0, nullptr),
mCurrentSwapchainImageIndex(0),
mCurrentSwapSerialIndex(0)
{}
{
mDepthStencilRenderTarget.init(&mDepthStencilImage, &mDepthStencilImageView, 0, nullptr);
}
WindowSurfaceVk::~WindowSurfaceVk()
{
......
......@@ -97,7 +97,7 @@ angle::Result TextureVk::generateMipmapLevelsWithCPU(ContextVk *contextVk,
size_t mipAllocationSize = destRowPitch * mipHeight;
gl::Extents mipLevelExtents(static_cast<int>(mipWidth), static_cast<int>(mipHeight), 1);
ANGLE_TRY(mImage.stageSubresourceUpdateAndGetData(
ANGLE_TRY(mImage->stageSubresourceUpdateAndGetData(
contextVk, mipAllocationSize,
gl::ImageIndex::MakeFromType(mState.getType(), currentMipLevel, layer), mipLevelExtents,
gl::Offset(), &destData));
......@@ -119,10 +119,8 @@ angle::Result TextureVk::generateMipmapLevelsWithCPU(ContextVk *contextVk,
// TextureVk implementation.
TextureVk::TextureVk(const gl::TextureState &state, RendererVk *renderer)
: TextureImpl(state), mRenderTarget(&mImage, &mDrawBaseLevelImageView, 0, this)
{
mImage.initStagingBuffer(renderer);
}
: TextureImpl(state), mImage(nullptr)
{}
TextureVk::~TextureVk() = default;
......@@ -134,6 +132,8 @@ void TextureVk::onDestroy(const gl::Context *context)
releaseImage(renderer);
releaseStagingBuffer(renderer);
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mSampler);
SafeDelete(mImage);
}
angle::Result TextureVk::setImage(const gl::Context *context,
......@@ -160,13 +160,13 @@ angle::Result TextureVk::setImage(const gl::Context *context,
}
// Create a new graph node to store image initialization commands.
mImage.finishCurrentCommands(renderer);
mImage->finishCurrentCommands(renderer);
// Handle initial data.
if (pixels)
{
ANGLE_TRY(mImage.stageSubresourceUpdate(contextVk, index, size, gl::Offset(), formatInfo,
unpack, type, pixels));
ANGLE_TRY(mImage->stageSubresourceUpdate(contextVk, index, size, gl::Offset(), formatInfo,
unpack, type, pixels));
}
return angle::Result::Continue;
......@@ -183,12 +183,12 @@ angle::Result TextureVk::setSubImage(const gl::Context *context,
{
ContextVk *contextVk = vk::GetImpl(context);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format, type);
ANGLE_TRY(mImage.stageSubresourceUpdate(
ANGLE_TRY(mImage->stageSubresourceUpdate(
contextVk, index, gl::Extents(area.width, area.height, area.depth),
gl::Offset(area.x, area.y, area.z), formatInfo, unpack, type, pixels));
// Create a new graph node to store image initialization commands.
mImage.finishCurrentCommands(contextVk->getRenderer());
mImage->finishCurrentCommands(contextVk->getRenderer());
return angle::Result::Continue;
}
......@@ -310,7 +310,7 @@ angle::Result TextureVk::copySubImageImpl(const gl::Context *context,
const vk::Format &srcFormat = framebufferVk->getColorReadRenderTarget()->getImageFormat();
const vk::Format &destFormat = renderer->getFormat(internalFormat.sizedInternalFormat);
bool forceCpuPath = ForceCpuPathForCopy(renderer, &mImage);
bool forceCpuPath = ForceCpuPathForCopy(renderer, mImage);
// If it's possible to perform the copy with a draw call, do that.
if (CanCopyWithDraw(renderer, srcFormat, destFormat) && !forceCpuPath)
......@@ -329,13 +329,13 @@ angle::Result TextureVk::copySubImageImpl(const gl::Context *context,
}
// Do a CPU readback that does the conversion, and then stage the change to the pixel buffer.
ANGLE_TRY(mImage.stageSubresourceUpdateFromFramebuffer(
ANGLE_TRY(mImage->stageSubresourceUpdateFromFramebuffer(
context, index, clippedSourceArea, modifiedDestOffset,
gl::Extents(clippedSourceArea.width, clippedSourceArea.height, 1), internalFormat,
framebufferVk));
mImage.finishCurrentCommands(renderer);
framebufferVk->getFramebuffer()->addReadDependency(&mImage);
mImage->finishCurrentCommands(renderer);
framebufferVk->getFramebuffer()->addReadDependency(mImage);
return angle::Result::Continue;
}
......@@ -357,7 +357,7 @@ angle::Result TextureVk::copySubTextureImpl(ContextVk *contextVk,
const vk::Format &sourceVkFormat = source->getImage().getFormat();
const vk::Format &destVkFormat = renderer->getFormat(destFormat.sizedInternalFormat);
bool forceCpuPath = ForceCpuPathForCopy(renderer, &mImage);
bool forceCpuPath = ForceCpuPathForCopy(renderer, mImage);
// If it's possible to perform the copy with a draw call, do that.
if (CanCopyWithDraw(renderer, sourceVkFormat, destVkFormat) && !forceCpuPath)
......@@ -387,7 +387,7 @@ angle::Result TextureVk::copySubTextureImpl(ContextVk *contextVk,
// Allocate memory in the destination texture for the copy/conversion
uint8_t *destData = nullptr;
ANGLE_TRY(mImage.stageSubresourceUpdateAndGetData(
ANGLE_TRY(mImage->stageSubresourceUpdateAndGetData(
contextVk, destinationAllocationSize, index,
gl::Extents(sourceArea.width, sourceArea.height, 1), destOffset, &destData));
......@@ -417,7 +417,7 @@ angle::Result TextureVk::copySubTextureImpl(ContextVk *contextVk,
unpackUnmultiplyAlpha);
// Create a new graph node to store image initialization commands.
mImage.finishCurrentCommands(contextVk->getRenderer());
mImage->finishCurrentCommands(contextVk->getRenderer());
return angle::Result::Continue;
}
......@@ -458,7 +458,7 @@ angle::Result TextureVk::copySubImageImplWithDraw(ContextVk *contextVk,
uint32_t layerCount = index.getLayerCount();
// If destination is valid, copy the source directly into it.
if (mImage.valid())
if (mImage->valid())
{
// Make sure any updates to the image are already flushed.
ANGLE_TRY(ensureImageInitialized(contextVk));
......@@ -471,7 +471,7 @@ angle::Result TextureVk::copySubImageImplWithDraw(ContextVk *contextVk,
ANGLE_TRY(
getLayerLevelDrawImageView(contextVk, baseLayer + layerIndex, level, &destView));
ANGLE_TRY(utilsVk.copyImage(contextVk, &mImage, destView, srcImage, srcView, params));
ANGLE_TRY(utilsVk.copyImage(contextVk, mImage, destView, srcImage, srcView, params));
}
}
else
......@@ -510,8 +510,9 @@ angle::Result TextureVk::copySubImageImplWithDraw(ContextVk *contextVk,
}
// Stage the copy for when the image storage is actually created.
mImage.stageSubresourceUpdateFromImage(stagingImage.release(), index, destOffset,
gl::Extents(sourceArea.width, sourceArea.height, 1));
mImage->stageSubresourceUpdateFromImage(
stagingImage.release(), index, destOffset,
gl::Extents(sourceArea.width, sourceArea.height, 1));
}
return angle::Result::Continue;
......@@ -525,11 +526,14 @@ angle::Result TextureVk::setStorage(const gl::Context *context,
{
ContextVk *contextVk = GetAs<ContextVk>(context->getImplementation());
RendererVk *renderer = contextVk->getRenderer();
ANGLE_TRY(ensureImageAllocated(renderer));
const vk::Format &format = renderer->getFormat(internalFormat);
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(mImage.recordCommands(contextVk, &commandBuffer));
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
if (mImage.valid())
if (mImage->valid())
{
releaseImage(renderer);
}
......@@ -555,6 +559,22 @@ angle::Result TextureVk::setImageExternal(const gl::Context *context,
return angle::Result::Stop;
}
angle::Result TextureVk::ensureImageAllocated(RendererVk *renderer)
{
if (mImage == nullptr)
{
mImage = new vk::ImageHelper();
mImage->initStagingBuffer(renderer);
mRenderTarget.init(mImage, &mDrawBaseLevelImageView, 0, this);
// Force re-creation of cube map render targets next time they are needed
mCubeMapRenderTargets.clear();
}
return angle::Result::Continue;
}
angle::Result TextureVk::redefineImage(const gl::Context *context,
const gl::ImageIndex &index,
const gl::InternalFormat &internalFormat,
......@@ -563,20 +583,28 @@ angle::Result TextureVk::redefineImage(const gl::Context *context,
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
// If there is any staged changes for this index, we can remove them since we're going to
// override them with this call.
mImage.removeStagedUpdates(renderer, index);
if (!size.empty())
{
ANGLE_TRY(ensureImageAllocated(renderer));
}
if (mImage.valid())
if (mImage != nullptr)
{
const vk::Format &vkFormat = renderer->getFormat(internalFormat.sizedInternalFormat);
// If there is any staged changes for this index, we can remove them since we're going to
// override them with this call.
mImage->removeStagedUpdates(renderer, index);
// Calculate the expected size for the index we are defining. If the size is different from
// the given size, or the format is different, we are redefining the image so we must
// release it.
if (mImage.getFormat() != vkFormat || size != mImage.getSize(index))
if (mImage->valid())
{
releaseImage(renderer);
const vk::Format &vkFormat = renderer->getFormat(internalFormat.sizedInternalFormat);
// Calculate the expected size for the index we are defining. If the size is different
// from the given size, or the format is different, we are redefining the image so we
// must release it.
if (mImage->getFormat() != vkFormat || size != mImage->getSize(index))
{
releaseImage(renderer);
}
}
}
......@@ -597,19 +625,19 @@ angle::Result TextureVk::copyImageDataToBuffer(ContextVk *contextVk,
sourceArea.width * sourceArea.height * imageFormat.pixelBytes * layerCount;
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(mImage.recordCommands(contextVk, &commandBuffer));
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
// Requirement of the copyImageToBuffer, the source image must be in SRC_OPTIMAL layout.
mImage.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
mImage->changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
// Allocate enough memory to copy the sourceArea region of the source texture into its pixel
// buffer.
VkBuffer copyBufferHandle = VK_NULL_HANDLE;
VkDeviceSize sourceCopyOffset = 0;
ANGLE_TRY(mImage.allocateStagingMemory(contextVk, sourceCopyAllocationSize, outDataPtr,
&copyBufferHandle, &sourceCopyOffset, nullptr));
ANGLE_TRY(mImage->allocateStagingMemory(contextVk, sourceCopyAllocationSize, outDataPtr,
&copyBufferHandle, &sourceCopyOffset, nullptr));
VkBufferImageCopy region = {};
region.bufferOffset = sourceCopyOffset;
......@@ -626,8 +654,8 @@ angle::Result TextureVk::copyImageDataToBuffer(ContextVk *contextVk,
region.imageSubresource.layerCount = layerCount;
region.imageSubresource.mipLevel = static_cast<uint32_t>(sourceLevel);
commandBuffer->copyImageToBuffer(mImage.getImage(), mImage.getCurrentLayout(), copyBufferHandle,
1, &region);
commandBuffer->copyImageToBuffer(mImage->getImage(), mImage->getCurrentLayout(),
copyBufferHandle, 1, &region);
// Explicitly finish. If new use cases arise where we don't want to block we can change this.
ANGLE_TRY(contextVk->getRenderer()->finish(contextVk));
......@@ -639,15 +667,15 @@ angle::Result TextureVk::generateMipmapsWithCPU(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
const gl::Extents baseLevelExtents = mImage.getExtents();
uint32_t imageLayerCount = mImage.getLayerCount();
const gl::Extents baseLevelExtents = mImage->getExtents();
uint32_t imageLayerCount = mImage->getLayerCount();
uint8_t *imageData = nullptr;
gl::Rectangle imageArea(0, 0, baseLevelExtents.width, baseLevelExtents.height);
ANGLE_TRY(copyImageDataToBuffer(contextVk, mState.getEffectiveBaseLevel(), imageLayerCount,
imageArea, &imageData));
const angle::Format &angleFormat = mImage.getFormat().textureFormat();
const angle::Format &angleFormat = mImage->getFormat().textureFormat();
GLuint sourceRowPitch = baseLevelExtents.width * angleFormat.pixelBytes;
size_t baseLevelAllocationSize = sourceRowPitch * baseLevelExtents.height;
......@@ -665,8 +693,8 @@ angle::Result TextureVk::generateMipmapsWithCPU(const gl::Context *context)
}
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(mImage.recordCommands(contextVk, &commandBuffer));
return mImage.flushStagedUpdates(contextVk, getLevelCount(), commandBuffer);
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
return mImage->flushStagedUpdates(contextVk, getLevelCount(), commandBuffer);
}
angle::Result TextureVk::generateMipmap(const gl::Context *context)
......@@ -674,13 +702,13 @@ angle::Result TextureVk::generateMipmap(const gl::Context *context)
ContextVk *contextVk = vk::GetImpl(context);
// Some data is pending, or the image has not been defined at all yet
if (!mImage.valid())
if (!mImage->valid())
{
// lets initialize the image so we can generate the next levels.
if (mImage.hasStagedUpdates())
if (mImage->hasStagedUpdates())
{
ANGLE_TRY(ensureImageInitialized(contextVk));
ASSERT(mImage.valid());
ASSERT(mImage->valid());
}
else
{
......@@ -693,11 +721,11 @@ angle::Result TextureVk::generateMipmap(const gl::Context *context)
// Check if the image supports blit. If it does, we can do the mipmap generation on the gpu
// only.
if (renderer->hasTextureFormatFeatureBits(mImage.getFormat().vkTextureFormat,
if (renderer->hasTextureFormatFeatureBits(mImage->getFormat().vkTextureFormat,
kBlitFeatureFlags))
{
ANGLE_TRY(ensureImageInitialized(contextVk));
ANGLE_TRY(mImage.generateMipmapsWithBlit(contextVk, mState.getMipmapMaxLevel()));
ANGLE_TRY(mImage->generateMipmapsWithBlit(contextVk, mState.getMipmapMaxLevel()));
}
else
{
......@@ -705,7 +733,7 @@ angle::Result TextureVk::generateMipmap(const gl::Context *context)
}
// We're changing this textureVk content, make sure we let the graph know.
mImage.finishCurrentCommands(renderer);
mImage->finishCurrentCommands(renderer);
return angle::Result::Continue;
}
......@@ -772,19 +800,19 @@ angle::Result TextureVk::ensureImageInitializedImpl(ContextVk *contextVk,
uint32_t levelCount,
const vk::Format &format)
{
if (mImage.valid() && !mImage.hasStagedUpdates())
if (mImage->valid() && !mImage->hasStagedUpdates())
{
return angle::Result::Continue;
}
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(mImage.recordCommands(contextVk, &commandBuffer));
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
if (!mImage.valid())
if (!mImage->valid())
{
ANGLE_TRY(initImage(contextVk, format, baseLevelExtents, levelCount, commandBuffer));
}
return mImage.flushStagedUpdates(contextVk, levelCount, commandBuffer);
return mImage->flushStagedUpdates(contextVk, levelCount, commandBuffer);
}
angle::Result TextureVk::initCubeMapRenderTargets(ContextVk *contextVk)
......@@ -793,11 +821,12 @@ angle::Result TextureVk::initCubeMapRenderTargets(ContextVk *contextVk)
if (!mCubeMapRenderTargets.empty())
return angle::Result::Continue;
mCubeMapRenderTargets.resize(gl::kCubeFaceCount);
for (size_t cubeMapFaceIndex = 0; cubeMapFaceIndex < gl::kCubeFaceCount; ++cubeMapFaceIndex)
{
vk::ImageView *imageView;
ANGLE_TRY(getLayerLevelDrawImageView(contextVk, cubeMapFaceIndex, 0, &imageView));
mCubeMapRenderTargets.emplace_back(&mImage, imageView, cubeMapFaceIndex, this);
mCubeMapRenderTargets[cubeMapFaceIndex].init(mImage, imageView, cubeMapFaceIndex, this);
}
return angle::Result::Continue;
}
......@@ -867,7 +896,7 @@ angle::Result TextureVk::initializeContents(const gl::Context *context,
const vk::ImageView &TextureVk::getReadImageView() const
{
ASSERT(mImage.valid());
ASSERT(mImage->valid());
const GLenum minFilter = mState.getSamplerState().getMinFilter();
if (minFilter == GL_LINEAR || minFilter == GL_NEAREST)
......@@ -883,18 +912,18 @@ angle::Result TextureVk::getLayerLevelDrawImageView(vk::Context *context,
size_t level,
vk::ImageView **imageViewOut)
{
ASSERT(mImage.valid());
ASSERT(mImage->valid());
// Lazily allocate the storage for image views
if (mLayerLevelDrawImageViews.empty())
{
mLayerLevelDrawImageViews.resize(mImage.getLayerCount());
mLayerLevelDrawImageViews.resize(mImage->getLayerCount());
}
ASSERT(mLayerLevelDrawImageViews.size() > layer);
if (mLayerLevelDrawImageViews[layer].empty())
{
mLayerLevelDrawImageViews[layer].resize(mImage.getLevelCount());
mLayerLevelDrawImageViews[layer].resize(mImage->getLevelCount());
}
ASSERT(mLayerLevelDrawImageViews[layer].size() > level);
......@@ -907,8 +936,8 @@ angle::Result TextureVk::getLayerLevelDrawImageView(vk::Context *context,
// Lazily allocate the image view itself.
// Note that these views are specifically made to be used as color attachments, and therefore
// don't have swizzle.
return mImage.initLayerImageView(context, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
gl::SwizzleState(), *imageViewOut, level, 1, layer, 1);
return mImage->initLayerImageView(context, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
gl::SwizzleState(), *imageViewOut, level, 1, layer, 1);
}
const vk::Sampler &TextureVk::getSampler() const
......@@ -929,32 +958,35 @@ angle::Result TextureVk::initImage(ContextVk *contextVk,
(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
ANGLE_TRY(mImage.init(contextVk, mState.getType(), extents, format, 1, usage, levelCount,
mState.getType() == gl::TextureType::CubeMap ? gl::kCubeFaceCount : 1));
ANGLE_TRY(mImage->init(contextVk, mState.getType(), extents, format, 1, usage, levelCount,
mState.getType() == gl::TextureType::CubeMap ? gl::kCubeFaceCount : 1));
const VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage.initMemory(contextVk, renderer->getMemoryProperties(), flags));
ANGLE_TRY(mImage->initMemory(contextVk, renderer->getMemoryProperties(), flags));
gl::SwizzleState mappedSwizzle;
MapSwizzleState(format, mState.getSwizzleState(), &mappedSwizzle);
ANGLE_TRY(mImage.initImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mReadMipmapImageView, levelCount));
ANGLE_TRY(mImage.initImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mReadBaseLevelImageView, 1));
ANGLE_TRY(mImage.initImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
gl::SwizzleState(), &mDrawBaseLevelImageView, 1));
ANGLE_TRY(mImage->initImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mReadMipmapImageView, levelCount));
ANGLE_TRY(mImage->initImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mReadBaseLevelImageView, 1));
ANGLE_TRY(mImage->initImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
gl::SwizzleState(), &mDrawBaseLevelImageView, 1));
// TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
VkClearColorValue black = {{0, 0, 0, 1.0f}};
mImage.clearColor(black, 0, levelCount, commandBuffer);
mImage->clearColor(black, 0, levelCount, commandBuffer);
return angle::Result::Continue;
}
void TextureVk::releaseImage(RendererVk *renderer)
{
mImage.releaseImage(renderer);
if (mImage)
{
mImage->releaseImage(renderer);
}
Serial currentSerial = renderer->getCurrentQueueSerial();
......@@ -978,7 +1010,10 @@ void TextureVk::releaseImage(RendererVk *renderer)
void TextureVk::releaseStagingBuffer(RendererVk *renderer)
{
mImage.releaseStagingBuffer(renderer);
if (mImage)
{
mImage->releaseStagingBuffer(renderer);
}
}
uint32_t TextureVk::getLevelCount() const
......
......@@ -129,14 +129,14 @@ class TextureVk : public TextureImpl
const vk::ImageHelper &getImage() const
{
ASSERT(mImage.valid());
return mImage;
ASSERT(mImage && mImage->valid());
return *mImage;
}
vk::ImageHelper &getImage()
{
ASSERT(mImage.valid());
return mImage;
ASSERT(mImage && mImage->valid());
return *mImage;
}
const vk::ImageView &getReadImageView() const;
......@@ -149,6 +149,8 @@ class TextureVk : public TextureImpl
angle::Result ensureImageInitialized(ContextVk *contextVk);
private:
angle::Result ensureImageAllocated(RendererVk *renderer);
angle::Result redefineImage(const gl::Context *context,
const gl::ImageIndex &index,
const gl::InternalFormat &internalFormat,
......@@ -218,7 +220,7 @@ class TextureVk : public TextureImpl
uint32_t levelCount,
const vk::Format &format);
vk::ImageHelper mImage;
vk::ImageHelper *mImage;
vk::ImageView mDrawBaseLevelImageView;
vk::ImageView mReadBaseLevelImageView;
vk::ImageView mReadMipmapImageView;
......
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