Drawing part#1
This commit is contained in:
parent
49e97858b1
commit
59400c190d
1 changed files with 209 additions and 21 deletions
230
Vulkan/main.cpp
230
Vulkan/main.cpp
|
@ -109,7 +109,17 @@ private:
|
|||
|
||||
std::vector<VkImageView> swapChainImageViews;
|
||||
|
||||
VkRenderPass renderPass;
|
||||
VkPipelineLayout pipelineLayout;
|
||||
VkPipeline graphicsPipeline;
|
||||
|
||||
std::vector<VkFramebuffer> swapChainFramebuffers;
|
||||
|
||||
VkCommandPool commandPool;
|
||||
std::vector<VkCommandBuffer> commandBuffers;
|
||||
|
||||
VkSemaphore imageAvailableSemaphore;
|
||||
VkSemaphore renderFinishedSemaphore;
|
||||
|
||||
void initWindow() {
|
||||
glfwInit();
|
||||
|
@ -125,18 +135,34 @@ private:
|
|||
pickPhysicalDevice();
|
||||
createLogicalDevice();
|
||||
createSwapChain();
|
||||
createImageView();
|
||||
createRenderPass();
|
||||
createGraphicsPipeline();
|
||||
createFrameBuffers();
|
||||
createCommandPool();
|
||||
createCommandBuffers();
|
||||
createSemaphores();
|
||||
}
|
||||
|
||||
|
||||
void mainLoop() {
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
glfwPollEvents();
|
||||
drawFrame();
|
||||
}
|
||||
vkDeviceWaitIdle(device);
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
vkDestroySemaphore(device, imageAvailableSemaphore, nullptr);
|
||||
vkDestroySemaphore(device, renderFinishedSemaphore, nullptr);
|
||||
vkDestroyCommandPool(device,commandPool,nullptr);
|
||||
for (auto framebuffer : swapChainFramebuffers) {
|
||||
vkDestroyFramebuffer(device,framebuffer,nullptr);
|
||||
}
|
||||
vkDestroyPipeline(device, graphicsPipeline, nullptr);
|
||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||
vkDestroyRenderPass(device, renderPass, nullptr);
|
||||
for (auto imageView : swapChainImageViews) {
|
||||
vkDestroyImageView(device, imageView, nullptr);
|
||||
}
|
||||
|
@ -532,10 +558,9 @@ private:
|
|||
auto vertShaderCode = readFile("shaders/vert.spv");
|
||||
auto fragShaderCode = readFile("shaders/frag.spv");
|
||||
|
||||
|
||||
VkShaderModule vertShaderModule = createShaderModule(vertShaderCode);
|
||||
VkShaderModule fragShaderModule = createShaderModule(fragShaderCode);
|
||||
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertShaderStageInfo = {};
|
||||
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
|
@ -550,14 +575,10 @@ private:
|
|||
|
||||
VkPipelineShaderStageCreateInfo shaderStages[] = { vertShaderStageInfo, fragShaderStageInfo };
|
||||
|
||||
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
|
||||
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
vertexInputInfo.vertexBindingDescriptionCount = 0;
|
||||
vertexInputInfo.pVertexBindingDescriptions = nullptr; // Optional
|
||||
vertexInputInfo.vertexAttributeDescriptionCount = 0;
|
||||
vertexInputInfo.pVertexAttributeDescriptions = nullptr; // Optional
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
|
||||
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
|
@ -588,25 +609,15 @@ private:
|
|||
rasterizer.depthClampEnable = VK_FALSE;
|
||||
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
||||
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
|
||||
rasterizer.lineWidth = 1.0f;
|
||||
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
|
||||
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||
|
||||
rasterizer.depthBiasEnable = VK_FALSE;
|
||||
rasterizer.depthBiasConstantFactor = 0.0f; // Optional
|
||||
rasterizer.depthBiasClamp = 0.0f; // Optional
|
||||
rasterizer.depthBiasSlopeFactor = 0.0f; // Optional
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisampling = {};
|
||||
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
multisampling.sampleShadingEnable = VK_FALSE;
|
||||
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
multisampling.minSampleShading = 1.0f; // Optional
|
||||
multisampling.pSampleMask = nullptr; // Optional
|
||||
multisampling.alphaToCoverageEnable = VK_FALSE; // Optional
|
||||
multisampling.alphaToOneEnable = VK_FALSE; // Optional
|
||||
|
||||
|
||||
VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
|
||||
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
|
@ -625,19 +636,34 @@ private:
|
|||
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
|
||||
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
pipelineLayoutInfo.setLayoutCount = 0; // Optional
|
||||
pipelineLayoutInfo.pSetLayouts = nullptr; // Optional
|
||||
pipelineLayoutInfo.pushConstantRangeCount = 0; // Optional
|
||||
pipelineLayoutInfo.pPushConstantRanges = nullptr; // Optional
|
||||
pipelineLayoutInfo.setLayoutCount = 0;
|
||||
pipelineLayoutInfo.pushConstantRangeCount = 0;
|
||||
|
||||
if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to create pipeline layout!");
|
||||
}
|
||||
|
||||
VkGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
pipelineInfo.stageCount = 2;
|
||||
pipelineInfo.pStages = shaderStages;
|
||||
pipelineInfo.pVertexInputState = &vertexInputInfo;
|
||||
pipelineInfo.pInputAssemblyState = &inputAssembly;
|
||||
pipelineInfo.pViewportState = &viewportState;
|
||||
pipelineInfo.pRasterizationState = &rasterizer;
|
||||
pipelineInfo.pMultisampleState = &multisampling;
|
||||
pipelineInfo.pColorBlendState = &colorBlending;
|
||||
pipelineInfo.layout = pipelineLayout;
|
||||
pipelineInfo.renderPass = renderPass;
|
||||
pipelineInfo.subpass = 0;
|
||||
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
|
||||
if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &graphicsPipeline) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to create graphics pipeline!");
|
||||
}
|
||||
|
||||
vkDestroyShaderModule(device, fragShaderModule, nullptr);
|
||||
vkDestroyShaderModule(device, vertShaderModule, nullptr);
|
||||
|
||||
}
|
||||
VkShaderModule createShaderModule(const std::vector<char>& code) {
|
||||
VkShaderModuleCreateInfo createInfo = {};
|
||||
|
@ -650,8 +676,170 @@ private:
|
|||
}
|
||||
return shaderModule;
|
||||
}
|
||||
void createRenderPass() {
|
||||
VkAttachmentDescription colorAttachment = {};
|
||||
colorAttachment.format = swapChainImageFormat;
|
||||
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
|
||||
VkAttachmentReference colorAttachmentRef = {};
|
||||
colorAttachmentRef.attachment = 0;
|
||||
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkSubpassDescription subpass = {};
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpass.colorAttachmentCount = 1;
|
||||
subpass.pColorAttachments = &colorAttachmentRef;
|
||||
|
||||
VkSubpassDependency dependency = {};
|
||||
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
dependency.dstSubpass = 0;
|
||||
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependency.srcAccessMask = 0;
|
||||
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
VkRenderPassCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
createInfo.attachmentCount = 1;
|
||||
createInfo.pAttachments = &colorAttachment;
|
||||
createInfo.subpassCount = 1;
|
||||
createInfo.pSubpasses = &subpass;
|
||||
createInfo.dependencyCount = 1;
|
||||
createInfo.pDependencies = &dependency;
|
||||
if (vkCreateRenderPass(device,&createInfo,nullptr,&renderPass) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to create render pass!");
|
||||
}
|
||||
|
||||
}
|
||||
void createFrameBuffers() {
|
||||
swapChainFramebuffers.resize(swapChainImageViews.size());
|
||||
for (size_t i = 0; i < swapChainImageViews.size();i++) {
|
||||
VkImageView attachments[] = { swapChainImageViews[i] };
|
||||
VkFramebufferCreateInfo framebufferInfo = {};
|
||||
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
framebufferInfo.attachmentCount = 1;
|
||||
framebufferInfo.pAttachments = attachments;
|
||||
framebufferInfo.renderPass = renderPass;
|
||||
framebufferInfo.width = swapChainExtent.width;
|
||||
framebufferInfo.height = swapChainExtent.height;
|
||||
framebufferInfo.layers = 1;
|
||||
|
||||
if (vkCreateFramebuffer(device,&framebufferInfo,nullptr,&swapChainFramebuffers[i] ) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to create framebuffer!");
|
||||
}
|
||||
}
|
||||
}
|
||||
void createCommandPool() {
|
||||
QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice);
|
||||
|
||||
VkCommandPoolCreateInfo poolInfo = {};
|
||||
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();
|
||||
poolInfo.flags = 0;
|
||||
|
||||
if (vkCreateCommandPool(device,&poolInfo,nullptr,&commandPool) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to create command pool!");
|
||||
}
|
||||
|
||||
}
|
||||
void createCommandBuffers() {
|
||||
commandBuffers.resize(swapChainFramebuffers.size());
|
||||
VkCommandBufferAllocateInfo allocInfo = {};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
allocInfo.commandPool = commandPool;
|
||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
allocInfo.commandBufferCount = (uint32_t)commandBuffers.size();
|
||||
|
||||
if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to allocate command buffers!");
|
||||
}
|
||||
for (size_t i = 0; i < commandBuffers.size();i++) {
|
||||
VkCommandBufferBeginInfo beginInfo = {};
|
||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
beginInfo.flags = 0;
|
||||
beginInfo.pInheritanceInfo = nullptr;
|
||||
if (vkBeginCommandBuffer(commandBuffers[i], &beginInfo) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to begin recording command buffer!");
|
||||
}
|
||||
|
||||
VkRenderPassBeginInfo renderPassInfo = {};
|
||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderPassInfo.renderPass = renderPass;
|
||||
renderPassInfo.framebuffer = swapChainFramebuffers[i];
|
||||
renderPassInfo.renderArea.extent = swapChainExtent;
|
||||
renderPassInfo.renderArea.offset = {0,0};
|
||||
VkClearValue clearColor = { 0.0f,0.0f,0.0f,1.0f };
|
||||
renderPassInfo.clearValueCount = 1;
|
||||
renderPassInfo.pClearValues = &clearColor;
|
||||
|
||||
vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
vkCmdBindPipeline(commandBuffers[i],VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline);
|
||||
|
||||
vkCmdDraw(commandBuffers[i], 3, 1, 0, 0);
|
||||
vkCmdEndRenderPass(commandBuffers[i]);
|
||||
|
||||
if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to record command buffer!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void drawFrame(){
|
||||
uint32_t imageIndex;
|
||||
vkAcquireNextImageKHR(device, swapChain, std::numeric_limits<uint32_t>::max(), imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
|
||||
|
||||
VkSubmitInfo submitInfo = {};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
|
||||
VkSemaphore waitSemaphores[] = { imageAvailableSemaphore };
|
||||
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||
submitInfo.waitSemaphoreCount = 1;
|
||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
||||
submitInfo.pWaitDstStageMask = waitStages;
|
||||
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &commandBuffers[imageIndex];
|
||||
|
||||
VkSemaphore signalSemaphores[] = { renderFinishedSemaphore };
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||
|
||||
if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to submit draw command buffer!");
|
||||
}
|
||||
|
||||
|
||||
VkPresentInfoKHR presentInfo = {};
|
||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
presentInfo.waitSemaphoreCount = 1;
|
||||
presentInfo.pWaitSemaphores = signalSemaphores;
|
||||
|
||||
VkSwapchainKHR swapchains[] = {swapChain};
|
||||
presentInfo.swapchainCount = 1;
|
||||
presentInfo.pSwapchains = swapchains;
|
||||
presentInfo.pImageIndices = &imageIndex;
|
||||
presentInfo.pResults = nullptr; // Optional
|
||||
|
||||
vkQueuePresentKHR(presentQueue, &presentInfo);
|
||||
|
||||
vkQueueWaitIdle(presentQueue);
|
||||
}
|
||||
|
||||
void createSemaphores(){
|
||||
VkSemaphoreCreateInfo semaphoreInfo = {};
|
||||
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphore) != VK_SUCCESS ||
|
||||
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore) != VK_SUCCESS) {
|
||||
|
||||
throw std::runtime_error("failed to create semaphores!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue