ステージングバッファー
テクニカル諏訪子 <suwako@076.moe>、2026-07-22 10:16
コミット 0ce43e85909334219f8b5d5a7c48cfa3de862e87
・親 cc5e0bd
・ファイルを見る
1個のファイル、+53 -16
| @@ -24,8 +24,10 @@ | ||
| 24 | 24 | bool framebufferResized = false; |
| 25 | 25 | |
| 26 | 26 | std::vector<vk::Image> swapChainImages; |
| 27 | +vk::CommandPool cmdPool; | |
| 27 | 28 | vk::CommandBuffer cmdBuf; |
| 28 | 29 | vk::CommandBufferBeginInfo beginInfo; |
| 30 | +vk::Queue gfxQueue; | |
| 29 | 31 | std::vector<vk::ImageView> swapChainImageViews; |
| 30 | 32 | vk::Extent2D swapChainExtent; |
| 31 | 33 | vk::Pipeline gfxPipeline; |
| @@ -272,6 +274,45 @@ | ||
| 272 | 274 | } |
| 273 | 275 | #pragma endregion |
| 274 | 276 | |
| 277 | +#pragma region createBuffer | |
| 278 | +std::pair<vk::Buffer, vk::DeviceMemory> createBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags props) { | |
| 279 | + vk::BufferCreateInfo bufInfo = {}; | |
| 280 | + bufInfo.size = size; | |
| 281 | + bufInfo.usage = usage; | |
| 282 | + bufInfo.sharingMode = vk::SharingMode::eExclusive; | |
| 283 | + vk::Buffer buf = device.createBuffer(bufInfo); | |
| 284 | + | |
| 285 | + vk::MemoryRequirements memReq = device.getBufferMemoryRequirements(buf); | |
| 286 | + vk::MemoryAllocateInfo allocInfo = {}; | |
| 287 | + allocInfo.allocationSize = memReq.size; | |
| 288 | + allocInfo.memoryTypeIndex = findMemoryType(memReq.memoryTypeBits, props); | |
| 289 | + vk::DeviceMemory alloc = device.allocateMemory(allocInfo); | |
| 290 | + device.bindBufferMemory(buf, alloc, 0); | |
| 291 | + | |
| 292 | + return { std::move(buf), std::move(alloc) }; | |
| 293 | +} | |
| 294 | + | |
| 295 | +void copyBuffer(vk::Buffer &srcBuf, vk::Buffer &dstBuf, vk::DeviceSize size) { | |
| 296 | + vk::CommandBufferAllocateInfo allocInfo = {}; | |
| 297 | + allocInfo.commandPool = cmdPool; | |
| 298 | + allocInfo.level = vk::CommandBufferLevel::ePrimary; | |
| 299 | + allocInfo.commandBufferCount = 1; | |
| 300 | + | |
| 301 | + vk::CommandBuffer cmdCopyBuf = std::move(device.allocateCommandBuffers(allocInfo).front()); | |
| 302 | + vk::CommandBufferBeginInfo beginInfo = {}; | |
| 303 | + beginInfo.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit; | |
| 304 | + cmdCopyBuf.begin(beginInfo); | |
| 305 | + cmdCopyBuf.copyBuffer(srcBuf, dstBuf, vk::BufferCopy(0, 0, size)); | |
| 306 | + cmdCopyBuf.end(); | |
| 307 | + | |
| 308 | + vk::SubmitInfo submitInfo = {}; | |
| 309 | + submitInfo.commandBufferCount = 1; | |
| 310 | + submitInfo.pCommandBuffers = &cmdCopyBuf; | |
| 311 | + gfxQueue.submit(submitInfo, nullptr); | |
| 312 | + gfxQueue.waitIdle(); | |
| 313 | +} | |
| 314 | +#pragma endregion | |
| 315 | + | |
| 275 | 316 | int main() { |
| 276 | 317 | #pragma region window |
| 277 | 318 | int winWidth = 800; |
| @@ -480,7 +521,7 @@ | ||
| 480 | 521 | |
| 481 | 522 | device = physicalDevice.createDevice(devCreateInfo); |
| 482 | 523 | VULKAN_HPP_DEFAULT_DISPATCHER.init(device); |
| 483 | - vk::Queue gfxQueue = device.getQueue(gfxIdx, 0); | |
| 524 | + gfxQueue = device.getQueue(gfxIdx, 0); | |
| 484 | 525 | #pragma endregion |
| 485 | 526 | |
| 486 | 527 | #pragma region swapchain |
| @@ -601,26 +642,20 @@ | ||
| 601 | 642 | poolInfo.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer; |
| 602 | 643 | poolInfo.queueFamilyIndex = queueIdx; |
| 603 | 644 | |
| 604 | - vk::CommandPool cmdPool = device.createCommandPool(poolInfo); | |
| 645 | + cmdPool = device.createCommandPool(poolInfo); | |
| 605 | 646 | #pragma endregion |
| 606 | 647 | |
| 607 | 648 | #pragma region vertexBuffer |
| 608 | - vk::BufferCreateInfo bufInfo = {}; | |
| 609 | - bufInfo.size = sizeof(vertices[0]) * vertices.size(); | |
| 610 | - bufInfo.usage = vk::BufferUsageFlagBits::eVertexBuffer; | |
| 611 | - bufInfo.sharingMode = vk::SharingMode::eExclusive; | |
| 612 | - vertBuf = device.createBuffer(bufInfo); | |
| 649 | + vk::DeviceSize bufSize = sizeof(vertices[0]) * vertices.size(); | |
| 650 | + vk::MemoryPropertyFlags flags = vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent; | |
| 651 | + auto [stagingBuf, stagingBufMem] = createBuffer(bufSize, vk::BufferUsageFlagBits::eTransferSrc, flags); | |
| 613 | 652 | |
| 614 | - vk::MemoryRequirements memReq = device.getBufferMemoryRequirements(vertBuf); | |
| 615 | - vk::MemoryAllocateInfo memAllocInfo = {}; | |
| 616 | - memAllocInfo.allocationSize = memReq.size; | |
| 617 | - memAllocInfo.memoryTypeIndex = findMemoryType(memReq.memoryTypeBits, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent); | |
| 618 | - vertBufMem = device.allocateMemory(memAllocInfo); | |
| 619 | - device.bindBufferMemory(vertBuf, vertBufMem, 0); | |
| 653 | + void *dataStaging = device.mapMemory(stagingBufMem, 0, bufSize); | |
| 654 | + memcpy(dataStaging, vertices.data(), bufSize); | |
| 655 | + device.unmapMemory(stagingBufMem); | |
| 620 | 656 | |
| 621 | - void *data = device.mapMemory(vertBufMem, 0, bufInfo.size); | |
| 622 | - memcpy(data, vertices.data(), bufInfo.size); | |
| 623 | - device.unmapMemory(vertBufMem); | |
| 657 | + std::tie(vertBuf, vertBufMem) = createBuffer(bufSize, vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eTransferDst, vk::MemoryPropertyFlagBits::eDeviceLocal); | |
| 658 | + copyBuffer(stagingBuf, vertBuf, bufSize); | |
| 624 | 659 | #pragma endregion |
| 625 | 660 | |
| 626 | 661 | #pragma region commandbuffers |
| @@ -726,6 +761,8 @@ | ||
| 726 | 761 | #pragma region destroy |
| 727 | 762 | if (device) device.waitIdle(); |
| 728 | 763 | if (cmdPool) device.destroyCommandPool(cmdPool); |
| 764 | + if (stagingBuf) device.destroyBuffer(stagingBuf); | |
| 765 | + if (stagingBufMem) device.freeMemory(stagingBufMem); | |
| 729 | 766 | if (vertBuf) device.destroyBuffer(vertBuf); |
| 730 | 767 | if (vertBufMem) device.freeMemory(vertBufMem); |
| 731 | 768 | if (gfxPipeline) device.destroyPipeline(gfxPipeline); |