From d71eca3c321d3b1e6fbe3af2fee5436bf8fe84d1 Mon Sep 17 00:00:00 2001 From: InkSoul Date: Mon, 18 Mar 2024 23:56:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9B=E5=BB=BAdescriptor=20sets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VulkanTutorial.cpp | 139 +++++++++++++++++++++++++++++++++++++-- VulkanTutorial.h | 31 ++++++++- shaders/triangle.vert | 9 ++- shaders/triangleVert.spv | Bin 1080 -> 1676 bytes 4 files changed, 171 insertions(+), 8 deletions(-) diff --git a/VulkanTutorial.cpp b/VulkanTutorial.cpp index 8ea7e31..5fffc5b 100644 --- a/VulkanTutorial.cpp +++ b/VulkanTutorial.cpp @@ -115,6 +115,7 @@ void HelloTriangleApplication::initVulkan() { createImageView(); createRenderPass(); + createDescriptorSetLayout(); createGraphicPipeline(); creatFramebuffers(); @@ -123,6 +124,10 @@ void HelloTriangleApplication::initVulkan() { createVertexBuffer(); createIndexBuffer(); + createUniformBuffers(); + + createDescriptorPool(); + createDescriptorSets(); createCommandBuffer(); @@ -152,6 +157,14 @@ void HelloTriangleApplication::cleanup(GLFWwindow* window) { cleanupSwapChain(); + for (size_t i = 0; i < MAX_FRAME_IN_FLIGHT; i++) + { + vkDestroyBuffer(device, uniformBuffers[i], nullptr); + vkFreeMemory(device, uniformBuffersMemory[i], nullptr); + } + vkDestroyDescriptorPool(device, descriptorPool, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + vkDestroyBuffer(device, indexBuffer, nullptr); vkFreeMemory(device, indexBufferMemory, nullptr); vkDestroyBuffer(device, vertexBuffer, nullptr); @@ -760,6 +773,95 @@ void HelloTriangleApplication::createIndexBuffer() vkFreeMemory(device, stagingBufferMemory, nullptr); } +void HelloTriangleApplication::createUniformBuffers() +{ + VkDeviceSize bufferSize = sizeof(UniformBufferObject); + + uniformBuffers.resize(MAX_FRAME_IN_FLIGHT); + uniformBuffersMemory.resize(MAX_FRAME_IN_FLIGHT); + uniformBuffersMapped.resize(MAX_FRAME_IN_FLIGHT); + + for (size_t i = 0; i < MAX_FRAME_IN_FLIGHT; i++) + { + createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, uniformBuffers[i], uniformBuffersMemory[i]); + vkMapMemory(device, uniformBuffersMemory[i], 0, bufferSize, 0, &uniformBuffersMapped[i]); + } + +} + +void HelloTriangleApplication::createDescriptorPool() +{ + VkDescriptorPoolSize poolSize{}; + poolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + poolSize.descriptorCount = static_cast(MAX_FRAME_IN_FLIGHT); + + VkDescriptorPoolCreateInfo poolInfo{}; + poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + poolInfo.poolSizeCount = 1; + poolInfo.pPoolSizes = &poolSize; + poolInfo.maxSets = static_cast(MAX_FRAME_IN_FLIGHT); + + if (vkCreateDescriptorPool(device,&poolInfo,nullptr,&descriptorPool) != VK_SUCCESS) + { + throw std::runtime_error("failed to create descriptor pool"); + } + +} + +void HelloTriangleApplication::createDescriptorSets() +{ + std::vector layouts(MAX_FRAME_IN_FLIGHT,descriptorSetLayout); + VkDescriptorSetAllocateInfo allocInfo{}; + allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + allocInfo.descriptorPool = descriptorPool; + allocInfo.descriptorSetCount = static_cast(MAX_FRAME_IN_FLIGHT); + allocInfo.pSetLayouts = layouts.data(); + + descriptorSets.resize(MAX_FRAME_IN_FLIGHT); + if (vkAllocateDescriptorSets(device,&allocInfo,descriptorSets.data()) != VK_SUCCESS) + { + throw std::runtime_error("failed to allocate descriptor sets in createDescriptoSets"); + } + + for (size_t i = 0; i < MAX_FRAME_IN_FLIGHT; i++) + { + VkDescriptorBufferInfo bufferInfo{}; + bufferInfo.buffer = uniformBuffers[i]; + bufferInfo.offset = 0; + bufferInfo.range = sizeof(UniformBufferObject); + VkWriteDescriptorSet descriptorWrite{}; + descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrite.dstSet = descriptorSets[i]; + descriptorWrite.dstBinding = 0; + descriptorWrite.dstArrayElement = 0; + descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descriptorWrite.descriptorCount = 1; + descriptorWrite.pBufferInfo = &bufferInfo; + descriptorWrite.pImageInfo = nullptr; + descriptorWrite.pTexelBufferView = nullptr; + + vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr); + } + + +} + +void HelloTriangleApplication::updateUniformBuffer(uint32_t currentImage) +{ + static auto startTime = std::chrono::high_resolution_clock::now(); + + auto currentTime = std::chrono::high_resolution_clock::now(); + float time = std::chrono::duration(currentTime - startTime).count(); + + UniformBufferObject ubo{}; + ubo.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f)); + ubo.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f,0.0f,0.1f)); + ubo.proj = glm::perspective(glm::radians(45.0f), swapChainExtent.width / (float)swapChainExtent.height, 0.1f, 10.0f); + ubo.proj[1][1] *= -1; + + memcpy(uniformBuffersMapped[currentImage], &ubo, sizeof(ubo)); +} + void HelloTriangleApplication::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) { VkBufferCreateInfo bufferInfo{}; @@ -862,7 +964,7 @@ void HelloTriangleApplication::createCommandBuffer() } } -void HelloTriangleApplication::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) +void HelloTriangleApplication::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex,uint32_t currentFrame) { VkCommandBufferBeginInfo beginInfo{}; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; @@ -907,6 +1009,8 @@ void HelloTriangleApplication::recordCommandBuffer(VkCommandBuffer commandBuffer // bind indexBuffer vkCmdBindIndexBuffer(commandBuffer, indexBuffer, 0, VK_INDEX_TYPE_UINT16); + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[currentFrame], 0, nullptr); + vkCmdDrawIndexed(commandBuffer, static_cast(indices.size()), 1, 0, 0, 0); vkCmdEndRenderPass(commandBuffer); @@ -942,7 +1046,9 @@ void HelloTriangleApplication::drawFrame() //vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex); vkResetCommandBuffer(commandBuffers[currentFrame], 0); - recordCommandBuffer(commandBuffers[currentFrame], imageIndex); + recordCommandBuffer(commandBuffers[currentFrame], imageIndex,currentFrame); + + updateUniformBuffer(currentFrame); VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; @@ -1069,6 +1175,29 @@ void HelloTriangleApplication::createRenderPass() throw std::runtime_error("failed to create render pass in createRenderPass"); } +} + +void HelloTriangleApplication::createDescriptorSetLayout() +{ + VkDescriptorSetLayoutBinding uboLayoutBinding{}; + uboLayoutBinding.binding = 0; + uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + uboLayoutBinding.descriptorCount = 1; + uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + uboLayoutBinding.pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutCreateInfo layoutInfo{}; + layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + layoutInfo.bindingCount = 1; + layoutInfo.pBindings = &uboLayoutBinding; + + if (vkCreateDescriptorSetLayout(device,&layoutInfo,nullptr,&descriptorSetLayout) != VK_SUCCESS) + { + throw std::runtime_error("failed to create descriptor set layout"); + } + + + } void HelloTriangleApplication::createGraphicPipeline() @@ -1156,7 +1285,7 @@ void HelloTriangleApplication::createGraphicPipeline() rasterizer.lineWidth = 1.0f; rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;// 背面剔除 - rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; + rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; // 根据fragment的斜率偏置深度值 rasterizer.depthBiasEnable = VK_FALSE; @@ -1213,8 +1342,8 @@ void HelloTriangleApplication::createGraphicPipeline() VkPipelineLayoutCreateInfo pipelineLayoutInfo{}; pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipelineLayoutInfo.setLayoutCount = 0; - pipelineLayoutInfo.pSetLayouts = nullptr; + pipelineLayoutInfo.setLayoutCount = 1; + pipelineLayoutInfo.pSetLayouts = &descriptorSetLayout; pipelineLayoutInfo.pushConstantRangeCount = 0; pipelineLayoutInfo.pPushConstantRanges = nullptr; diff --git a/VulkanTutorial.h b/VulkanTutorial.h index b5eb858..f0050c5 100644 --- a/VulkanTutorial.h +++ b/VulkanTutorial.h @@ -3,6 +3,9 @@ #pragma once +#define GLM_FORCE_RADIANS +#include +#include #define GLFW_INCLUDE_VULKAN #include @@ -20,7 +23,7 @@ #include #include #include - +#include #include @@ -68,6 +71,7 @@ private: std::vector swapChainImageViews; VkRenderPass renderPass; + VkDescriptorSetLayout descriptorSetLayout; VkPipelineLayout pipelineLayout; VkPipeline graphicsPipeline; @@ -122,11 +126,25 @@ private: 0,1,2,2,3,0 }; + struct UniformBufferObject + { + alignas(16) glm::mat4 model; + alignas(16) glm::mat4 view; + alignas(16) glm::mat4 proj; + }; + + std::vector uniformBuffers; + std::vector uniformBuffersMemory; + std::vector uniformBuffersMapped; + VkBuffer vertexBuffer; VkDeviceMemory vertexBufferMemory; VkBuffer indexBuffer; VkDeviceMemory indexBufferMemory; + VkDescriptorPool descriptorPool; + std::vector descriptorSets; + void initWindow(int Width, int Height); void createInstance(); @@ -175,6 +193,7 @@ private: void createImageView(); void createRenderPass(); + void createDescriptorSetLayout(); void createGraphicPipeline(); static std::vector readFile(const std::string& filename); @@ -187,6 +206,13 @@ private: void createVertexBuffer(); void createIndexBuffer(); + void createUniformBuffers(); + + void createDescriptorPool(); + void createDescriptorSets(); + + void updateUniformBuffer(uint32_t currentImage); + void createBuffer(VkDeviceSize size,VkBufferUsageFlags usage,VkMemoryPropertyFlags properties,VkBuffer& buffer,VkDeviceMemory& bufferMemory); void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size); @@ -195,7 +221,8 @@ private: void createCommandBuffer(); - void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex); + void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex,uint32_t currentFrame); + void drawFrame(); diff --git a/shaders/triangle.vert b/shaders/triangle.vert index 6b72343..52b6925 100644 --- a/shaders/triangle.vert +++ b/shaders/triangle.vert @@ -5,9 +5,16 @@ layout(location = 1) in vec3 inColor; layout(location = 0) out vec3 fragColor; +layout(binding = 0) uniform uniformBufferObject{ + + mat4 model; + mat4 view; + mat4 proj; + +}ubo; void main(){ - gl_Position = vec4(inPosition, 0.0, 1.0); + gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition,0.0,1.0); fragColor = inColor; } \ No newline at end of file diff --git a/shaders/triangleVert.spv b/shaders/triangleVert.spv index 1e4ce0c041e7ee15f8cf030b9c3e352942361e75..e2c02b66a3dda41a2c4062de0c707e8f75151ac6 100644 GIT binary patch literal 1676 zcmZ9L+fEZv6o$8y0R#aNIjD#&ct$HGYD|nrB;}$>F(lqL&`!xF!%Q=s;^B%{&`0vA zyfN|r_RMZZH(6b4{p+~@JygavCylvaX3VU4YVxyS#)KGQ6HYgp2hI8*>(-w=-zHq5A-IKd>0`*vs9>%tpq^BQ- zyjE7&8{7hewI*!0~M3(X|`~@4fW! zcqfUH)YXi;cd&7e>?sSbI9_{<`Cw>|F&~UOdkhY9q5op~ z_{?ROm)9}3T!&BHJBjZF_J19-%XRqFolATjn6G1J_5y2YXE@!EaJ*m3UFT!3mwY%b z`+Vp4?6#<`^sQ+IJYg@(nvkwaRy2=2@ZoPszf;mx31_SD`Ol)?n*3>L^1;?+!ME>0 z45=#bk~A}kzbbsbNigQjNmnKGWe)zlgtIE2x1cY3tru?x=7kwo}xwjA%@cHa40>L1AFzTAWUThi2k z5r0(J;Pl7mJ$<|`JD-)u@p)gc7vh9H;fF)bZy|hp@Ab=FmnHB42d|aMy;mgQKIfWj za^S(|T$c_0Q+=qpA)yZ3*R9E>jyLmlH)VtSI=(|{!O4Ng4M|P%Nxk9XPJu~{u)77u zJ@>^P{N0m~OKejD&p*_I*nJ7J$YDQte<giOpt2xJ3s0hxr}j8kznF2RA| zIiVvyxV*Zzez&IO`)Zjt`YRDxtVbEgv+{AR84*Vy%?96j5zXo&Yqb?##)IMA=yfzE zE@CNC^_2}z?ul&a0-xOK|2$O>`RAlVW|Pb^Xn-Dki$4SEmo;~q+Bw|XZQxt*_ME-l z*uO`d15OC%AMo3wX8y2_(a+`!6tuS}(5B05)POuyr$v8q1=CgwXz7`w9lcX)e1BS} t)|~W&8SU%>Yt4Crwr`oC<$X|s4RDPYx%KYUNiQf%1SYkM5I-2b0Kc}`8@>Pl