{"id":597,"date":"2025-12-06T16:28:31","date_gmt":"2025-12-06T08:28:31","guid":{"rendered":"http:\/\/liyanliang.net\/?p=597"},"modified":"2025-12-06T17:44:58","modified_gmt":"2025-12-06T09:44:58","slug":"vulkan_cube_rotate","status":"publish","type":"post","link":"http:\/\/liyanliang.net\/index.php\/2025\/12\/06\/vulkan_cube_rotate\/","title":{"rendered":"Vulkan \u5165\u95e8\uff1a\u5b9e\u73b0\u4e00\u4e2a\u5e26\u7eb9\u7406\u7684\u65cb\u8f6c\u7acb\u65b9\u4f53"},"content":{"rendered":"<p><strong>\u6548\u679c\uff1a<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/202512061607330.gif\" alt=\"\" \/><\/p>\n<hr \/>\n<div id=\"toc_container\" class=\"no_bullets\"><p class=\"toc_title\">Contents<\/p><ul class=\"toc_list\"><li><a href=\"#1\"><span class=\"toc_number toc_depth_1\">1<\/span> 1. \u6982\u8ff0<\/a><\/li><li><a href=\"#2\"><span class=\"toc_number toc_depth_1\">2<\/span> 2. \u4ee3\u7801\u7ed3\u6784\u56fe<\/a><\/li><li><a href=\"#3_UML\"><span class=\"toc_number toc_depth_1\">3<\/span> 3. \u7c7bUML\u56fe<\/a><ul><li><a href=\"#31\"><span class=\"toc_number toc_depth_2\">3.1<\/span> 3.1 \u6838\u5fc3\u7c7b\u5173\u7cfb<\/a><\/li><li><a href=\"#32\"><span class=\"toc_number toc_depth_2\">3.2<\/span> 3.2 \u547d\u4ee4\u7cfb\u7edf\u7c7b\u56fe<\/a><\/li><\/ul><\/li><li><a href=\"#4\"><span class=\"toc_number toc_depth_1\">4<\/span> 4. \u6e32\u67d3\u6d41\u7a0b\u56fe<\/a><\/li><li><a href=\"#5\"><span class=\"toc_number toc_depth_1\">5<\/span> 5. \u547d\u4ee4\u7cfb\u7edf<\/a><ul><li><a href=\"#51\"><span class=\"toc_number toc_depth_2\">5.1<\/span> 5.1 \u547d\u4ee4\u961f\u5217\/\u7f13\u51b2\/\u5217\u8868\u5173\u7cfb<\/a><\/li><li><a href=\"#52_Ring_Buffer\"><span class=\"toc_number toc_depth_2\">5.2<\/span> 5.2 Ring Buffer\u7ba1\u7406<\/a><\/li><\/ul><\/li><li><a href=\"#6\"><span class=\"toc_number toc_depth_1\">6<\/span> 6. \u540c\u6b65\u673a\u5236<\/a><ul><li><a href=\"#61\"><span class=\"toc_number toc_depth_2\">6.1<\/span> 6.1 \u540c\u6b65\u539f\u8bed<\/a><\/li><li><a href=\"#62\"><span class=\"toc_number toc_depth_2\">6.2<\/span> 6.2 \u540c\u6b65\u6d41\u7a0b<\/a><\/li><li><a href=\"#63_Image_Memory_Barrier\"><span class=\"toc_number toc_depth_2\">6.3<\/span> 6.3 Image Memory Barrier\u793a\u4f8b<\/a><\/li><\/ul><\/li><li><a href=\"#7\"><span class=\"toc_number toc_depth_1\">7<\/span> 7. \u63cf\u8ff0\u7b26\u7cfb\u7edf<\/a><ul><li><a href=\"#71\"><span class=\"toc_number toc_depth_2\">7.1<\/span> 7.1 \u63cf\u8ff0\u7b26\u67b6\u6784<\/a><\/li><li><a href=\"#72\"><span class=\"toc_number toc_depth_2\">7.2<\/span> 7.2 \u63cf\u8ff0\u7b26\u66f4\u65b0\u6d41\u7a0b<\/a><\/li><\/ul><\/li><li><a href=\"#8\"><span class=\"toc_number toc_depth_1\">8<\/span> 8. \u7ba1\u7ebf\u7ba1\u7406<\/a><ul><li><a href=\"#81\"><span class=\"toc_number toc_depth_2\">8.1<\/span> 8.1 \u7ba1\u7ebf\u72b6\u6001\u521b\u5efa<\/a><\/li><li><a href=\"#82\"><span class=\"toc_number toc_depth_2\">8.2<\/span> 8.2 \u7ba1\u7ebf\u7f13\u5b58\u4f18\u5316<\/a><\/li><\/ul><\/li><li><a href=\"#9\"><span class=\"toc_number toc_depth_1\">9<\/span> 9. \u6e32\u67d3\u9644\u4ef6<\/a><ul><li><a href=\"#91\"><span class=\"toc_number toc_depth_2\">9.1<\/span> 9.1 \u989c\u8272\u9644\u4ef6<\/a><\/li><li><a href=\"#92\"><span class=\"toc_number toc_depth_2\">9.2<\/span> 9.2 \u6df1\u5ea6\u6a21\u677f\u9644\u4ef6<\/a><\/li><\/ul><\/li><li><a href=\"#10\"><span class=\"toc_number toc_depth_1\">10<\/span> 10. \u6027\u80fd\u4f18\u5316\u7b56\u7565<\/a><\/li><li><a href=\"#11\"><span class=\"toc_number toc_depth_1\">11<\/span> 11. \u603b\u7ed3<\/a><\/li><li><a href=\"#i\"><span class=\"toc_number toc_depth_1\">12<\/span> \u53c2\u8003\u8d44\u6599<\/a><\/li><\/ul><\/div>\n<h2><span id=\"1\">1. \u6982\u8ff0<\/span><\/h2>\n<p>\u672c\u6587\u4ecb\u7ecd\u5982\u4f55\u4f7f\u7528 <strong>Vulkan API<\/strong> \u5b9e\u73b0\u4e00\u4e2a\u5e26\u7eb9\u7406\u7684\u65cb\u8f6c\u7acb\u65b9\u4f53\u6e32\u67d3\uff0c\u4ece\u96f6\u5f00\u59cb\u6784\u5efa\u4e00\u4e2a\u5b8c\u6574\u7684 3D \u6e32\u67d3\u6d41\u7a0b\u3002<\/p>\n<hr \/>\n<h2><span id=\"2\">2. \u4ee3\u7801\u7ed3\u6784\u56fe<\/span><\/h2>\n<p>\u9879\u76ee\u91c7\u7528\u5206\u5c42\u67b6\u6784\uff0c\u5c06\u5e94\u7528\u903b\u8f91\u3001RHI \u62bd\u8c61\u5c42\u548c Vulkan \u5b9e\u73b0\u5206\u79bb\uff0c\u4fbf\u4e8e\u7ef4\u62a4\u548c\u6269\u5c55\u3002<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/202512061608835.png\" alt=\"deepseek_mermaid_20251206_d33b62\" \/><\/p>\n<hr \/>\n<h2><span id=\"3_UML\">3. \u7c7bUML\u56fe<\/span><\/h2>\n<h3><span id=\"31\">3.1 \u6838\u5fc3\u7c7b\u5173\u7cfb<\/span><\/h3>\n<p><code>CubeApplication<\/code> \u7ba1\u7406\u5e94\u7528\u751f\u547d\u5468\u671f\uff0c<code>CubeRenderer<\/code> \u8d1f\u8d23\u8d44\u6e90\u521b\u5efa\u548c\u6e32\u67d3\u903b\u8f91\u3002\u4e24\u8005\u901a\u8fc7 RHI \u63a5\u53e3\u4e0e\u5e95\u5c42 Vulkan \u5b9e\u73b0\u89e3\u8026\u3002<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/202512061605114.png\" alt=\"deepseek_mermaid_20251206_bd716f\" \/><\/p>\n<pre><code class=\"language-cpp\">\/\/ CubeRenderer \u521d\u59cb\u5316\u6d41\u7a0b\nbool CubeRenderer::initialize(RHI::IRHIDevice* device) {\n    createVertexBuffer();    \/\/ 36 \u9876\u70b9\u6570\u636e\n    createUniformBuffer();   \/\/ MVP \u77e9\u9635\n    loadTextures();          \/\/ 2 \u5f20\u7eb9\u7406\n    createShaders();         \/\/ \u9876\u70b9\/\u7247\u6bb5\u7740\u8272\u5668\n    createPipelineState();   \/\/ \u6e32\u67d3\u7ba1\u7ebf\n}<\/code><\/pre>\n<h3><span id=\"32\">3.2 \u547d\u4ee4\u7cfb\u7edf\u7c7b\u56fe<\/span><\/h3>\n<p>\u547d\u4ee4\u7cfb\u7edf\u91c7\u7528\u4e09\u5c42\u5c01\u88c5\uff1a<code>IRHICommandList<\/code>\uff08RHI \u63a5\u53e3\uff09\u2192 <code>FVulkanRHICommandListImmediate<\/code>\uff08Vulkan \u5b9e\u73b0\uff09\u2192 <code>FVulkanCmdBuffer<\/code>\uff08\u539f\u751f\u5c01\u88c5\uff09\u3002<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/202512061611213.png\" alt=\"deepseek_mermaid_20251206_07a4ca\" \/><\/p>\n<h2><span id=\"4\">4. \u6e32\u67d3\u6d41\u7a0b\u56fe<\/span><\/h2>\n<p>\u6bcf\u5e27\u6e32\u67d3\u9075\u5faa\u56fa\u5b9a\u6d41\u7a0b\uff1a\u51c6\u5907\u5e27 \u2192 \u5f55\u5236\u547d\u4ee4 \u2192 \u63d0\u4ea4\u6267\u884c \u2192 \u5448\u73b0\u3002<code>CubeRenderer::render()<\/code> \u5728\u547d\u4ee4\u5f55\u5236\u9636\u6bb5\u88ab\u8c03\u7528\u3002<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/202512061613467.png\" alt=\"deepseek_mermaid_20251206_d03f4f\" \/><\/p>\n<pre><code class=\"language-cpp\">\/\/ \u6bcf\u5e27\u6e32\u67d3\u6d41\u7a0b (CubeApplication::onRender)\nvoid onRender() {\n    context-&gt;prepareForNewFrame();  \/\/ \u5207\u6362\u547d\u4ee4\u7f13\u51b2\u533a\uff0c\u83b7\u53d6\u4ea4\u6362\u94fe\u56fe\u50cf\n    cmdList-&gt;begin();               \/\/ \u5f00\u59cb\u5f55\u5236\u547d\u4ee4\n    cmdList-&gt;setRenderTargets(...); \/\/ \u8bbe\u7f6e\u6e32\u67d3\u76ee\u6807\uff08\u89e6\u53d1 BeginRenderPass\uff09\n    m_cubeRenderer-&gt;render(cmdList, deltaTime);  \/\/ \u7ed1\u5b9a\u8d44\u6e90\u5e76\u7ed8\u5236\n    cmdList-&gt;endRenderPass();       \/\/ \u7ed3\u675f\u6e32\u67d3\u901a\u9053\n    cmdList-&gt;end();                 \/\/ \u7ed3\u675f\u5f55\u5236\n    device-&gt;present();              \/\/ \u63d0\u4ea4\u5e76\u5448\u73b0\n}<\/code><\/pre>\n<hr \/>\n<h2><span id=\"5\">5. \u547d\u4ee4\u7cfb\u7edf<\/span><\/h2>\n<h3><span id=\"51\">5.1 \u547d\u4ee4\u961f\u5217\/\u7f13\u51b2\/\u5217\u8868\u5173\u7cfb<\/span><\/h3>\n<p>Vulkan \u547d\u4ee4\u7cfb\u7edf\u5206\u4e3a\u4e09\u5c42\uff1a<strong>Queue<\/strong>\uff08\u6267\u884c\u5165\u53e3\uff09\u2192 <strong>CommandBuffer<\/strong>\uff08\u547d\u4ee4\u5bb9\u5668\uff09\u2192 <strong>CommandPool<\/strong>\uff08\u5185\u5b58\u5206\u914d\uff09\u3002MonsterEngine \u901a\u8fc7 <code>FVulkanCmdBuffer<\/code> \u5c01\u88c5\u539f\u751f\u547d\u4ee4\u7f13\u51b2\u533a\u3002<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/202512061616542.png\" alt=\"deepseek_mermaid_20251206_c85718\" \/><\/p>\n<pre><code class=\"language-cpp\">\/\/ \u547d\u4ee4\u5f55\u5236\u4e0e\u63d0\u4ea4\nvkBeginCommandBuffer(cmdBuffer, &amp;beginInfo);\n    vkCmdBeginRenderPass(...);\n    vkCmdBindPipeline(...);\n    vkCmdBindDescriptorSets(...);\n    vkCmdDraw(36, 1, 0, 0);  \/\/ \u7ed8\u5236\u7acb\u65b9\u4f53\n    vkCmdEndRenderPass(...);\nvkEndCommandBuffer(cmdBuffer);\nvkQueueSubmit(queue, 1, &amp;submitInfo, fence);<\/code><\/pre>\n<h3><span id=\"52_Ring_Buffer\">5.2 Ring Buffer\u7ba1\u7406<\/span><\/h3>\n<p>\u4f7f\u7528 <strong>3 \u4e2a\u547d\u4ee4\u7f13\u51b2\u533a\u8f6e\u6362<\/strong>\uff08Triple Buffering\uff09\uff0c\u5b9e\u73b0 CPU \u5f55\u5236\u4e0e GPU \u6267\u884c\u5e76\u884c\uff0c\u907f\u514d\u5e27\u95f4\u7b49\u5f85\u3002<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/202512061619258.png\" alt=\"deepseek_mermaid_20251206_e06afd\" \/><\/p>\n<p>\u547d\u4ee4\u7f13\u51b2\u533a\u72b6\u6001\u673a\uff1a<code>ReadyForBegin<\/code> \u2192 <code>Recording<\/code> \u2192 <code>Ended<\/code> \u2192 <code>Submitted<\/code> \u2192 \u7b49\u5f85 Fence \u2192 \u91cd\u7f6e \u2192 <code>ReadyForBegin<\/code><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/202512061619055.png\" alt=\"deepseek_mermaid_20251206_7c7345\" \/><\/p>\n<h2><span id=\"6\">6. \u540c\u6b65\u673a\u5236<\/span><\/h2>\n<p>Vulkan \u662f\u663e\u5f0f\u540c\u6b65 API\uff0c\u9700\u8981\u5f00\u53d1\u8005\u624b\u52a8\u7ba1\u7406 CPU-GPU \u548c GPU-GPU \u4e4b\u95f4\u7684\u540c\u6b65\u3002<\/p>\n<h3><span id=\"61\">6.1 \u540c\u6b65\u539f\u8bed<\/span><\/h3>\n<table>\n<thead>\n<tr>\n<th>\u539f\u8bed<\/th>\n<th>\u7528\u9014<\/th>\n<th>\u573a\u666f<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Semaphore<\/strong><\/td>\n<td>GPU-GPU\u540c\u6b65<\/td>\n<td>\u4ea4\u6362\u94fe\u56fe\u50cf\u83b7\u53d6\u2192\u6e32\u67d3\u2192\u5448\u73b0<\/td>\n<\/tr>\n<tr>\n<td><strong>Fence<\/strong><\/td>\n<td>GPU-CPU\u540c\u6b65<\/td>\n<td>CPU\u7b49\u5f85GPU\u5b8c\u6210\u547d\u4ee4\u6267\u884c<\/td>\n<\/tr>\n<tr>\n<td><strong>Pipeline Barrier<\/strong><\/td>\n<td>\u547d\u4ee4\u7f13\u51b2\u5185\u540c\u6b65<\/td>\n<td>\u8d44\u6e90\u72b6\u6001\/\u5e03\u5c40\u8f6c\u6362<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<pre><code class=\"language-cpp\">\/\/ Fence \u4f7f\u7528\u793a\u4f8b\uff1a\u7b49\u5f85\u547d\u4ee4\u6267\u884c\u5b8c\u6210\u540e\u91cd\u7528\u547d\u4ee4\u7f13\u51b2\u533a\nvkWaitForFences(device, 1, &amp;fence, VK_TRUE, UINT64_MAX);\nvkResetFences(device, 1, &amp;fence);\nvkResetCommandBuffer(cmdBuffer, 0);\n\n\/\/ Semaphore \u4f7f\u7528\u793a\u4f8b\uff1a\u5e27\u540c\u6b65\nvkAcquireNextImageKHR(..., imageAvailableSemaphore, ...);  \/\/ \u83b7\u53d6\u56fe\u50cf\nvkQueueSubmit(..., waitSemaphore=imageAvailable, signalSemaphore=renderFinished, ...);\nvkQueuePresentKHR(..., waitSemaphore=renderFinished, ...);  \/\/ \u5448\u73b0<\/code><\/pre>\n<h3><span id=\"62\">6.2 \u540c\u6b65\u6d41\u7a0b<\/span><\/h3>\n<p>\u5e27\u6e32\u67d3\u7684\u540c\u6b65\u65f6\u5e8f\uff1a<code>AcquireImage<\/code>\uff08\u4fe1\u53f7 imageAvailable\uff09\u2192 <code>QueueSubmit<\/code>\uff08\u7b49\u5f85 imageAvailable\uff0c\u4fe1\u53f7 renderFinished\uff09\u2192 <code>Present<\/code>\uff08\u7b49\u5f85 renderFinished\uff09<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/202512061636386.png\" alt=\"deepseek_mermaid_20251206_0fd82e\" \/><\/p>\n<h3><span id=\"63_Image_Memory_Barrier\">6.3 Image Memory Barrier\u793a\u4f8b<\/span><\/h3>\n<p><strong>Pipeline Barrier<\/strong> \u7528\u4e8e\u5728\u547d\u4ee4\u7f13\u51b2\u533a\u5185\u540c\u6b65\u8d44\u6e90\u72b6\u6001\u3002\u7eb9\u7406\u4e0a\u4f20\u9700\u8981\u4e24\u6b21\u5e03\u5c40\u8f6c\u6362\uff1a<code>UNDEFINED<\/code> \u2192 <code>TRANSFER_DST<\/code>\uff08\u51c6\u5907\u63a5\u6536\u6570\u636e\uff09\u2192 <code>SHADER_READ_ONLY<\/code>\uff08\u51c6\u5907\u88ab\u7740\u8272\u5668\u91c7\u6837\uff09\u3002<\/p>\n<pre><code class=\"language-cpp\">\/\/ \u7eb9\u7406\u4e0a\u4f20\u524d: UNDEFINED \u2192 TRANSFER_DST_OPTIMAL\nVkImageMemoryBarrier barrier{};\nbarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;\nbarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;\nbarrier.srcAccessMask = 0;\nbarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;\n\nvkCmdPipelineBarrier(cmdBuffer,\n    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,\n    VK_PIPELINE_STAGE_TRANSFER_BIT,\n    0, 0, nullptr, 0, nullptr, 1, &amp;barrier);\n\n\/\/ \u4e0a\u4f20\u540e: TRANSFER_DST \u2192 SHADER_READ_ONLY\nbarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;\nbarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;\nbarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;\nbarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;\n\nvkCmdPipelineBarrier(cmdBuffer,\n    VK_PIPELINE_STAGE_TRANSFER_BIT,\n    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,\n    0, 0, nullptr, 0, nullptr, 1, &amp;barrier);<\/code><\/pre>\n<hr \/>\n<h2><span id=\"7\">7. \u63cf\u8ff0\u7b26\u7cfb\u7edf<\/span><\/h2>\n<p>\u63cf\u8ff0\u7b26\uff08Descriptor\uff09\u662f Vulkan \u4e2d\u5c06\u8d44\u6e90\uff08Buffer\u3001Texture\uff09\u7ed1\u5b9a\u5230\u7740\u8272\u5668\u7684\u673a\u5236\u3002\u7acb\u65b9\u4f53\u6e32\u67d3\u4f7f\u7528 3 \u4e2a\u7ed1\u5b9a\u70b9\uff1a1 \u4e2a Uniform Buffer + 2 \u4e2a\u7eb9\u7406\u91c7\u6837\u5668\u3002<\/p>\n<h3><span id=\"71\">7.1 \u63cf\u8ff0\u7b26\u67b6\u6784<\/span><\/h3>\n<p>\u63cf\u8ff0\u7b26\u7cfb\u7edf\u5206\u4e3a\u56db\u5c42\uff1a<code>DescriptorSetLayout<\/code>\uff08\u6a21\u677f\uff09\u2192 <code>PipelineLayout<\/code>\uff08\u7ba1\u7ebf\u5e03\u5c40\uff09\u2192 <code>DescriptorPool<\/code>\uff08\u5185\u5b58\u6c60\uff09\u2192 <code>DescriptorSet<\/code>\uff08\u5b9e\u4f8b\uff09\u3002<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/202512061639601.png\" alt=\"deepseek_mermaid_20251206_4dd7fc\" \/><\/p>\n<pre><code class=\"language-glsl\">\/\/ Cube.vert - \u9876\u70b9\u7740\u8272\u5668\nlayout(set = 0, binding = 0) uniform UBO {\n    mat4 model;       \/\/ \u6a21\u578b\u77e9\u9635\uff08\u65cb\u8f6c\uff09\n    mat4 view;        \/\/ \u89c6\u56fe\u77e9\u9635\uff08\u76f8\u673a\uff09\n    mat4 projection;  \/\/ \u6295\u5f71\u77e9\u9635\uff08\u900f\u89c6\uff09\n} ubo;\n\n\/\/ Cube.frag - \u7247\u6bb5\u7740\u8272\u5668\nlayout(set = 0, binding = 1) uniform sampler2D texture1;  \/\/ container.jpg\nlayout(set = 0, binding = 2) uniform sampler2D texture2;  \/\/ awesomeface.png<\/code><\/pre>\n<h3><span id=\"72\">7.2 \u63cf\u8ff0\u7b26\u66f4\u65b0\u6d41\u7a0b<\/span><\/h3>\n<p><code>FVulkanPendingState<\/code> \u6536\u96c6\u8d44\u6e90\u7ed1\u5b9a\uff0c\u5728 <code>draw()<\/code> \u65f6\u901a\u8fc7 <code>updateAndBindDescriptorSets()<\/code> \u7edf\u4e00\u66f4\u65b0\u548c\u7ed1\u5b9a\u63cf\u8ff0\u7b26\u96c6\u3002<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/202512061647249.png\" alt=\"deepseek_mermaid_20251206_b6926f\" \/><\/p>\n<pre><code class=\"language-cpp\">\/\/ CubeRenderer::render() \u4e2d\u7684\u8d44\u6e90\u7ed1\u5b9a\ncmdList-&gt;setConstantBuffer(0, m_uniformBuffer);  \/\/ binding 0: MVP \u77e9\u9635\ncmdList-&gt;setShaderResource(1, m_texture1);       \/\/ binding 1: container.jpg\ncmdList-&gt;setShaderResource(2, m_texture2);       \/\/ binding 2: awesomeface.png\n\/\/ draw() \u65f6\u81ea\u52a8\u89e6\u53d1 vkUpdateDescriptorSets + vkCmdBindDescriptorSets<\/code><\/pre>\n<h2><span id=\"8\">8. \u7ba1\u7ebf\u7ba1\u7406<\/span><\/h2>\n<p>\u56fe\u5f62\u7ba1\u7ebf\uff08Graphics Pipeline\uff09\u5b9a\u4e49\u4e86\u4ece\u9876\u70b9\u6570\u636e\u5230\u6700\u7ec8\u50cf\u7d20\u7684\u5b8c\u6574\u5904\u7406\u6d41\u7a0b\u3002Vulkan \u7ba1\u7ebf\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u9700\u8981\u9884\u5148\u521b\u5efa\u3002<\/p>\n<h3><span id=\"81\">8.1 \u7ba1\u7ebf\u72b6\u6001\u521b\u5efa<\/span><\/h3>\n<p>\u7ba1\u7ebf\u521b\u5efa\u5206\u4e3a\u56db\u6b65\uff1a\u7740\u8272\u5668\u6a21\u5757 \u2192 \u7740\u8272\u5668\u53cd\u5c04 \u2192 \u7ba1\u7ebf\u5e03\u5c40 \u2192 \u56fe\u5f62\u7ba1\u7ebf\u3002<\/p>\n<pre><code class=\"language-cpp\">\/\/ VulkanPipelineState::initialize() \u6d41\u7a0b\n1. createShaderModules()     - \u4eceSPV\u521b\u5efaVkShaderModule\n2. reflectShaders()          - \u53cd\u5c04\u83b7\u53d6\u8d44\u6e90\u7ed1\u5b9a\u4fe1\u606f\n3. createPipelineLayout()    - \u521b\u5efaVkDescriptorSetLayout\u548cVkPipelineLayout\n4. createGraphicsPipeline()  - \u521b\u5efaVkPipeline\n\n\/\/ Cube\u7ba1\u7ebf\u914d\u7f6e:\nPipelineStateDesc desc;\ndesc.vertexShader = vertexShader;\ndesc.pixelShader = pixelShader;\ndesc.primitiveTopology = TriangleList;\ndesc.rasterizerState.cullMode = Back;\ndesc.depthStencilState.depthEnable = true;\ndesc.depthStencilState.depthCompareOp = Less;\ndesc.blendState.blendEnable = false;\ndesc.renderTargetFormats = {B8G8R8A8_SRGB};\ndesc.depthStencilFormat = D32_FLOAT;<\/code><\/pre>\n<h3><span id=\"82\">8.2 \u7ba1\u7ebf\u7f13\u5b58\u4f18\u5316<\/span><\/h3>\n<p>\u4f7f\u7528 <code>VkPipelineCache<\/code> \u7f13\u5b58\u7ba1\u7ebf\u7f16\u8bd1\u7ed3\u679c\uff0c\u907f\u514d\u91cd\u590d\u7f16\u8bd1\u3002MonsterEngine \u901a\u8fc7\u54c8\u5e0c\u67e5\u627e\u5b9e\u73b0\u7ba1\u7ebf\u590d\u7528\u3002<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/202512061650661.png\" alt=\"deepseek_mermaid_20251206_8eb342\" \/><\/p>\n<hr \/>\n<h2><span id=\"9\">9. \u6e32\u67d3\u9644\u4ef6<\/span><\/h2>\n<p>\u6e32\u67d3\u901a\u9053\uff08RenderPass\uff09\u5b9a\u4e49\u4e86\u6e32\u67d3\u76ee\u6807\u7684\u683c\u5f0f\u548c\u64cd\u4f5c\u3002\u7acb\u65b9\u4f53\u6e32\u67d3\u4f7f\u7528 1 \u4e2a\u989c\u8272\u9644\u4ef6 + 1 \u4e2a\u6df1\u5ea6\u9644\u4ef6\u3002<\/p>\n<h3><span id=\"91\">9.1 \u989c\u8272\u9644\u4ef6<\/span><\/h3>\n<p>\u4ea4\u6362\u94fe\u56fe\u50cf\u4f5c\u4e3a\u989c\u8272\u9644\u4ef6\uff0c\u6bcf\u5e27\u6e05\u9664\u4e3a\u6df1\u84dd\u8272\u80cc\u666f\u3002<\/p>\n<pre><code class=\"language-cpp\">\/\/ \u989c\u8272\u9644\u4ef6\u914d\u7f6e\nVkAttachmentDescription colorAttachment{};\ncolorAttachment.format = VK_FORMAT_B8G8R8A8_SRGB;\ncolorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;    \/\/ \u6e05\u9664\ncolorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;  \/\/ \u4fdd\u5b58\ncolorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;\ncolorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;\n\n\/\/ \u6e05\u9664\u989c\u8272\nVkClearValue clearColor = {{{0.2f, 0.3f, 0.3f, 1.0f}}};  \/\/ \u6df1\u84dd\u8272<\/code><\/pre>\n<h3><span id=\"92\">9.2 \u6df1\u5ea6\u6a21\u677f\u9644\u4ef6<\/span><\/h3>\n<p>\u6df1\u5ea6\u7f13\u51b2\u7528\u4e8e Z-Buffer \u6df1\u5ea6\u6d4b\u8bd5\uff0c\u786e\u4fdd\u8fd1\u5904\u7269\u4f53\u906e\u6321\u8fdc\u5904\u7269\u4f53\u3002<\/p>\n<pre><code class=\"language-cpp\">\/\/ \u6df1\u5ea6\u9644\u4ef6\u914d\u7f6e\nVkAttachmentDescription depthAttachment{};\ndepthAttachment.format = VK_FORMAT_D32_SFLOAT;\ndepthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;      \/\/ \u6e05\u9664\u4e3a 1.0\ndepthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; \/\/ \u4e0d\u9700\u8981\u4fdd\u5b58\ndepthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;\ndepthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;\n\n\/\/ \u6e05\u9664\u6df1\u5ea6\nVkClearValue clearDepth = {.depthStencil = {1.0f, 0}};<\/code><\/pre>\n<hr \/>\n<h2><span id=\"10\">10. \u6027\u80fd\u4f18\u5316\u7b56\u7565<\/span><\/h2>\n<p>MonsterEngine \u91c7\u7528\u591a\u79cd\u4f18\u5316\u7b56\u7565\uff0c\u51cf\u5c11 CPU \u5f00\u9500\u548c GPU \u7b49\u5f85\u65f6\u95f4\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u4f18\u5316\u70b9<\/th>\n<th>\u5b9e\u73b0\u65b9\u5f0f<\/th>\n<th>\u6548\u679c<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Triple Buffering<\/strong><\/td>\n<td>Ring Buffer (3\u4e2a\u547d\u4ee4\u7f13\u51b2)<\/td>\n<td>GPU-CPU \u5e76\u884c\uff0c\u51cf\u5c11\u5e27\u7b49\u5f85<\/td>\n<\/tr>\n<tr>\n<td><strong>\u63cf\u8ff0\u7b26\u96c6\u7f13\u5b58<\/strong><\/td>\n<td><code>FVulkanDescriptorSetCache<\/code><\/td>\n<td>\u5e27\u5185\u590d\u7528\u76f8\u540c\u7ed1\u5b9a\u7684\u63cf\u8ff0\u7b26\u96c6<\/td>\n<\/tr>\n<tr>\n<td><strong>\u7ba1\u7ebf\u7f13\u5b58<\/strong><\/td>\n<td><code>VulkanPipelineCache<\/code><\/td>\n<td>\u54c8\u5e0c\u67e5\u627e\uff0c\u907f\u514d\u91cd\u590d\u7f16\u8bd1<\/td>\n<\/tr>\n<tr>\n<td><strong>\u5e03\u5c40\u7f13\u5b58<\/strong><\/td>\n<td><code>FVulkanDescriptorSetLayoutCache<\/code><\/td>\n<td>\u907f\u514d\u91cd\u590d\u521b\u5efa\u76f8\u540c\u5e03\u5c40<\/td>\n<\/tr>\n<tr>\n<td><strong>RenderPass\u7f13\u5b58<\/strong><\/td>\n<td><code>FVulkanRenderPassCache<\/code><\/td>\n<td>\u6309\u914d\u7f6e\u7f13\u5b58\u6e32\u67d3\u901a\u9053<\/td>\n<\/tr>\n<tr>\n<td><strong>\u5ef6\u8fdf\u72b6\u6001\u7ed1\u5b9a<\/strong><\/td>\n<td><code>FVulkanPendingState<\/code><\/td>\n<td>draw \u524d\u6279\u91cf\u5e94\u7528\u72b6\u6001<\/td>\n<\/tr>\n<tr>\n<td><strong>\u5185\u5b58\u6c60<\/strong><\/td>\n<td>\u63cf\u8ff0\u7b26\u6c60\u6bcf\u5e27\u91cd\u7f6e<\/td>\n<td>\u907f\u514d\u5355\u72ec\u5206\u914d\/\u91ca\u653e\u5f00\u9500<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<pre><code class=\"language-cpp\">\/\/ \u5ef6\u8fdf\u72b6\u6001\u7ed1\u5b9a\u793a\u4f8b (FVulkanPendingState)\nvoid prepareForDraw(VkCommandBuffer cmdBuffer) {\n    if (m_pipelineDirty) {\n        vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline);\n    }\n    if (m_descriptorsDirty) {\n        updateAndBindDescriptorSets(cmdBuffer);  \/\/ \u6279\u91cf\u66f4\u65b0\n    }\n    if (m_vertexBuffersDirty) {\n        vkCmdBindVertexBuffers(cmdBuffer, 0, 1, &amp;m_vertexBuffer, &amp;offset);\n    }\n}<\/code><\/pre>\n<hr \/>\n<h2><span id=\"11\">11. \u603b\u7ed3<\/span><\/h2>\n<p>\u672c\u6587\u901a\u8fc7\u5b9e\u73b0\u4e00\u4e2a\u5e26\u7eb9\u7406\u7684\u65cb\u8f6c\u7acb\u65b9\u4f53\uff0c\u4ecb\u7ecd\u4e86 Vulkan \u6e32\u67d3\u7684\u6838\u5fc3\u6982\u5ff5\uff1a<\/p>\n<ol>\n<li><strong>\u547d\u4ee4\u7cfb\u7edf<\/strong>\uff1aQueue \u2192 CommandBuffer \u2192 CommandPool \u7684\u5c42\u6b21\u5173\u7cfb<\/li>\n<li><strong>\u540c\u6b65\u673a\u5236<\/strong>\uff1aFence\uff08CPU-GPU\uff09\u3001Semaphore\uff08GPU-GPU\uff09\u3001Pipeline Barrier\uff08\u547d\u4ee4\u5185\uff09<\/li>\n<li><strong>\u63cf\u8ff0\u7b26\u7cfb\u7edf<\/strong>\uff1aLayout \u2192 Pool \u2192 Set \u7684\u8d44\u6e90\u7ed1\u5b9a\u6d41\u7a0b<\/li>\n<li><strong>\u7ba1\u7ebf\u7ba1\u7406<\/strong>\uff1a\u4e0d\u53ef\u53d8\u7ba1\u7ebf\u7684\u521b\u5efa\u4e0e\u7f13\u5b58<\/li>\n<li><strong>\u6e32\u67d3\u9644\u4ef6<\/strong>\uff1a\u989c\u8272\u9644\u4ef6 + \u6df1\u5ea6\u9644\u4ef6\u7684\u914d\u7f6e<\/li>\n<\/ol>\n<hr \/>\n<p><strong>\u5b8c\u6574\u4ee3\u7801\u89c1 GitHub \u4ed3\u5e93:<\/strong><\/p>\n<p><a href=\"https:\/\/github.com\/liyanliang-auto\/MonsterEngine\">https:\/\/github.com\/liyanliang-auto\/MonsterEngine<\/a><\/p>\n<hr \/>\n<h2><span id=\"i\">\u53c2\u8003\u8d44\u6599<\/span><\/h2>\n<ul>\n<li>UE5 VulkanRHI\u6e90\u7801: <code>Engine\/Source\/Runtime\/VulkanRHI\/<\/code><\/li>\n<li>LearnOpenGL\u5750\u6807\u7cfb\u7edf: <a href=\"https:\/\/learnopengl-cn.github.io\/01%20Getting%20started\/08%20Coordinate%20Systems\/\">https:\/\/learnopengl-cn.github.io\/01%20Getting%20started\/08%20Coordinate%20Systems\/<\/a><\/li>\n<li>Vulkan\u89c4\u8303: <a href=\"https:\/\/www.khronos.org\/registry\/vulkan\/specs\/\">https:\/\/www.khronos.org\/registry\/vulkan\/specs\/<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>\u6548\u679c\uff1a Contents1 1. \u6982\u8ff02 2. \u4ee3\u7801\u7ed3\u6784\u56fe3 3. \u7c7bUML\u56fe3.1 3.1 \u6838\u5fc3\u7c7b\u5173\u7cfb3.2 3.2 \u547d\u4ee4\u7cfb\u7edf\u7c7b\u56fe4 4. \u6e32\u67d3\u6d41\u7a0b\u56fe5 5. \u547d\u4ee4\u7cfb\u7edf5.1 5.1 \u547d\u4ee4\u961f\u5217\/\u7f13\u51b2\/\u5217\u8868\u5173\u7cfb5.2 5.2 Ring Buffer\u7ba1\u74066 6. \u540c\u6b65\u673a\u52366.1 6.1 \u540c\u6b65\u539f\u8bed6.2 6.2 \u540c\u6b65\u6d41\u7a0b6.3 6.3 Image Memory Barrier\u793a\u4f8b7 7. \u63cf\u8ff0\u7b26\u7cfb\u7edf7.1 7.1 \u63cf\u8ff0\u7b26\u67b6\u67847.2 7.2 \u63cf\u8ff0\u7b26\u66f4\u65b0\u6d41\u7a0b8 8. \u7ba1\u7ebf\u7ba1\u74068.1 8.1 \u7ba1\u7ebf\u72b6\u6001\u521b\u5efa8.2 8.2 \u7ba1\u7ebf\u7f13\u5b58\u4f18\u53169 9. \u6e32\u67d3\u9644\u4ef69.1 9.1 \u989c\u8272\u9644\u4ef69.2 9.2 \u6df1\u5ea6\u6a21\u677f\u9644\u4ef610 10. \u6027\u80fd\u4f18\u5316\u7b56\u756511 11. \u603b\u7ed312 \u53c2\u8003\u8d44\u6599 1. \u6982\u8ff0 \u672c\u6587\u4ecb\u7ecd\u5982\u4f55\u4f7f\u7528 Vulkan API \u5b9e\u73b0\u4e00\u4e2a\u5e26\u7eb9\u7406\u7684\u65cb\u8f6c\u7acb\u65b9\u4f53\u6e32\u67d3\uff0c\u4ece\u96f6\u5f00\u59cb\u6784\u5efa\u4e00\u4e2a\u5b8c\u6574\u7684 3D \u6e32\u67d3\u6d41\u7a0b\u3002 2. \u4ee3\u7801\u7ed3\u6784\u56fe \u9879\u76ee\u91c7\u7528\u5206\u5c42\u67b6\u6784\uff0c\u5c06\u5e94\u7528\u903b\u8f91\u3001RHI \u62bd\u8c61\u5c42\u548c Vulkan \u5b9e\u73b0\u5206\u79bb\uff0c\u4fbf\u4e8e\u7ef4\u62a4\u548c\u6269\u5c55\u3002 3. \u7c7bUML\u56fe 3.1 \u6838\u5fc3\u7c7b\u5173\u7cfb CubeApplication \u7ba1\u7406\u5e94\u7528\u751f\u547d\u5468\u671f\uff0cCubeRender&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"http:\/\/liyanliang.net\/index.php\/2025\/12\/06\/vulkan_cube_rotate\/\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":602,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[65],"tags":[],"class_list":["post-597","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-vulkan"],"_links":{"self":[{"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/posts\/597","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/comments?post=597"}],"version-history":[{"count":5,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/posts\/597\/revisions"}],"predecessor-version":[{"id":604,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/posts\/597\/revisions\/604"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/media\/602"}],"wp:attachment":[{"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/media?parent=597"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/categories?post=597"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/tags?post=597"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}