From c1583a558c5898098423bc2de0b9da1ab04f4770 Mon Sep 17 00:00:00 2001 From: Idan Raiter <idanr@google.com> Date: Fri, 2 Aug 2019 05:16:42 +0000 Subject: [PATCH] Create CommandRecordingContext Adds a structure that contains wait / signal semaphores and the current command buffer. Will allow us to have a list of pending semaphores after recording, either to consume or do something smarter with in the future. Bug: chromium:976495 Change-Id: Ib61455039bd97ac8b0ff701af2b694cc8794226d Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/9600 Commit-Queue: Kai Ninomiya <kainino@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org> --- src/dawn_native/vulkan/BufferVk.cpp | 15 +++-- src/dawn_native/vulkan/BufferVk.h | 4 +- src/dawn_native/vulkan/CommandBufferVk.cpp | 66 +++++++++++-------- src/dawn_native/vulkan/CommandBufferVk.h | 8 ++- .../vulkan/CommandRecordingContext.h | 33 ++++++++++ src/dawn_native/vulkan/DeviceVk.cpp | 36 ++++++---- src/dawn_native/vulkan/DeviceVk.h | 6 +- .../vulkan/NativeSwapChainImplVk.cpp | 2 +- src/dawn_native/vulkan/QueueVk.cpp | 5 +- src/dawn_native/vulkan/SwapChainVk.cpp | 4 +- src/dawn_native/vulkan/TextureVk.cpp | 25 +++---- src/dawn_native/vulkan/TextureVk.h | 9 ++- 12 files changed, 141 insertions(+), 72 deletions(-) create mode 100644 src/dawn_native/vulkan/CommandRecordingContext.h diff --git a/src/dawn_native/vulkan/BufferVk.cpp b/src/dawn_native/vulkan/BufferVk.cpp index e7b3bea1e7..d1e6c62bb1 100644 --- a/src/dawn_native/vulkan/BufferVk.cpp +++ b/src/dawn_native/vulkan/BufferVk.cpp @@ -163,7 +163,8 @@ namespace dawn_native { namespace vulkan { return mHandle; } - void Buffer::TransitionUsageNow(VkCommandBuffer commands, dawn::BufferUsageBit usage) { + void Buffer::TransitionUsageNow(CommandRecordingContext* recordingContext, + dawn::BufferUsageBit usage) { bool lastIncludesTarget = (mLastUsage & usage) == usage; bool lastReadOnly = (mLastUsage & kReadOnlyBufferUsages) == mLastUsage; @@ -193,8 +194,8 @@ namespace dawn_native { namespace vulkan { barrier.size = GetSize(); ToBackend(GetDevice()) - ->fn.CmdPipelineBarrier(commands, srcStages, dstStages, 0, 0, nullptr, 1, &barrier, 0, - nullptr); + ->fn.CmdPipelineBarrier(recordingContext->commandBuffer, srcStages, dstStages, 0, 0, + nullptr, 1, &barrier, 0, nullptr); mLastUsage = usage; } @@ -212,8 +213,8 @@ namespace dawn_native { namespace vulkan { MaybeError Buffer::MapReadAsyncImpl(uint32_t serial) { Device* device = ToBackend(GetDevice()); - VkCommandBuffer commands = device->GetPendingCommandBuffer(); - TransitionUsageNow(commands, dawn::BufferUsageBit::MapRead); + CommandRecordingContext* recordingContext = device->GetPendingRecordingContext(); + TransitionUsageNow(recordingContext, dawn::BufferUsageBit::MapRead); uint8_t* memory = mMemoryAllocation.GetMappedPointer(); ASSERT(memory != nullptr); @@ -226,8 +227,8 @@ namespace dawn_native { namespace vulkan { MaybeError Buffer::MapWriteAsyncImpl(uint32_t serial) { Device* device = ToBackend(GetDevice()); - VkCommandBuffer commands = device->GetPendingCommandBuffer(); - TransitionUsageNow(commands, dawn::BufferUsageBit::MapWrite); + CommandRecordingContext* recordingContext = device->GetPendingRecordingContext(); + TransitionUsageNow(recordingContext, dawn::BufferUsageBit::MapWrite); uint8_t* memory = mMemoryAllocation.GetMappedPointer(); ASSERT(memory != nullptr); diff --git a/src/dawn_native/vulkan/BufferVk.h b/src/dawn_native/vulkan/BufferVk.h index 81d7a4e3ff..abf735daf5 100644 --- a/src/dawn_native/vulkan/BufferVk.h +++ b/src/dawn_native/vulkan/BufferVk.h @@ -23,6 +23,7 @@ namespace dawn_native { namespace vulkan { + struct CommandRecordingContext; class Device; class Buffer : public BufferBase { @@ -38,7 +39,8 @@ namespace dawn_native { namespace vulkan { // Transitions the buffer to be used as `usage`, recording any necessary barrier in // `commands`. // TODO(cwallez@chromium.org): coalesce barriers and do them early when possible. - void TransitionUsageNow(VkCommandBuffer commands, dawn::BufferUsageBit usage); + void TransitionUsageNow(CommandRecordingContext* recordingContext, + dawn::BufferUsageBit usage); private: // Dawn API diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp index c682a6d79f..1d626e03fa 100644 --- a/src/dawn_native/vulkan/CommandBufferVk.cpp +++ b/src/dawn_native/vulkan/CommandBufferVk.cpp @@ -18,6 +18,7 @@ #include "dawn_native/Commands.h" #include "dawn_native/vulkan/BindGroupVk.h" #include "dawn_native/vulkan/BufferVk.h" +#include "dawn_native/vulkan/CommandRecordingContext.h" #include "dawn_native/vulkan/ComputePipelineVk.h" #include "dawn_native/vulkan/DeviceVk.h" #include "dawn_native/vulkan/FencedDeleter.h" @@ -189,9 +190,11 @@ namespace dawn_native { namespace vulkan { std::array<std::array<uint32_t, kMaxBindingsPerGroup>, kMaxBindGroups> mDynamicOffsets; }; - void RecordBeginRenderPass(VkCommandBuffer commands, + void RecordBeginRenderPass(CommandRecordingContext* recordingContext, Device* device, BeginRenderPassCmd* renderPass) { + VkCommandBuffer commands = recordingContext->commandBuffer; + // Query a VkRenderPass from the cache VkRenderPass renderPassVK = VK_NULL_HANDLE; { @@ -232,7 +235,7 @@ namespace dawn_native { namespace vulkan { attachmentInfo.stencilLoadOp == dawn::LoadOp::Load) { ToBackend(attachmentInfo.view->GetTexture()) ->EnsureSubresourceContentInitialized( - commands, attachmentInfo.view->GetBaseMipLevel(), + recordingContext, attachmentInfo.view->GetBaseMipLevel(), attachmentInfo.view->GetLevelCount(), attachmentInfo.view->GetBaseArrayLayer(), attachmentInfo.view->GetLayerCount()); @@ -339,14 +342,16 @@ namespace dawn_native { namespace vulkan { FreeCommands(&mCommands); } - void CommandBuffer::RecordCommands(VkCommandBuffer commands) { + void CommandBuffer::RecordCommands(CommandRecordingContext* recordingContext) { Device* device = ToBackend(GetDevice()); + VkCommandBuffer commands = recordingContext->commandBuffer; // Records the necessary barriers for the resource usage pre-computed by the frontend - auto TransitionForPass = [](VkCommandBuffer commands, const PassResourceUsage& usages) { + auto TransitionForPass = [](CommandRecordingContext* recordingContext, + const PassResourceUsage& usages) { for (size_t i = 0; i < usages.buffers.size(); ++i) { Buffer* buffer = ToBackend(usages.buffers[i]); - buffer->TransitionUsageNow(commands, usages.bufferUsages[i]); + buffer->TransitionUsageNow(recordingContext, usages.bufferUsages[i]); } for (size_t i = 0; i < usages.textures.size(); ++i) { Texture* texture = ToBackend(usages.textures[i]); @@ -354,8 +359,8 @@ namespace dawn_native { namespace vulkan { // TODO(natlee@microsoft.com): Update clearing here when subresource tracking is // implemented texture->EnsureSubresourceContentInitialized( - commands, 0, texture->GetNumMipLevels(), 0, texture->GetArrayLayers()); - texture->TransitionUsageNow(commands, usages.textureUsages[i]); + recordingContext, 0, texture->GetNumMipLevels(), 0, texture->GetArrayLayers()); + texture->TransitionUsageNow(recordingContext, usages.textureUsages[i]); } }; @@ -370,8 +375,8 @@ namespace dawn_native { namespace vulkan { Buffer* srcBuffer = ToBackend(copy->source.Get()); Buffer* dstBuffer = ToBackend(copy->destination.Get()); - srcBuffer->TransitionUsageNow(commands, dawn::BufferUsageBit::CopySrc); - dstBuffer->TransitionUsageNow(commands, dawn::BufferUsageBit::CopyDst); + srcBuffer->TransitionUsageNow(recordingContext, dawn::BufferUsageBit::CopySrc); + dstBuffer->TransitionUsageNow(recordingContext, dawn::BufferUsageBit::CopyDst); VkBufferCopy region; region.srcOffset = copy->sourceOffset; @@ -399,13 +404,14 @@ namespace dawn_native { namespace vulkan { subresource.mipLevel, 1, subresource.baseArrayLayer, 1); } else { ToBackend(dst.texture) - ->EnsureSubresourceContentInitialized(commands, subresource.mipLevel, 1, + ->EnsureSubresourceContentInitialized(recordingContext, + subresource.mipLevel, 1, subresource.baseArrayLayer, 1); } ToBackend(src.buffer) - ->TransitionUsageNow(commands, dawn::BufferUsageBit::CopySrc); + ->TransitionUsageNow(recordingContext, dawn::BufferUsageBit::CopySrc); ToBackend(dst.texture) - ->TransitionUsageNow(commands, dawn::TextureUsageBit::CopyDst); + ->TransitionUsageNow(recordingContext, dawn::TextureUsageBit::CopyDst); VkBuffer srcBuffer = ToBackend(src.buffer)->GetHandle(); VkImage dstImage = ToBackend(dst.texture)->GetHandle(); @@ -426,13 +432,14 @@ namespace dawn_native { namespace vulkan { VkImageSubresourceLayers subresource = region.imageSubresource; ToBackend(src.texture) - ->EnsureSubresourceContentInitialized(commands, subresource.mipLevel, 1, + ->EnsureSubresourceContentInitialized(recordingContext, + subresource.mipLevel, 1, subresource.baseArrayLayer, 1); ToBackend(src.texture) - ->TransitionUsageNow(commands, dawn::TextureUsageBit::CopySrc); + ->TransitionUsageNow(recordingContext, dawn::TextureUsageBit::CopySrc); ToBackend(dst.buffer) - ->TransitionUsageNow(commands, dawn::BufferUsageBit::CopyDst); + ->TransitionUsageNow(recordingContext, dawn::BufferUsageBit::CopyDst); VkImage srcImage = ToBackend(src.texture)->GetHandle(); VkBuffer dstBuffer = ToBackend(dst.buffer)->GetHandle(); @@ -452,7 +459,8 @@ namespace dawn_native { namespace vulkan { VkImageSubresourceLayers srcSubresource = region.srcSubresource; ToBackend(src.texture) - ->EnsureSubresourceContentInitialized(commands, srcSubresource.mipLevel, 1, + ->EnsureSubresourceContentInitialized(recordingContext, + srcSubresource.mipLevel, 1, srcSubresource.baseArrayLayer, 1); if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize, dstSubresource.mipLevel)) { @@ -461,14 +469,14 @@ namespace dawn_native { namespace vulkan { dstSubresource.mipLevel, 1, dstSubresource.baseArrayLayer, 1); } else { ToBackend(dst.texture) - ->EnsureSubresourceContentInitialized(commands, dstSubresource.mipLevel, - 1, dstSubresource.baseArrayLayer, - 1); + ->EnsureSubresourceContentInitialized(recordingContext, + dstSubresource.mipLevel, 1, + dstSubresource.baseArrayLayer, 1); } ToBackend(src.texture) - ->TransitionUsageNow(commands, dawn::TextureUsageBit::CopySrc); + ->TransitionUsageNow(recordingContext, dawn::TextureUsageBit::CopySrc); ToBackend(dst.texture) - ->TransitionUsageNow(commands, dawn::TextureUsageBit::CopyDst); + ->TransitionUsageNow(recordingContext, dawn::TextureUsageBit::CopyDst); VkImage srcImage = ToBackend(src.texture)->GetHandle(); VkImage dstImage = ToBackend(dst.texture)->GetHandle(); @@ -481,8 +489,8 @@ namespace dawn_native { namespace vulkan { case Command::BeginRenderPass: { BeginRenderPassCmd* cmd = mCommands.NextCommand<BeginRenderPassCmd>(); - TransitionForPass(commands, passResourceUsages[nextPassNumber]); - RecordRenderPass(commands, cmd); + TransitionForPass(recordingContext, passResourceUsages[nextPassNumber]); + RecordRenderPass(recordingContext, cmd); nextPassNumber++; } break; @@ -490,8 +498,8 @@ namespace dawn_native { namespace vulkan { case Command::BeginComputePass: { mCommands.NextCommand<BeginComputePassCmd>(); - TransitionForPass(commands, passResourceUsages[nextPassNumber]); - RecordComputePass(commands); + TransitionForPass(recordingContext, passResourceUsages[nextPassNumber]); + RecordComputePass(recordingContext); nextPassNumber++; } break; @@ -501,8 +509,9 @@ namespace dawn_native { namespace vulkan { } } - void CommandBuffer::RecordComputePass(VkCommandBuffer commands) { + void CommandBuffer::RecordComputePass(CommandRecordingContext* recordingContext) { Device* device = ToBackend(GetDevice()); + VkCommandBuffer commands = recordingContext->commandBuffer; DescriptorSetTracker descriptorSets; @@ -558,11 +567,12 @@ namespace dawn_native { namespace vulkan { // EndComputePass should have been called UNREACHABLE(); } - void CommandBuffer::RecordRenderPass(VkCommandBuffer commands, + void CommandBuffer::RecordRenderPass(CommandRecordingContext* recordingContext, BeginRenderPassCmd* renderPassCmd) { Device* device = ToBackend(GetDevice()); + VkCommandBuffer commands = recordingContext->commandBuffer; - RecordBeginRenderPass(commands, device, renderPassCmd); + RecordBeginRenderPass(recordingContext, device, renderPassCmd); // Set the default value for the dynamic state { diff --git a/src/dawn_native/vulkan/CommandBufferVk.h b/src/dawn_native/vulkan/CommandBufferVk.h index a9608fed6e..6025eef04b 100644 --- a/src/dawn_native/vulkan/CommandBufferVk.h +++ b/src/dawn_native/vulkan/CommandBufferVk.h @@ -26,6 +26,7 @@ namespace dawn_native { namespace dawn_native { namespace vulkan { + struct CommandRecordingContext; class Device; class CommandBuffer : public CommandBufferBase { @@ -33,11 +34,12 @@ namespace dawn_native { namespace vulkan { CommandBuffer(CommandEncoderBase* encoder, const CommandBufferDescriptor* descriptor); ~CommandBuffer(); - void RecordCommands(VkCommandBuffer commands); + void RecordCommands(CommandRecordingContext* recordingContext); private: - void RecordComputePass(VkCommandBuffer commands); - void RecordRenderPass(VkCommandBuffer commands, BeginRenderPassCmd* renderPass); + void RecordComputePass(CommandRecordingContext* recordingContext); + void RecordRenderPass(CommandRecordingContext* recordingContext, + BeginRenderPassCmd* renderPass); CommandIterator mCommands; }; diff --git a/src/dawn_native/vulkan/CommandRecordingContext.h b/src/dawn_native/vulkan/CommandRecordingContext.h new file mode 100644 index 0000000000..5de9087397 --- /dev/null +++ b/src/dawn_native/vulkan/CommandRecordingContext.h @@ -0,0 +1,33 @@ +// Copyright 2019 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef DAWNNATIVE_VULKAN_COMMANDRECORDINGCONTEXT_H_ +#define DAWNNATIVE_VULKAN_COMMANDRECORDINGCONTEXT_H_ + +#include "common/vulkan_platform.h" + +#include <vector> + +namespace dawn_native { namespace vulkan { + + // Used to track operations that are handled after recording. + // Currently only tracks semaphores, but may be used to do barrier coalescing in the future. + struct CommandRecordingContext { + VkCommandBuffer commandBuffer = VK_NULL_HANDLE; + std::vector<VkSemaphore> waitSemaphores = {}; + std::vector<VkSemaphore> signalSemaphores = {}; + }; + +}} // namespace dawn_native::vulkan + +#endif // DAWNNATIVE_VULKAN_COMMANDRECORDINGCONTEXT_H_ diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp index 3d370e3284..94845c7191 100644 --- a/src/dawn_native/vulkan/DeviceVk.cpp +++ b/src/dawn_native/vulkan/DeviceVk.cpp @@ -108,7 +108,8 @@ namespace dawn_native { namespace vulkan { } mUnusedCommands.clear(); - ASSERT(mWaitSemaphores.empty()); + ASSERT(mRecordingContext.waitSemaphores.empty()); + ASSERT(mRecordingContext.signalSemaphores.empty()); for (VkFence fence : mUnusedFences) { fn.DestroyFence(mVkDevice, fence, nullptr); @@ -276,6 +277,14 @@ namespace dawn_native { namespace vulkan { return mPendingCommands.commandBuffer; } + CommandRecordingContext* Device::GetPendingRecordingContext() { + if (mRecordingContext.commandBuffer == VK_NULL_HANDLE) { + mRecordingContext.commandBuffer = GetPendingCommandBuffer(); + } + + return &mRecordingContext; + } + void Device::SubmitPendingCommands() { if (mPendingCommands.pool == VK_NULL_HANDLE) { return; @@ -285,19 +294,21 @@ namespace dawn_native { namespace vulkan { ASSERT(false); } - std::vector<VkPipelineStageFlags> dstStageMasks(mWaitSemaphores.size(), + std::vector<VkPipelineStageFlags> dstStageMasks(mRecordingContext.waitSemaphores.size(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); VkSubmitInfo submitInfo; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.pNext = nullptr; - submitInfo.waitSemaphoreCount = static_cast<uint32_t>(mWaitSemaphores.size()); - submitInfo.pWaitSemaphores = mWaitSemaphores.data(); + submitInfo.waitSemaphoreCount = + static_cast<uint32_t>(mRecordingContext.waitSemaphores.size()); + submitInfo.pWaitSemaphores = mRecordingContext.waitSemaphores.data(); submitInfo.pWaitDstStageMask = dstStageMasks.data(); submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &mPendingCommands.commandBuffer; - submitInfo.signalSemaphoreCount = 0; - submitInfo.pSignalSemaphores = 0; + submitInfo.signalSemaphoreCount = + static_cast<uint32_t>(mRecordingContext.signalSemaphores.size()); + submitInfo.pSignalSemaphores = mRecordingContext.signalSemaphores.data(); VkFence fence = GetUnusedFence(); if (fn.QueueSubmit(mQueue, 1, &submitInfo, fence) != VK_SUCCESS) { @@ -309,14 +320,15 @@ namespace dawn_native { namespace vulkan { mPendingCommands = CommandPoolAndBuffer(); mFencesInFlight.emplace(fence, mLastSubmittedSerial); - for (VkSemaphore semaphore : mWaitSemaphores) { + for (VkSemaphore semaphore : mRecordingContext.waitSemaphores) { mDeleter->DeleteWhenUnused(semaphore); } - mWaitSemaphores.clear(); - } - void Device::AddWaitSemaphore(VkSemaphore semaphore) { - mWaitSemaphores.push_back(semaphore); + for (VkSemaphore semaphore : mRecordingContext.signalSemaphores) { + mDeleter->DeleteWhenUnused(semaphore); + } + + mRecordingContext = CommandRecordingContext(); } ResultOrError<VulkanDeviceKnobs> Device::CreateDevice(VkPhysicalDevice physicalDevice) { @@ -529,7 +541,7 @@ namespace dawn_native { namespace vulkan { // Insert pipeline barrier to ensure correct ordering with previous memory operations on the // buffer. ToBackend(destination) - ->TransitionUsageNow(GetPendingCommandBuffer(), dawn::BufferUsageBit::CopyDst); + ->TransitionUsageNow(GetPendingRecordingContext(), dawn::BufferUsageBit::CopyDst); VkBufferCopy copy; copy.srcOffset = sourceOffset; diff --git a/src/dawn_native/vulkan/DeviceVk.h b/src/dawn_native/vulkan/DeviceVk.h index 7eb33620d6..be76c162d7 100644 --- a/src/dawn_native/vulkan/DeviceVk.h +++ b/src/dawn_native/vulkan/DeviceVk.h @@ -20,6 +20,7 @@ #include "common/Serial.h" #include "common/SerialQueue.h" #include "dawn_native/Device.h" +#include "dawn_native/vulkan/CommandRecordingContext.h" #include "dawn_native/vulkan/Forward.h" #include "dawn_native/vulkan/VulkanFunctions.h" #include "dawn_native/vulkan/VulkanInfo.h" @@ -59,9 +60,9 @@ namespace dawn_native { namespace vulkan { RenderPassCache* GetRenderPassCache() const; VkCommandBuffer GetPendingCommandBuffer(); + CommandRecordingContext* GetPendingRecordingContext(); Serial GetPendingCommandSerial() const override; void SubmitPendingCommands(); - void AddWaitSemaphore(VkSemaphore semaphore); // Dawn API CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder, @@ -142,7 +143,8 @@ namespace dawn_native { namespace vulkan { SerialQueue<CommandPoolAndBuffer> mCommandsInFlight; std::vector<CommandPoolAndBuffer> mUnusedCommands; CommandPoolAndBuffer mPendingCommands; - std::vector<VkSemaphore> mWaitSemaphores; + + CommandRecordingContext mRecordingContext; }; }} // namespace dawn_native::vulkan diff --git a/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp b/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp index 264ad32770..5f1e5ad39a 100644 --- a/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp +++ b/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp @@ -184,7 +184,7 @@ namespace dawn_native { namespace vulkan { } nextTexture->texture.u64 = mSwapChainImages[mLastImageIndex].GetU64(); - mDevice->AddWaitSemaphore(semaphore); + mDevice->GetPendingRecordingContext()->waitSemaphores.push_back(semaphore); return DAWN_SWAP_CHAIN_NO_ERROR; } diff --git a/src/dawn_native/vulkan/QueueVk.cpp b/src/dawn_native/vulkan/QueueVk.cpp index a5451b182b..c268bcd3d4 100644 --- a/src/dawn_native/vulkan/QueueVk.cpp +++ b/src/dawn_native/vulkan/QueueVk.cpp @@ -15,6 +15,7 @@ #include "dawn_native/vulkan/QueueVk.h" #include "dawn_native/vulkan/CommandBufferVk.h" +#include "dawn_native/vulkan/CommandRecordingContext.h" #include "dawn_native/vulkan/DeviceVk.h" namespace dawn_native { namespace vulkan { @@ -30,9 +31,9 @@ namespace dawn_native { namespace vulkan { device->Tick(); - VkCommandBuffer commandBuffer = device->GetPendingCommandBuffer(); + CommandRecordingContext* recordingContext = device->GetPendingRecordingContext(); for (uint32_t i = 0; i < commandCount; ++i) { - ToBackend(commands[i])->RecordCommands(commandBuffer); + ToBackend(commands[i])->RecordCommands(recordingContext); } device->SubmitPendingCommands(); diff --git a/src/dawn_native/vulkan/SwapChainVk.cpp b/src/dawn_native/vulkan/SwapChainVk.cpp index f4e857d4d8..37877b4161 100644 --- a/src/dawn_native/vulkan/SwapChainVk.cpp +++ b/src/dawn_native/vulkan/SwapChainVk.cpp @@ -51,8 +51,8 @@ namespace dawn_native { namespace vulkan { // Perform the necessary pipeline barriers for the texture to be used with the usage // requested by the implementation. - VkCommandBuffer commands = device->GetPendingCommandBuffer(); - ToBackend(texture)->TransitionUsageNow(commands, mTextureUsage); + CommandRecordingContext* recordingContext = device->GetPendingRecordingContext(); + ToBackend(texture)->TransitionUsageNow(recordingContext, mTextureUsage); device->SubmitPendingCommands(); } diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp index 7512712160..727292c946 100644 --- a/src/dawn_native/vulkan/TextureVk.cpp +++ b/src/dawn_native/vulkan/TextureVk.cpp @@ -15,6 +15,7 @@ #include "dawn_native/vulkan/TextureVk.h" #include "dawn_native/vulkan/AdapterVk.h" +#include "dawn_native/vulkan/CommandRecordingContext.h" #include "dawn_native/vulkan/DeviceVk.h" #include "dawn_native/vulkan/FencedDeleter.h" @@ -436,7 +437,7 @@ namespace dawn_native { namespace vulkan { range.levelCount = GetNumMipLevels(); range.baseArrayLayer = 0; range.layerCount = GetArrayLayers(); - TransitionUsageNow(ToBackend(GetDevice())->GetPendingCommandBuffer(), + TransitionUsageNow(ToBackend(GetDevice())->GetPendingRecordingContext(), dawn::TextureUsageBit::CopyDst); if (GetFormat().HasDepthOrStencil()) { @@ -494,7 +495,8 @@ namespace dawn_native { namespace vulkan { return VulkanAspectMask(GetFormat()); } - void Texture::TransitionUsageNow(VkCommandBuffer commands, dawn::TextureUsageBit usage) { + void Texture::TransitionUsageNow(CommandRecordingContext* recordingContext, + dawn::TextureUsageBit usage) { // Avoid encoding barriers when it isn't needed. bool lastReadOnly = (mLastUsage & kReadOnlyTextureUsages) == mLastUsage; if (lastReadOnly && mLastUsage == usage) { @@ -525,13 +527,13 @@ namespace dawn_native { namespace vulkan { barrier.subresourceRange.layerCount = GetArrayLayers(); ToBackend(GetDevice()) - ->fn.CmdPipelineBarrier(commands, srcStages, dstStages, 0, 0, nullptr, 0, nullptr, 1, - &barrier); + ->fn.CmdPipelineBarrier(recordingContext->commandBuffer, srcStages, dstStages, 0, 0, + nullptr, 0, nullptr, 1, &barrier); mLastUsage = usage; } - void Texture::ClearTexture(VkCommandBuffer commands, + void Texture::ClearTexture(CommandRecordingContext* recordingContext, uint32_t baseMipLevel, uint32_t levelCount, uint32_t baseArrayLayer, @@ -543,13 +545,13 @@ namespace dawn_native { namespace vulkan { range.baseArrayLayer = baseArrayLayer; range.layerCount = layerCount; - TransitionUsageNow(commands, dawn::TextureUsageBit::CopyDst); + TransitionUsageNow(recordingContext, dawn::TextureUsageBit::CopyDst); if (GetFormat().HasDepthOrStencil()) { VkClearDepthStencilValue clear_color[1]; clear_color[0].depth = 0.0f; clear_color[0].stencil = 0u; ToBackend(GetDevice()) - ->fn.CmdClearDepthStencilImage(commands, GetHandle(), + ->fn.CmdClearDepthStencilImage(recordingContext->commandBuffer, GetHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clear_color, 1, &range); } else { @@ -559,14 +561,15 @@ namespace dawn_native { namespace vulkan { clear_color[0].float32[2] = 0.0f; clear_color[0].float32[3] = 0.0f; ToBackend(GetDevice()) - ->fn.CmdClearColorImage(commands, GetHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - clear_color, 1, &range); + ->fn.CmdClearColorImage(recordingContext->commandBuffer, GetHandle(), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clear_color, 1, + &range); } SetIsSubresourceContentInitialized(baseMipLevel, levelCount, baseArrayLayer, layerCount); GetDevice()->IncrementLazyClearCountForTesting(); } - void Texture::EnsureSubresourceContentInitialized(VkCommandBuffer commands, + void Texture::EnsureSubresourceContentInitialized(CommandRecordingContext* recordingContext, uint32_t baseMipLevel, uint32_t levelCount, uint32_t baseArrayLayer, @@ -584,7 +587,7 @@ namespace dawn_native { namespace vulkan { // If subresource has not been initialized, clear it to black as it could contain dirty // bits from recycled memory - ClearTexture(commands, baseMipLevel, levelCount, baseArrayLayer, layerCount); + ClearTexture(recordingContext, baseMipLevel, levelCount, baseArrayLayer, layerCount); } } diff --git a/src/dawn_native/vulkan/TextureVk.h b/src/dawn_native/vulkan/TextureVk.h index 41cdf6d30a..9f716928c1 100644 --- a/src/dawn_native/vulkan/TextureVk.h +++ b/src/dawn_native/vulkan/TextureVk.h @@ -22,6 +22,8 @@ namespace dawn_native { namespace vulkan { + struct CommandRecordingContext; + VkFormat VulkanImageFormat(dawn::TextureFormat format); VkImageUsageFlags VulkanImageUsage(dawn::TextureUsageBit usage, const Format& format); VkSampleCountFlagBits VulkanSampleCount(uint32_t sampleCount); @@ -38,8 +40,9 @@ namespace dawn_native { namespace vulkan { // Transitions the texture to be used as `usage`, recording any necessary barrier in // `commands`. // TODO(cwallez@chromium.org): coalesce barriers and do them early when possible. - void TransitionUsageNow(VkCommandBuffer commands, dawn::TextureUsageBit usage); - void EnsureSubresourceContentInitialized(VkCommandBuffer commands, + void TransitionUsageNow(CommandRecordingContext* recordingContext, + dawn::TextureUsageBit usage); + void EnsureSubresourceContentInitialized(CommandRecordingContext* recordingContext, uint32_t baseMipLevel, uint32_t levelCount, uint32_t baseArrayLayer, @@ -47,7 +50,7 @@ namespace dawn_native { namespace vulkan { private: void DestroyImpl() override; - void ClearTexture(VkCommandBuffer commands, + void ClearTexture(CommandRecordingContext* recordingContext, uint32_t baseMipLevel, uint32_t levelCount, uint32_t baseArrayLayer,