Commit 858c1ccc by Jamie Madill Committed by Commit Bot

Vulkan: Move image layout into helper.

Now that we're using the helper everywhere, we can clean up the vk::Image class and move the layout tracking into ImageHelper. Bug: angleproject:2318 Change-Id: I9636835a2a3a76f181dac629bd4182bc5815cdee Reviewed-on: https://chromium-review.googlesource.com/980774 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org>
parent 24a3137a
......@@ -161,12 +161,7 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
RenderTargetVk *renderTarget = mRenderTargetCache.getDepthStencil();
renderTarget->resource->onWriteResource(writingNode, currentSerial);
renderTarget->image->getImage().changeLayoutWithStages(
aspectFlags, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleDepthStencilImage(renderTarget->image->getImage(), aspectFlags,
clearDepthStencilValue);
renderTarget->image->clearDepthStencil(aspectFlags, clearDepthStencilValue, commandBuffer);
if (!clearColor)
{
......@@ -191,13 +186,7 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
ASSERT(colorRenderTarget);
colorRenderTarget->resource->onWriteResource(writingNode, currentSerial);
colorRenderTarget->image->getImage().changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleColorImage(colorRenderTarget->image->getImage(),
contextVk->getClearColorValue().color);
colorRenderTarget->image->clearColor(contextVk->getClearColorValue().color, commandBuffer);
}
return gl::NoError();
......@@ -264,7 +253,6 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState);
ASSERT(renderTarget);
vk::Image &readImage = renderTarget->image->getImage();
vk::ImageHelper stagingImage;
ANGLE_TRY(stagingImage.init2DStaging(
device, renderer->getMemoryProperties(), renderTarget->image->getFormat(),
......@@ -273,33 +261,13 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
stagingImage.getImage().changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
commandBuffer);
readImage.changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
VkImageCopy region;
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.srcSubresource.mipLevel = 0;
region.srcSubresource.baseArrayLayer = 0;
region.srcSubresource.layerCount = 1;
region.srcOffset.x = area.x;
region.srcOffset.y = area.y;
region.srcOffset.z = 0;
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.dstSubresource.mipLevel = 0;
region.dstSubresource.baseArrayLayer = 0;
region.dstSubresource.layerCount = 1;
region.dstOffset.x = 0;
region.dstOffset.y = 0;
region.dstOffset.z = 0;
region.extent.width = area.width;
region.extent.height = area.height;
region.extent.depth = 1;
commandBuffer->copyImage(readImage, stagingImage.getImage(), 1, &region);
stagingImage.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
vk::ImageHelper::Copy(renderTarget->image, &stagingImage, gl::Offset(area.x, area.y, 0),
gl::Offset(), gl::Extents(area.width, area.height, 1),
VK_IMAGE_ASPECT_COLOR_BIT, commandBuffer);
// Triggers a full finish.
// TODO(jmadill): Don't block on asynchronous readback.
......@@ -590,7 +558,7 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
ASSERT(colorRenderTarget);
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
colorRenderTarget->image->getImage().changeLayoutWithStages(
colorRenderTarget->image->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
commandBuffer);
......@@ -606,7 +574,7 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
VkImageAspectFlags aspectFlags = (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
(format.stencilBits > 0 ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
depthStencilRenderTarget->image->getImage().changeLayoutWithStages(
depthStencilRenderTarget->image->changeLayoutWithStages(
aspectFlags, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
commandBuffer);
......
......@@ -870,7 +870,7 @@ vk::Error ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
const gl::State &glState = contextVk->getGLState();
const auto &completeTextures = glState.getCompleteTextureCache();
for (const auto &samplerBinding : mState.getSamplerBindings())
for (const gl::SamplerBinding &samplerBinding : mState.getSamplerBindings())
{
ASSERT(!samplerBinding.unreferenced);
......@@ -884,7 +884,7 @@ vk::Error ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
ASSERT(texture);
TextureVk *textureVk = vk::GetImpl(texture);
const vk::Image &image = textureVk->getImage();
const vk::ImageHelper &image = textureVk->getImage();
VkDescriptorImageInfo &imageInfo = descriptorImageInfo[imageCount];
......
......@@ -97,18 +97,13 @@ gl::Error RenderbufferVk::setStorage(const gl::Context *context,
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
mImage.getImage().changeLayoutWithStages(aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
if (isDepthOrStencilFormat)
{
commandBuffer->clearSingleDepthStencilImage(mImage.getImage(), aspect,
kDefaultClearDepthStencilValue);
mImage.clearDepthStencil(aspect, kDefaultClearDepthStencilValue, commandBuffer);
}
else
{
commandBuffer->clearSingleColorImage(mImage.getImage(), kBlackClearColorValue);
mImage.clearColor(kBlackClearColorValue, commandBuffer);
}
}
......
......@@ -203,7 +203,7 @@ void WindowSurfaceVk::destroy(const egl::Display *display)
for (SwapchainImage &swapchainImage : mSwapchainImages)
{
// Although we don't own the swapchain image handles, we need to keep our shutdown clean.
swapchainImage.image.getImage().reset();
swapchainImage.image.resetImageWeakReference();
swapchainImage.image.destroy(device);
swapchainImage.imageView.destroy(device);
swapchainImage.framebuffer.destroy(device);
......@@ -400,10 +400,7 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
&member.imageView);
// Set transfer dest layout, and clear the image to black.
member.image.getImage().changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleColorImage(member.image.getImage(), transparentBlack);
member.image.clearColor(transparentBlack, commandBuffer);
ANGLE_TRY(member.imageAcquiredSemaphore.init(device));
ANGLE_TRY(member.commandsCompleteSemaphore.init(device));
......@@ -432,11 +429,7 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
VkClearDepthStencilValue depthStencilClearValue = {1.0f, 0};
// Set transfer dest layout, and clear the image.
mDepthStencilImage.getImage().changeLayoutWithStages(
aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleDepthStencilImage(mDepthStencilImage.getImage(), aspect,
depthStencilClearValue);
mDepthStencilImage.clearDepthStencil(aspect, depthStencilClearValue, commandBuffer);
ANGLE_TRY(mDepthStencilImage.initImageView(device, aspect, gl::SwizzleState(),
&mDepthStencilImageView));
......@@ -466,9 +459,9 @@ egl::Error WindowSurfaceVk::swap(const gl::Context *context)
SwapchainImage &image = mSwapchainImages[mCurrentSwapchainImageIndex];
image.image.getImage().changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, swapCommands);
image.image.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, swapCommands);
ANGLE_TRY(
renderer->flush(context, image.imageAcquiredSemaphore, image.commandsCompleteSemaphore));
......
......@@ -141,10 +141,7 @@ gl::Error TextureVk::setImage(const gl::Context *context,
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
VkClearColorValue black = {{0}};
mImage.getImage().changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleColorImage(mImage.getImage(), black);
mImage.clearColor(black, commandBuffer);
}
if (!mSampler.valid())
......@@ -253,16 +250,8 @@ gl::Error TextureVk::setSubImageImpl(ContextVk *contextVk,
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
stagingImage.getImage().changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
mImage.getImage().changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
gl::Box wholeRegion(0, 0, 0, size.width, size.height, size.depth);
commandBuffer->copySingleImage(stagingImage.getImage(), mImage.getImage(), wholeRegion,
VK_IMAGE_ASPECT_COLOR_BIT);
vk::ImageHelper::Copy(&stagingImage, &mImage, gl::Offset(), gl::Offset(), size,
VK_IMAGE_ASPECT_COLOR_BIT, commandBuffer);
// Immediately release staging image.
// TODO(jmadill): Staging image re-use.
......@@ -403,10 +392,10 @@ gl::Error TextureVk::initializeContents(const gl::Context *context,
return gl::NoError();
}
const vk::Image &TextureVk::getImage() const
const vk::ImageHelper &TextureVk::getImage() const
{
ASSERT(mImage.valid());
return mImage.getImage();
return mImage;
}
const vk::ImageView &TextureVk::getImageView() const
......
......@@ -111,7 +111,7 @@ class TextureVk : public TextureImpl, public ResourceVk
gl::Error initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex) override;
const vk::Image &getImage() const;
const vk::ImageHelper &getImage() const;
const vk::ImageView &getImageView() const;
const vk::Sampler &getSampler() const;
......
......@@ -475,48 +475,25 @@ void CommandBuffer::copyBuffer(const VkBuffer &srcBuffer,
vkCmdCopyBuffer(mHandle, srcBuffer, destBuffer, regionCount, regions);
}
void CommandBuffer::clearSingleColorImage(const vk::Image &image, const VkClearColorValue &color)
void CommandBuffer::clearColorImage(const vk::Image &image,
VkImageLayout imageLayout,
const VkClearColorValue &color,
uint32_t rangeCount,
const VkImageSubresourceRange *ranges)
{
ASSERT(valid());
ASSERT(image.getCurrentLayout() == VK_IMAGE_LAYOUT_GENERAL ||
image.getCurrentLayout() == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkImageSubresourceRange range;
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
range.baseMipLevel = 0;
range.levelCount = 1;
range.baseArrayLayer = 0;
range.layerCount = 1;
vkCmdClearColorImage(mHandle, image.getHandle(), image.getCurrentLayout(), &color, 1, &range);
}
void CommandBuffer::clearSingleDepthStencilImage(const vk::Image &image,
VkImageAspectFlags aspectFlags,
const VkClearDepthStencilValue &depthStencil)
{
VkImageSubresourceRange clearRange = {
/*aspectMask*/ aspectFlags,
/*baseMipLevel*/ 0,
/*levelCount*/ 1,
/*baseArrayLayer*/ 0,
/*layerCount*/ 1,
};
clearDepthStencilImage(image, depthStencil, 1, &clearRange);
vkCmdClearColorImage(mHandle, image.getHandle(), imageLayout, &color, rangeCount, ranges);
}
void CommandBuffer::clearDepthStencilImage(const vk::Image &image,
VkImageLayout imageLayout,
const VkClearDepthStencilValue &depthStencil,
uint32_t rangeCount,
const VkImageSubresourceRange *ranges)
{
ASSERT(valid());
ASSERT(image.getCurrentLayout() == VK_IMAGE_LAYOUT_GENERAL ||
image.getCurrentLayout() == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
vkCmdClearDepthStencilImage(mHandle, image.getHandle(), image.getCurrentLayout(), &depthStencil,
rangeCount, ranges);
vkCmdClearDepthStencilImage(mHandle, image.getHandle(), imageLayout, &depthStencil, rangeCount,
ranges);
}
void CommandBuffer::clearAttachments(uint32_t attachmentCount,
......@@ -529,45 +506,16 @@ void CommandBuffer::clearAttachments(uint32_t attachmentCount,
vkCmdClearAttachments(mHandle, attachmentCount, attachments, rectCount, rects);
}
void CommandBuffer::copySingleImage(const vk::Image &srcImage,
const vk::Image &destImage,
const gl::Box &copyRegion,
VkImageAspectFlags aspectMask)
{
VkImageCopy region;
region.srcSubresource.aspectMask = aspectMask;
region.srcSubresource.mipLevel = 0;
region.srcSubresource.baseArrayLayer = 0;
region.srcSubresource.layerCount = 1;
region.srcOffset.x = copyRegion.x;
region.srcOffset.y = copyRegion.y;
region.srcOffset.z = copyRegion.z;
region.dstSubresource.aspectMask = aspectMask;
region.dstSubresource.mipLevel = 0;
region.dstSubresource.baseArrayLayer = 0;
region.dstSubresource.layerCount = 1;
region.dstOffset.x = copyRegion.x;
region.dstOffset.y = copyRegion.y;
region.dstOffset.z = copyRegion.z;
region.extent.width = copyRegion.width;
region.extent.height = copyRegion.height;
region.extent.depth = copyRegion.depth;
copyImage(srcImage, destImage, 1, &region);
}
void CommandBuffer::copyImage(const vk::Image &srcImage,
VkImageLayout srcImageLayout,
const vk::Image &dstImage,
VkImageLayout dstImageLayout,
uint32_t regionCount,
const VkImageCopy *regions)
{
ASSERT(valid() && srcImage.valid() && dstImage.valid());
ASSERT(srcImage.getCurrentLayout() == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
srcImage.getCurrentLayout() == VK_IMAGE_LAYOUT_GENERAL);
ASSERT(dstImage.getCurrentLayout() == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
dstImage.getCurrentLayout() == VK_IMAGE_LAYOUT_GENERAL);
vkCmdCopyImage(mHandle, srcImage.getHandle(), srcImage.getCurrentLayout(), dstImage.getHandle(),
dstImage.getCurrentLayout(), 1, regions);
vkCmdCopyImage(mHandle, srcImage.getHandle(), srcImageLayout, dstImage.getHandle(),
dstImageLayout, 1, regions);
}
void CommandBuffer::beginRenderPass(const VkRenderPassBeginInfo &beginInfo,
......@@ -647,7 +595,7 @@ void CommandBuffer::executeCommands(uint32_t commandBufferCount,
}
// Image implementation.
Image::Image() : mCurrentLayout(VK_IMAGE_LAYOUT_UNDEFINED)
Image::Image()
{
}
......@@ -674,75 +622,9 @@ Error Image::init(VkDevice device, const VkImageCreateInfo &createInfo)
{
ASSERT(!valid());
ANGLE_VK_TRY(vkCreateImage(device, &createInfo, nullptr, &mHandle));
mCurrentLayout = createInfo.initialLayout;
return NoError();
}
void Image::changeLayoutTop(VkImageAspectFlags aspectMask,
VkImageLayout newLayout,
CommandBuffer *commandBuffer)
{
if (newLayout == mCurrentLayout)
{
// No-op.
return;
}
changeLayoutWithStages(aspectMask, newLayout, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, commandBuffer);
}
void Image::changeLayoutWithStages(VkImageAspectFlags aspectMask,
VkImageLayout newLayout,
VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
CommandBuffer *commandBuffer)
{
VkImageMemoryBarrier imageMemoryBarrier;
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemoryBarrier.pNext = nullptr;
imageMemoryBarrier.srcAccessMask = 0;
imageMemoryBarrier.dstAccessMask = 0;
imageMemoryBarrier.oldLayout = mCurrentLayout;
imageMemoryBarrier.newLayout = newLayout;
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
imageMemoryBarrier.image = mHandle;
// TODO(jmadill): Is this needed for mipped/layer images?
imageMemoryBarrier.subresourceRange.aspectMask = aspectMask;
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
imageMemoryBarrier.subresourceRange.levelCount = 1;
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = 1;
// TODO(jmadill): Test all the permutations of the access flags.
imageMemoryBarrier.srcAccessMask = GetBasicLayoutAccessFlags(mCurrentLayout);
if (mCurrentLayout == VK_IMAGE_LAYOUT_PREINITIALIZED)
{
imageMemoryBarrier.srcAccessMask |= VK_ACCESS_HOST_WRITE_BIT;
}
imageMemoryBarrier.dstAccessMask = GetBasicLayoutAccessFlags(newLayout);
if (newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
{
imageMemoryBarrier.srcAccessMask |=
(VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT);
imageMemoryBarrier.dstAccessMask |= VK_ACCESS_SHADER_READ_BIT;
}
if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
{
imageMemoryBarrier.dstAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
}
commandBuffer->singleImageBarrier(srcStageMask, dstStageMask, 0, imageMemoryBarrier);
mCurrentLayout = newLayout;
}
void Image::getMemoryRequirements(VkDevice device, VkMemoryRequirements *requirementsOut) const
{
ASSERT(valid());
......@@ -760,7 +642,7 @@ void Image::getSubresourceLayout(VkDevice device,
VkImageAspectFlagBits aspectMask,
uint32_t mipLevel,
uint32_t arrayLayer,
VkSubresourceLayout *outSubresourceLayout)
VkSubresourceLayout *outSubresourceLayout) const
{
VkImageSubresource subresource;
subresource.aspectMask = aspectMask;
......@@ -869,7 +751,7 @@ Error DeviceMemory::map(VkDevice device,
VkDeviceSize offset,
VkDeviceSize size,
VkMemoryMapFlags flags,
uint8_t **mapPointer)
uint8_t **mapPointer) const
{
ASSERT(valid());
ANGLE_VK_TRY(
......@@ -877,7 +759,7 @@ Error DeviceMemory::map(VkDevice device,
return NoError();
}
void DeviceMemory::unmap(VkDevice device)
void DeviceMemory::unmap(VkDevice device) const
{
ASSERT(valid());
vkUnmapMemory(device, mHandle);
......@@ -1421,7 +1303,11 @@ void LineLoopHandler::onSubjectStateChange(const gl::Context *context,
}
// ImageHelper implementation.
ImageHelper::ImageHelper() : mFormat(nullptr), mSamples(0), mAllocatedMemorySize(0)
ImageHelper::ImageHelper()
: mFormat(nullptr),
mSamples(0),
mAllocatedMemorySize(0),
mCurrentLayout(VK_IMAGE_LAYOUT_UNDEFINED)
{
}
......@@ -1431,7 +1317,8 @@ ImageHelper::ImageHelper(ImageHelper &&other)
mExtents(other.mExtents),
mFormat(other.mFormat),
mSamples(other.mSamples),
mAllocatedMemorySize(other.mAllocatedMemorySize)
mAllocatedMemorySize(other.mAllocatedMemorySize),
mCurrentLayout(other.mCurrentLayout)
{
}
......@@ -1476,6 +1363,8 @@ Error ImageHelper::init2D(VkDevice device,
imageInfo.pQueueFamilyIndices = nullptr;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
mCurrentLayout = VK_IMAGE_LAYOUT_UNDEFINED;
ANGLE_TRY(mImage.init(device, imageInfo));
return NoError();
}
......@@ -1486,6 +1375,11 @@ void ImageHelper::release(Serial serial, RendererVk *renderer)
renderer->releaseObject(serial, &mDeviceMemory);
}
void ImageHelper::resetImageWeakReference()
{
mImage.reset();
}
Error ImageHelper::initMemory(VkDevice device,
const MemoryProperties &memoryProperties,
VkMemoryPropertyFlags flags)
......@@ -1556,8 +1450,8 @@ Error ImageHelper::init2DStaging(VkDevice device,
// Use Preinitialized for writable staging images - in these cases we want to map the memory
// before we do a copy. For readback images, use an undefined layout.
VkImageLayout initialLayout = usage == vk::StagingUsage::Read ? VK_IMAGE_LAYOUT_UNDEFINED
: VK_IMAGE_LAYOUT_PREINITIALIZED;
mCurrentLayout = usage == vk::StagingUsage::Read ? VK_IMAGE_LAYOUT_UNDEFINED
: VK_IMAGE_LAYOUT_PREINITIALIZED;
VkImageCreateInfo imageInfo;
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
......@@ -1576,7 +1470,7 @@ Error ImageHelper::init2DStaging(VkDevice device,
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageInfo.queueFamilyIndexCount = 0;
imageInfo.pQueueFamilyIndices = nullptr;
imageInfo.initialLayout = initialLayout;
imageInfo.initialLayout = mCurrentLayout;
ANGLE_TRY(mImage.init(device, imageInfo));
......@@ -1598,21 +1492,11 @@ void ImageHelper::dumpResources(Serial serial, std::vector<vk::GarbageObject> *g
mDeviceMemory.dumpResources(serial, garbageQueue);
}
Image &ImageHelper::getImage()
{
return mImage;
}
const Image &ImageHelper::getImage() const
{
return mImage;
}
DeviceMemory &ImageHelper::getDeviceMemory()
{
return mDeviceMemory;
}
const DeviceMemory &ImageHelper::getDeviceMemory() const
{
return mDeviceMemory;
......@@ -1638,6 +1522,146 @@ size_t ImageHelper::getAllocatedMemorySize() const
return mAllocatedMemorySize;
}
void ImageHelper::changeLayoutWithStages(VkImageAspectFlags aspectMask,
VkImageLayout newLayout,
VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
CommandBuffer *commandBuffer)
{
VkImageMemoryBarrier imageMemoryBarrier;
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemoryBarrier.pNext = nullptr;
imageMemoryBarrier.srcAccessMask = 0;
imageMemoryBarrier.dstAccessMask = 0;
imageMemoryBarrier.oldLayout = mCurrentLayout;
imageMemoryBarrier.newLayout = newLayout;
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
imageMemoryBarrier.image = mImage.getHandle();
// TODO(jmadill): Is this needed for mipped/layer images?
imageMemoryBarrier.subresourceRange.aspectMask = aspectMask;
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
imageMemoryBarrier.subresourceRange.levelCount = 1;
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = 1;
// TODO(jmadill): Test all the permutations of the access flags.
imageMemoryBarrier.srcAccessMask = GetBasicLayoutAccessFlags(mCurrentLayout);
if (mCurrentLayout == VK_IMAGE_LAYOUT_PREINITIALIZED)
{
imageMemoryBarrier.srcAccessMask |= VK_ACCESS_HOST_WRITE_BIT;
}
imageMemoryBarrier.dstAccessMask = GetBasicLayoutAccessFlags(newLayout);
if (newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
{
imageMemoryBarrier.srcAccessMask |=
(VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT);
imageMemoryBarrier.dstAccessMask |= VK_ACCESS_SHADER_READ_BIT;
}
if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
{
imageMemoryBarrier.dstAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
}
commandBuffer->singleImageBarrier(srcStageMask, dstStageMask, 0, imageMemoryBarrier);
mCurrentLayout = newLayout;
}
void ImageHelper::clearColor(const VkClearColorValue &color, CommandBuffer *commandBuffer)
{
ASSERT(valid());
changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
commandBuffer);
VkImageSubresourceRange range;
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
range.baseMipLevel = 0;
range.levelCount = 1;
range.baseArrayLayer = 0;
range.layerCount = 1;
commandBuffer->clearColorImage(mImage, mCurrentLayout, color, 1, &range);
}
void ImageHelper::clearDepthStencil(VkImageAspectFlags aspectFlags,
const VkClearDepthStencilValue &depthStencil,
CommandBuffer *commandBuffer)
{
ASSERT(valid());
changeLayoutWithStages(aspectFlags, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
commandBuffer);
VkImageSubresourceRange clearRange = {
/*aspectMask*/ aspectFlags,
/*baseMipLevel*/ 0,
/*levelCount*/ 1,
/*baseArrayLayer*/ 0,
/*layerCount*/ 1,
};
commandBuffer->clearDepthStencilImage(mImage, mCurrentLayout, depthStencil, 1, &clearRange);
}
// static
void ImageHelper::Copy(vk::ImageHelper *srcImage,
vk::ImageHelper *dstImage,
const gl::Offset &srcOffset,
const gl::Offset &dstOffset,
const gl::Extents &copySize,
VkImageAspectFlags aspectMask,
CommandBuffer *commandBuffer)
{
ASSERT(commandBuffer->valid() && srcImage->valid() && dstImage->valid());
if (srcImage->getCurrentLayout() != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL &&
srcImage->getCurrentLayout() != VK_IMAGE_LAYOUT_GENERAL)
{
srcImage->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
}
if (dstImage->getCurrentLayout() != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
dstImage->getCurrentLayout() != VK_IMAGE_LAYOUT_GENERAL)
{
dstImage->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
}
VkImageCopy region;
region.srcSubresource.aspectMask = aspectMask;
region.srcSubresource.mipLevel = 0;
region.srcSubresource.baseArrayLayer = 0;
region.srcSubresource.layerCount = 1;
region.srcOffset.x = srcOffset.x;
region.srcOffset.y = srcOffset.y;
region.srcOffset.z = srcOffset.z;
region.dstSubresource.aspectMask = aspectMask;
region.dstSubresource.mipLevel = 0;
region.dstSubresource.baseArrayLayer = 0;
region.dstSubresource.layerCount = 1;
region.dstOffset.x = dstOffset.x;
region.dstOffset.y = dstOffset.y;
region.dstOffset.z = dstOffset.z;
region.extent.width = copySize.width;
region.extent.height = copySize.height;
region.extent.depth = copySize.depth;
commandBuffer->copyImage(srcImage->getImage(), srcImage->getCurrentLayout(),
dstImage->getImage(), dstImage->getCurrentLayout(), 1, &region);
}
} // namespace vk
namespace gl_vk
......
......@@ -251,7 +251,7 @@ class WrappedObject : angle::NonCopyable
const HandleT *ptr() const { return &mHandle; }
void dumpResources(Serial serial, std::vector<vk::GarbageObject> *garbageQueue)
void dumpResources(Serial serial, std::vector<GarbageObject> *garbageQueue)
{
if (valid())
{
......@@ -311,7 +311,7 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
CommandBuffer();
VkCommandBuffer releaseHandle();
void destroy(VkDevice device, const vk::CommandPool &commandPool);
void destroy(VkDevice device, const CommandPool &commandPool);
Error init(VkDevice device, const VkCommandBufferAllocateInfo &createInfo);
using WrappedObject::operator=;
......@@ -330,13 +330,13 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
VkDependencyFlags dependencyFlags,
const VkBufferMemoryBarrier &bufferBarrier);
void clearSingleColorImage(const vk::Image &image, const VkClearColorValue &color);
void clearSingleDepthStencilImage(const vk::Image &image,
VkImageAspectFlags aspectFlags,
const VkClearDepthStencilValue &depthStencil);
void clearDepthStencilImage(const vk::Image &image,
void clearColorImage(const Image &image,
VkImageLayout imageLayout,
const VkClearColorValue &color,
uint32_t rangeCount,
const VkImageSubresourceRange *ranges);
void clearDepthStencilImage(const Image &image,
VkImageLayout imageLayout,
const VkClearDepthStencilValue &depthStencil,
uint32_t rangeCount,
const VkImageSubresourceRange *ranges);
......@@ -346,8 +346,8 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
uint32_t rectCount,
const VkClearRect *rects);
void copyBuffer(const vk::Buffer &srcBuffer,
const vk::Buffer &destBuffer,
void copyBuffer(const Buffer &srcBuffer,
const Buffer &destBuffer,
uint32_t regionCount,
const VkBufferCopy *regions);
......@@ -356,13 +356,10 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
uint32_t regionCount,
const VkBufferCopy *regions);
void copySingleImage(const vk::Image &srcImage,
const vk::Image &destImage,
const gl::Box &copyRegion,
VkImageAspectFlags aspectMask);
void copyImage(const vk::Image &srcImage,
const vk::Image &dstImage,
void copyImage(const Image &srcImage,
VkImageLayout srcImageLayout,
const Image &dstImage,
VkImageLayout dstImageLayout,
uint32_t regionCount,
const VkImageCopy *regions);
......@@ -380,21 +377,21 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
int32_t vertexOffset,
uint32_t firstInstance);
void bindPipeline(VkPipelineBindPoint pipelineBindPoint, const vk::Pipeline &pipeline);
void bindPipeline(VkPipelineBindPoint pipelineBindPoint, const Pipeline &pipeline);
void bindVertexBuffers(uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer *buffers,
const VkDeviceSize *offsets);
void bindIndexBuffer(const VkBuffer &buffer, VkDeviceSize offset, VkIndexType indexType);
void bindDescriptorSets(VkPipelineBindPoint bindPoint,
const vk::PipelineLayout &layout,
const PipelineLayout &layout,
uint32_t firstSet,
uint32_t descriptorSetCount,
const VkDescriptorSet *descriptorSets,
uint32_t dynamicOffsetCount,
const uint32_t *dynamicOffsets);
void executeCommands(uint32_t commandBufferCount, const vk::CommandBuffer *commandBuffers);
void executeCommands(uint32_t commandBufferCount, const CommandBuffer *commandBuffers);
};
class Image final : public WrappedObject<Image, VkImage>
......@@ -413,29 +410,14 @@ class Image final : public WrappedObject<Image, VkImage>
Error init(VkDevice device, const VkImageCreateInfo &createInfo);
void changeLayoutTop(VkImageAspectFlags aspectMask,
VkImageLayout newLayout,
CommandBuffer *commandBuffer);
void changeLayoutWithStages(VkImageAspectFlags aspectMask,
VkImageLayout newLayout,
VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
CommandBuffer *commandBuffer);
void getMemoryRequirements(VkDevice device, VkMemoryRequirements *requirementsOut) const;
Error bindMemory(VkDevice device, const vk::DeviceMemory &deviceMemory);
Error bindMemory(VkDevice device, const DeviceMemory &deviceMemory);
VkImageLayout getCurrentLayout() const { return mCurrentLayout; }
void getSubresourceLayout(VkDevice device,
VkImageAspectFlagBits aspectMask,
uint32_t mipLevel,
uint32_t arrayLayer,
VkSubresourceLayout *outSubresourceLayout);
void updateLayout(VkImageLayout layout) { mCurrentLayout = layout; }
private:
VkImageLayout mCurrentLayout;
VkSubresourceLayout *outSubresourceLayout) const;
};
class ImageView final : public WrappedObject<ImageView, VkImageView>
......@@ -479,8 +461,8 @@ class DeviceMemory final : public WrappedObject<DeviceMemory, VkDeviceMemory>
VkDeviceSize offset,
VkDeviceSize size,
VkMemoryMapFlags flags,
uint8_t **mapPointer);
void unmap(VkDevice device);
uint8_t **mapPointer) const;
void unmap(VkDevice device) const;
};
class RenderPass final : public WrappedObject<RenderPass, VkRenderPass>
......@@ -588,7 +570,7 @@ class StagingBuffer final : angle::NonCopyable
StagingBuffer();
void destroy(VkDevice device);
vk::Error init(ContextVk *contextVk, VkDeviceSize size, StagingUsage usage);
Error init(ContextVk *contextVk, VkDeviceSize size, StagingUsage usage);
Buffer &getBuffer() { return mBuffer; }
const Buffer &getBuffer() const { return mBuffer; }
......@@ -596,7 +578,7 @@ class StagingBuffer final : angle::NonCopyable
const DeviceMemory &getDeviceMemory() const { return mDeviceMemory; }
size_t getSize() const { return mSize; }
void dumpResources(Serial serial, std::vector<vk::GarbageObject> *garbageQueue);
void dumpResources(Serial serial, std::vector<GarbageObject> *garbageQueue);
private:
Buffer mBuffer;
......@@ -649,8 +631,8 @@ Error AllocateBufferMemory(RendererVk *renderer,
struct BufferAndMemory final : private angle::NonCopyable
{
vk::Buffer buffer;
vk::DeviceMemory memory;
Buffer buffer;
DeviceMemory memory;
};
Error AllocateImageMemory(RendererVk *renderer,
......@@ -670,7 +652,7 @@ class LineLoopHandler final : angle::NonCopyable, angle::ObserverInterface
LineLoopHandler();
~LineLoopHandler();
void bindIndexBuffer(VkIndexType indexType, vk::CommandBuffer **commandBuffer);
void bindIndexBuffer(VkIndexType indexType, CommandBuffer **commandBuffer);
gl::Error createIndexBuffer(ContextVk *contextVk, int firstVertex, int count);
gl::Error createIndexBufferFromElementArrayBuffer(ContextVk *contextVk,
......@@ -711,10 +693,6 @@ class ImageHelper final : angle::NonCopyable
const Format &format,
GLint samples,
VkImageUsageFlags usage);
void init2DWeakReference(VkImage handle,
const gl::Extents &extents,
const Format &format,
GLint samples);
Error initMemory(VkDevice device,
const MemoryProperties &memoryProperties,
VkMemoryPropertyFlags flags);
......@@ -730,11 +708,15 @@ class ImageHelper final : angle::NonCopyable
void release(Serial serial, RendererVk *renderer);
void destroy(VkDevice device);
void dumpResources(Serial serial, std::vector<vk::GarbageObject> *garbageQueue);
void dumpResources(Serial serial, std::vector<GarbageObject> *garbageQueue);
void init2DWeakReference(VkImage handle,
const gl::Extents &extents,
const Format &format,
GLint samples);
void resetImageWeakReference();
Image &getImage();
const Image &getImage() const;
DeviceMemory &getDeviceMemory();
const DeviceMemory &getDeviceMemory() const;
const gl::Extents &getExtents() const;
......@@ -742,6 +724,29 @@ class ImageHelper final : angle::NonCopyable
GLint getSamples() const;
size_t getAllocatedMemorySize() const;
VkImageLayout getCurrentLayout() const { return mCurrentLayout; }
void updateLayout(VkImageLayout layout) { mCurrentLayout = layout; }
void changeLayoutWithStages(VkImageAspectFlags aspectMask,
VkImageLayout newLayout,
VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
CommandBuffer *commandBuffer);
void clearColor(const VkClearColorValue &color, CommandBuffer *commandBuffer);
void clearDepthStencil(VkImageAspectFlags aspectFlags,
const VkClearDepthStencilValue &depthStencil,
CommandBuffer *commandBuffer);
static void Copy(ImageHelper *srcImage,
ImageHelper *dstImage,
const gl::Offset &srcOffset,
const gl::Offset &dstOffset,
const gl::Extents &copySize,
VkImageAspectFlags aspectMask,
CommandBuffer *commandBuffer);
private:
// Vulkan objects.
Image mImage;
......@@ -752,6 +757,9 @@ class ImageHelper final : angle::NonCopyable
const Format *mFormat;
GLint mSamples;
size_t mAllocatedMemorySize;
// Current state.
VkImageLayout mCurrentLayout;
};
} // namespace vk
......
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