ステージングバッファー

テクニカル諏訪子 <suwako@076.moe>、2026-07-22 10:16
コミット 0ce43e85909334219f8b5d5a7c48cfa3de862e87 ・親 cc5e0bd ・ファイルを見る

1個のファイル、+53 -16

@@ -24,8 +24,10 @@
2424 bool framebufferResized = false;
2525
2626 std::vector<vk::Image> swapChainImages;
27+vk::CommandPool cmdPool;
2728 vk::CommandBuffer cmdBuf;
2829 vk::CommandBufferBeginInfo beginInfo;
30+vk::Queue gfxQueue;
2931 std::vector<vk::ImageView> swapChainImageViews;
3032 vk::Extent2D swapChainExtent;
3133 vk::Pipeline gfxPipeline;
@@ -272,6 +274,45 @@
272274 }
273275 #pragma endregion
274276
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+
275316 int main() {
276317 #pragma region window
277318 int winWidth = 800;
@@ -480,7 +521,7 @@
480521
481522 device = physicalDevice.createDevice(devCreateInfo);
482523 VULKAN_HPP_DEFAULT_DISPATCHER.init(device);
483- vk::Queue gfxQueue = device.getQueue(gfxIdx, 0);
524+ gfxQueue = device.getQueue(gfxIdx, 0);
484525 #pragma endregion
485526
486527 #pragma region swapchain
@@ -601,26 +642,20 @@
601642 poolInfo.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer;
602643 poolInfo.queueFamilyIndex = queueIdx;
603644
604- vk::CommandPool cmdPool = device.createCommandPool(poolInfo);
645+ cmdPool = device.createCommandPool(poolInfo);
605646 #pragma endregion
606647
607648 #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);
613652
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);
620656
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);
624659 #pragma endregion
625660
626661 #pragma region commandbuffers
@@ -726,6 +761,8 @@
726761 #pragma region destroy
727762 if (device) device.waitIdle();
728763 if (cmdPool) device.destroyCommandPool(cmdPool);
764+ if (stagingBuf) device.destroyBuffer(stagingBuf);
765+ if (stagingBufMem) device.freeMemory(stagingBufMem);
729766 if (vertBuf) device.destroyBuffer(vertBuf);
730767 if (vertBufMem) device.freeMemory(vertBufMem);
731768 if (gfxPipeline) device.destroyPipeline(gfxPipeline);