Triangle drawn
This commit is contained in:
@@ -155,6 +155,14 @@ private:
|
||||
|
||||
VkPipeline graphicsPipeline;
|
||||
|
||||
VkCommandPool commandPool;
|
||||
VkCommandBuffer commandBuffer;
|
||||
|
||||
VkSemaphore imageAvailableSemaphore, renderFinishedSemaphore;
|
||||
VkFence inFlightFence;
|
||||
|
||||
std::vector<VkFramebuffer> swapChainFramebuffers;
|
||||
|
||||
void createInstance(){
|
||||
if(enableValidationLayers && !checkValidationLayerSupport()){
|
||||
throw std::runtime_error("Func: createInstance\nError: Validation Layers requested, but not available!\n");
|
||||
@@ -541,6 +549,7 @@ private:
|
||||
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
inputAssembly.primitiveRestartEnable = VK_FALSE;
|
||||
|
||||
/*
|
||||
VkViewport viewport{};
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
@@ -548,17 +557,20 @@ private:
|
||||
viewport.height = (float)swapChainExtent.height;
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
|
||||
|
||||
VkRect2D scissor{};
|
||||
scissor.offset = { 0, 0 };
|
||||
scissor.extent = swapChainExtent;
|
||||
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
||||
*/
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportState{};
|
||||
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
viewportState.viewportCount = 1;
|
||||
viewportState.pViewports = &viewport; // possibly made immutable
|
||||
// viewportState.pViewports = &viewport; // possibly made immutable
|
||||
viewportState.scissorCount = 1;
|
||||
viewportState.pScissors = &scissor; // possibly made immutable
|
||||
// viewportState.pScissors = &scissor; // possibly made immutable
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterizer{};
|
||||
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
@@ -660,18 +672,175 @@ private:
|
||||
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_WRITE_BIT;
|
||||
|
||||
VkRenderPassCreateInfo renderPassInfo{};
|
||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
renderPassInfo.attachmentCount = 1;
|
||||
renderPassInfo.pAttachments = &colorAttachment;
|
||||
renderPassInfo.subpassCount = 1;
|
||||
renderPassInfo.pSubpasses = &subpass;
|
||||
renderPassInfo.dependencyCount = 1;
|
||||
renderPassInfo.pDependencies = &dependency;
|
||||
|
||||
if(vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS){
|
||||
throw std::runtime_error("Func: createRenderPass\nError: Failed to create render pass!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void createFrameBuffers(){
|
||||
swapChainFramebuffers.resize(swapChainImageViews.size());
|
||||
|
||||
for(size_t i = 0; i < swapChainImageViews.size(); i++){
|
||||
VkImageView attachements[] = { swapChainImageViews[i] };
|
||||
|
||||
VkFramebufferCreateInfo framebufferInfo{};
|
||||
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
framebufferInfo.renderPass = renderPass;
|
||||
framebufferInfo.attachmentCount = 1;
|
||||
framebufferInfo.pAttachments = attachements;
|
||||
framebufferInfo.width = swapChainExtent.width;
|
||||
framebufferInfo.height = swapChainExtent.height;
|
||||
framebufferInfo.layers = 1;
|
||||
|
||||
if(vkCreateFramebuffer(device, &framebufferInfo, nullptr, &swapChainFramebuffers[i]) != VK_SUCCESS){
|
||||
throw std::runtime_error("Func: createFrameBuffers\nError: Failed to create Framebuffer!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createCommandPool(){
|
||||
QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice);
|
||||
VkCommandPoolCreateInfo poolInfo{};
|
||||
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();
|
||||
|
||||
if(vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS){
|
||||
throw std::runtime_error("Func: createCommandPool\nError: Failed to create Command Pool!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void createCommandBuffer(){
|
||||
VkCommandBufferAllocateInfo allocInfo{};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
allocInfo.commandPool = commandPool;
|
||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
allocInfo.commandBufferCount = 1;
|
||||
|
||||
if(vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer) != VK_SUCCESS){
|
||||
throw std::runtime_error("Func: createCommandBuffer\nError: Failed to allocate Command Buffers!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex){
|
||||
VkCommandBufferBeginInfo beginInfo{};
|
||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
|
||||
if(vkBeginCommandBuffer(commandBuffer, &beginInfo) != VK_SUCCESS){
|
||||
throw std::runtime_error("Func: recordCommandBuffer\nError: Failed to begin recording command buffer!\n");
|
||||
}
|
||||
|
||||
VkRenderPassBeginInfo renderPassInfo{};
|
||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderPassInfo.renderPass = renderPass;
|
||||
renderPassInfo.framebuffer = swapChainFramebuffers[imageIndex];
|
||||
renderPassInfo.renderArea.offset = { 0, 0 };
|
||||
renderPassInfo.renderArea.extent = swapChainExtent;
|
||||
|
||||
VkClearValue clearColor = {{{0.0f, 0.0f, 0.0f, 1.0f}}}; // Background color after clear (Black 100%)
|
||||
renderPassInfo.clearValueCount = 1;
|
||||
renderPassInfo.pClearValues = &clearColor;
|
||||
|
||||
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
|
||||
|
||||
VkViewport viewport{};
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
viewport.width = (float)swapChainExtent.width;
|
||||
viewport.height = (float)swapChainExtent.height;
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
|
||||
|
||||
VkRect2D scissor{};
|
||||
scissor.offset = { 0, 0 };
|
||||
scissor.extent = swapChainExtent;
|
||||
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
||||
|
||||
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
|
||||
|
||||
vkCmdEndRenderPass(commandBuffer);
|
||||
if(vkEndCommandBuffer(commandBuffer) != VK_SUCCESS){
|
||||
throw std::runtime_error("Func: recordCommandBuffer\nError: Failed to record command buffer!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void createSyncObjects(){
|
||||
VkSemaphoreCreateInfo semaphoreInfo{};
|
||||
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
|
||||
VkFenceCreateInfo fenceInfo{};
|
||||
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
|
||||
if(vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphore) != VK_SUCCESS
|
||||
|| vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore) != VK_SUCCESS
|
||||
|| vkCreateFence(device, &fenceInfo, nullptr, &inFlightFence) != VK_SUCCESS){
|
||||
throw std::runtime_error("Func: createSyncObjects\nError: Failed to create semaphores!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void drawFrame(){
|
||||
vkWaitForFences(device, 1, &inFlightFence, VK_TRUE, UINT64_MAX);
|
||||
vkResetFences(device, 1, &inFlightFence);
|
||||
|
||||
uint32_t imageIndex;
|
||||
vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
|
||||
|
||||
vkResetCommandBuffer(commandBuffer, 0);
|
||||
recordCommandBuffer(commandBuffer, 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 = &commandBuffer;
|
||||
|
||||
VkSemaphore signalSemaphore[] = { renderFinishedSemaphore };
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = signalSemaphore;
|
||||
|
||||
if(vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFence) != VK_SUCCESS){
|
||||
throw std::runtime_error("Func: drawFrame\nError: Failed to submit draw command buffer!\n");
|
||||
}
|
||||
|
||||
VkPresentInfoKHR presentInfo{};
|
||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
presentInfo.waitSemaphoreCount = 1;
|
||||
presentInfo.pWaitSemaphores = signalSemaphore;
|
||||
|
||||
VkSwapchainKHR swapChains[] = { swapChain };
|
||||
presentInfo.swapchainCount = 1;
|
||||
presentInfo.pSwapchains = swapChains;
|
||||
presentInfo.pImageIndices = &imageIndex;
|
||||
|
||||
vkQueuePresentKHR(presentQueue, &presentInfo);
|
||||
}
|
||||
|
||||
void initWindow(){
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); // tell glfw to not use opengl
|
||||
@@ -689,17 +858,32 @@ private:
|
||||
createImageViews();
|
||||
createRenderPass();
|
||||
createGraphicsPipeline();
|
||||
createFrameBuffers();
|
||||
createCommandPool();
|
||||
createCommandBuffer();
|
||||
createSyncObjects();
|
||||
}
|
||||
|
||||
void mainLoop(){
|
||||
while(!glfwWindowShouldClose(this->window)){
|
||||
glfwSwapBuffers(window);
|
||||
// glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
drawFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup(){
|
||||
// Vulkan
|
||||
vkDestroySemaphore(device, imageAvailableSemaphore, nullptr);
|
||||
vkDestroySemaphore(device, renderFinishedSemaphore, nullptr);
|
||||
vkDestroyFence(device, inFlightFence, nullptr);
|
||||
|
||||
vkDestroyCommandPool(device, commandPool, nullptr);
|
||||
|
||||
for(VkFramebuffer framebuffer : swapChainFramebuffers){
|
||||
vkDestroyFramebuffer(device, framebuffer, nullptr);
|
||||
}
|
||||
|
||||
vkDestroyPipeline(device, graphicsPipeline, nullptr);
|
||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||
vkDestroyRenderPass(device, renderPass, nullptr);
|
||||
|
||||
Reference in New Issue
Block a user