device/commands.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // SPDX-License-Identifier: BSD-3-Clause | ||
| 2 | /// @file commands.cpp | ||
| 3 | /// @brief Recording copies and buffer writes on Vulkan. | ||
| 4 | #include "ernie/device/commands.h" | ||
| 5 | |||
| 6 | #include "ernie/device/buffer.h" | ||
| 7 | |||
| 8 | #include <algorithm> | ||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | namespace ernie { | ||
| 12 | namespace { | ||
| 13 | |||
| 14 | /// The most `vkCmdUpdateBuffer` writes at once. | ||
| 15 | constexpr std::uint64_t kUpdateBytes = 65536; | ||
| 16 | |||
| 17 | } // namespace | ||
| 18 | |||
| 19 | 3 | void CommandList::Copy(std::span<const BufferRegions> copies) const { | |
| 20 | 3 | std::vector<std::vector<VkBufferCopy>> regions; | |
| 21 | 3 | std::vector<BufferCopies> vulkan; | |
| 22 | 6 | for (const BufferRegions& copy : copies) { | |
| 23 | 3 | std::vector<VkBufferCopy>& converted = regions.emplace_back(); | |
| 24 | 8 | for (const CopyRegion& region : copy.regions) { | |
| 25 | 5 | converted.push_back({region.from, region.to, region.bytes}); | |
| 26 | } | ||
| 27 | 3 | vulkan.push_back({copy.source->Handle(), copy.destination->Handle(), converted}); | |
| 28 | } | ||
| 29 | 3 | CopyBuffers(commands_, vulkan); | |
| 30 | 3 | } | |
| 31 | |||
| 32 | 26 | void CommandList::Update(const Buffer& buffer, std::uint64_t offset, | |
| 33 | std::span<const std::byte> bytes) const { | ||
| 34 | 52 | for (std::uint64_t at = 0; at < bytes.size(); at += kUpdateBytes) { | |
| 35 | 26 | const std::uint64_t size = std::min<std::uint64_t>(kUpdateBytes, bytes.size() - at); | |
| 36 | 26 | vkCmdUpdateBuffer(commands_, buffer.Handle(), offset + at, size, bytes.data() + at); | |
| 37 | } | ||
| 38 | 26 | Barrier(commands_, VK_PIPELINE_STAGE_2_COPY_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, | |
| 39 | VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, kAnyAccess); | ||
| 40 | 26 | } | |
| 41 | |||
| 42 | } // namespace ernie | ||
| 43 |