Commit bea35a63 by Jamie Madill Committed by Commit Bot

Vulkan: Use Scoped resource init helper.

In a few places we initialize resource on the stack in the Vulkan back-end. When we do this we should use a RAII wrapper so that if we generate an error and unwind the stack we can auto-release the object. This fixes a bug that was being triggered by an unexpected failure on Present with the Vulkan back-end on Intel. There are several other places in the code that should be modified to use the new wrapper. Bug: angleproject:2690 Change-Id: I49a1c5516756f8b7dba833aca65926aa7b8bd5c6 Reviewed-on: https://chromium-review.googlesource.com/1118610 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 072c3519
...@@ -180,6 +180,12 @@ RendererVk::CommandBatch &RendererVk::CommandBatch::operator=(CommandBatch &&oth ...@@ -180,6 +180,12 @@ RendererVk::CommandBatch &RendererVk::CommandBatch::operator=(CommandBatch &&oth
return *this; return *this;
} }
void RendererVk::CommandBatch::destroy(VkDevice device)
{
commandPool.destroy(device);
fence.destroy(device);
}
// RendererVk implementation. // RendererVk implementation.
RendererVk::RendererVk() RendererVk::RendererVk()
: mCapsInitialized(false), : mCapsInitialized(false),
...@@ -737,7 +743,8 @@ vk::Error RendererVk::submitFrame(const VkSubmitInfo &submitInfo, vk::CommandBuf ...@@ -737,7 +743,8 @@ vk::Error RendererVk::submitFrame(const VkSubmitInfo &submitInfo, vk::CommandBuf
fenceInfo.pNext = nullptr; fenceInfo.pNext = nullptr;
fenceInfo.flags = 0; fenceInfo.flags = 0;
CommandBatch batch; vk::Scoped<CommandBatch> scopedBatch(mDevice);
CommandBatch &batch = scopedBatch.get();
ANGLE_TRY(batch.fence.init(mDevice, fenceInfo)); ANGLE_TRY(batch.fence.init(mDevice, fenceInfo));
ANGLE_VK_TRY(vkQueueSubmit(mQueue, 1, &submitInfo, batch.fence.getHandle())); ANGLE_VK_TRY(vkQueueSubmit(mQueue, 1, &submitInfo, batch.fence.getHandle()));
...@@ -746,7 +753,7 @@ vk::Error RendererVk::submitFrame(const VkSubmitInfo &submitInfo, vk::CommandBuf ...@@ -746,7 +753,7 @@ vk::Error RendererVk::submitFrame(const VkSubmitInfo &submitInfo, vk::CommandBuf
batch.commandPool = std::move(mCommandPool); batch.commandPool = std::move(mCommandPool);
batch.serial = mCurrentQueueSerial; batch.serial = mCurrentQueueSerial;
mInFlightCommands.emplace_back(std::move(batch)); mInFlightCommands.emplace_back(scopedBatch.release());
// Sanity check. // Sanity check.
ASSERT(mInFlightCommands.size() < 1000u); ASSERT(mInFlightCommands.size() < 1000u);
...@@ -818,8 +825,8 @@ vk::Error RendererVk::flush(const gl::Context *context, ...@@ -818,8 +825,8 @@ vk::Error RendererVk::flush(const gl::Context *context,
const vk::Semaphore &waitSemaphore, const vk::Semaphore &waitSemaphore,
const vk::Semaphore &signalSemaphore) const vk::Semaphore &signalSemaphore)
{ {
vk::CommandBuffer commandBatch; vk::Scoped<vk::CommandBuffer> commandBatch(mDevice);
ANGLE_TRY(flushCommandGraph(context, &commandBatch)); ANGLE_TRY(flushCommandGraph(context, &commandBatch.get()));
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
...@@ -830,11 +837,11 @@ vk::Error RendererVk::flush(const gl::Context *context, ...@@ -830,11 +837,11 @@ vk::Error RendererVk::flush(const gl::Context *context,
submitInfo.pWaitSemaphores = waitSemaphore.ptr(); submitInfo.pWaitSemaphores = waitSemaphore.ptr();
submitInfo.pWaitDstStageMask = &waitStageMask; submitInfo.pWaitDstStageMask = &waitStageMask;
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = commandBatch.ptr(); submitInfo.pCommandBuffers = commandBatch.get().ptr();
submitInfo.signalSemaphoreCount = 1; submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphore.ptr(); submitInfo.pSignalSemaphores = signalSemaphore.ptr();
ANGLE_TRY(submitFrame(submitInfo, std::move(commandBatch))); ANGLE_TRY(submitFrame(submitInfo, commandBatch.release()));
return vk::NoError(); return vk::NoError();
} }
......
...@@ -179,6 +179,8 @@ class RendererVk : angle::NonCopyable ...@@ -179,6 +179,8 @@ class RendererVk : angle::NonCopyable
CommandBatch(CommandBatch &&other); CommandBatch(CommandBatch &&other);
CommandBatch &operator=(CommandBatch &&other); CommandBatch &operator=(CommandBatch &&other);
void destroy(VkDevice device);
vk::CommandPool commandPool; vk::CommandPool commandPool;
vk::Fence fence; vk::Fence fence;
Serial serial; Serial serial;
......
...@@ -445,6 +445,11 @@ void CommandBuffer::singleBufferBarrier(VkPipelineStageFlags srcStageMask, ...@@ -445,6 +445,11 @@ void CommandBuffer::singleBufferBarrier(VkPipelineStageFlags srcStageMask,
&bufferBarrier, 0, nullptr); &bufferBarrier, 0, nullptr);
} }
void CommandBuffer::destroy(VkDevice device)
{
releaseHandle();
}
void CommandBuffer::destroy(VkDevice device, const vk::CommandPool &commandPool) void CommandBuffer::destroy(VkDevice device, const vk::CommandPool &commandPool)
{ {
if (valid()) if (valid())
......
...@@ -314,7 +314,13 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer> ...@@ -314,7 +314,13 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
CommandBuffer(); CommandBuffer();
VkCommandBuffer releaseHandle(); VkCommandBuffer releaseHandle();
// This is used for normal pool allocated command buffers. It reset the handle.
void destroy(VkDevice device);
// This is used in conjunction with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT.
void destroy(VkDevice device, const CommandPool &commandPool); void destroy(VkDevice device, const CommandPool &commandPool);
Error init(VkDevice device, const VkCommandBufferAllocateInfo &createInfo); Error init(VkDevice device, const VkCommandBufferAllocateInfo &createInfo);
void blitImage(const Image &srcImage, void blitImage(const Image &srcImage,
VkImageLayout srcImageLayout, VkImageLayout srcImageLayout,
...@@ -697,6 +703,25 @@ enum class RecordingMode ...@@ -697,6 +703,25 @@ enum class RecordingMode
Start, Start,
Append, Append,
}; };
// Helper class to handle RAII patterns for initialization. Requires that T have a destroy method
// that takes a VkDevice and returns void.
template <typename T>
class Scoped final : angle::NonCopyable
{
public:
Scoped(VkDevice device) : mDevice(device) {}
~Scoped() { mVar.destroy(mDevice); }
const T &get() const { return mVar; }
T &get() { return mVar; }
T &&release() { return std::move(mVar); }
private:
VkDevice mDevice;
T mVar;
};
} // namespace vk } // namespace vk
namespace gl_vk namespace gl_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