From 09b9841c03b193b9f7bb2e389a1ea20c46c200c1 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Thu, 12 Aug 2021 23:29:45 -0700 Subject: [PATCH] Vulkan triangle! Switched to Vulkan 1.1 GLSL dialect Added vulkan test shader Implemented test render thread function --- kraken/KRContext.cpp | 39 ++++++++++++++++++++++-- kraken/KRPipeline.cpp | 10 ++++++ kraken/KRPipelineManager.cpp | 4 +-- kraken/KRShaderManager.cpp | 2 ++ standard_assets/shaders/CMakeLists.txt | 2 ++ standard_assets/shaders/vulkan_test.frag | 12 ++++++++ standard_assets/shaders/vulkan_test.vert | 23 ++++++++++++++ 7 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 standard_assets/shaders/vulkan_test.frag create mode 100644 standard_assets/shaders/vulkan_test.vert diff --git a/kraken/KRContext.cpp b/kraken/KRContext.cpp index 2a2bd61..2a705a0 100755 --- a/kraken/KRContext.cpp +++ b/kraken/KRContext.cpp @@ -1106,7 +1106,7 @@ KrResult KRContext::createWindowSurface(const KrCreateWindowSurfaceInfo* createW m_pPipelineManager->createPipelines(surfaceHandle); { - KRPipeline* testPipeline = m_pPipelineManager->get("simple_blit"); + KRPipeline* testPipeline = m_pPipelineManager->get("vulkan_test"); SurfaceInfo& surface = m_surfaces[surfaceHandle]; surface.swapChainFramebuffers.resize(surface.swapChainImageViews.size()); @@ -1200,9 +1200,13 @@ void KRContext::renderFrame() for (auto surfaceItr = m_surfaces.begin(); surfaceItr != m_surfaces.end(); surfaceItr++) { SurfaceInfo& surface = (*surfaceItr).second; DeviceInfo& device = GetDeviceInfo(surface.deviceHandle); + + uint32_t imageIndex = 0; + vkAcquireNextImageKHR(device.logicalDevice, surface.swapChain, UINT64_MAX, surface.imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex); + // TODO - this will break with more than one surface... Expect to refactor this out - VkCommandBuffer commandBuffer = device.graphicsCommandBuffers[frameIndex % device.graphicsCommandBuffers.size()]; - KRPipeline* testPipeline = m_pPipelineManager->get("simple_blit"); + VkCommandBuffer commandBuffer = device.graphicsCommandBuffers[imageIndex]; + KRPipeline* testPipeline = m_pPipelineManager->get("vulkan_test"); VkCommandBufferBeginInfo beginInfo{}; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; @@ -1231,6 +1235,35 @@ void KRContext::renderFrame() if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) { // TODO - Add error handling... } + + VkSubmitInfo submitInfo{}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + + VkSemaphore waitSemaphores[] = { surface.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 signalSemaphores[] = { surface.renderFinishedSemaphore }; + submitInfo.signalSemaphoreCount = 1; + submitInfo.pSignalSemaphores = signalSemaphores; + + if (vkQueueSubmit(device.graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS) { + // TODO - Add error handling... + } + + VkPresentInfoKHR presentInfo{}; + presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + presentInfo.waitSemaphoreCount = 1; + presentInfo.pWaitSemaphores = signalSemaphores; + presentInfo.swapchainCount = 1; + presentInfo.pSwapchains = &surface.swapChain; + presentInfo.pImageIndices = &imageIndex; + presentInfo.pResults = nullptr; + vkQueuePresentKHR(device.graphicsQueue, &presentInfo); } frameIndex++; diff --git a/kraken/KRPipeline.cpp b/kraken/KRPipeline.cpp index a065fb8..037fce1 100644 --- a/kraken/KRPipeline.cpp +++ b/kraken/KRPipeline.cpp @@ -163,12 +163,22 @@ KRPipeline::KRPipeline(KRContext& context, KrSurfaceHandle surfaceHandle, const 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.logicalDevice, &renderPassInfo, nullptr, &m_renderPass) != VK_SUCCESS) { // failed! TODO - Error handling diff --git a/kraken/KRPipelineManager.cpp b/kraken/KRPipelineManager.cpp index e0e46fb..76592c3 100644 --- a/kraken/KRPipelineManager.cpp +++ b/kraken/KRPipelineManager.cpp @@ -65,8 +65,8 @@ KRPipelineManager::~KRPipelineManager() { void KRPipelineManager::createPipelines(KrSurfaceHandle surface) { { - // simple_blit - std::string pipeline_name = "simple_blit"; + // vulkan_test + std::string pipeline_name = "vulkan_test"; std::vector shaders; shaders.push_back(m_pContext->getShaderManager()->get(pipeline_name + ".vert", "spv")); shaders.push_back(m_pContext->getShaderManager()->get(pipeline_name + ".frag", "spv")); diff --git a/kraken/KRShaderManager.cpp b/kraken/KRShaderManager.cpp index 6a295d6..1956c0c 100644 --- a/kraken/KRShaderManager.cpp +++ b/kraken/KRShaderManager.cpp @@ -258,7 +258,9 @@ bool KRShaderManager::compileAll(KRBundle* outputBundle, KRUnknown* logResource) glslang::TShader vertShader(EShLangVertex); glslang::TShader fragShader(EShLangFragment); vertShader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3); + vertShader.setEnvClient(glslang::EShClientVulkan, glslang::EshTargetClientVersion::EShTargetVulkan_1_1); fragShader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3); + fragShader.setEnvClient(glslang::EShClientVulkan, glslang::EshTargetClientVersion::EShTargetVulkan_1_1); glslang::TProgram program; // this must be declared after the TShader's to ensure it is deallocated before the TShader's if (vertSource) { vertSource->getData()->lock(); diff --git a/standard_assets/shaders/CMakeLists.txt b/standard_assets/shaders/CMakeLists.txt index d2e5243..b9055b9 100644 --- a/standard_assets/shaders/CMakeLists.txt +++ b/standard_assets/shaders/CMakeLists.txt @@ -3,3 +3,5 @@ add_standard_asset(simple_blit.frag) add_standard_asset(simple_blit.vert) add_standard_asset(sprite.frag) add_standard_asset(sprite.vert) +add_standard_asset(vulkan_test.vert) +add_standard_asset(vulkan_test.frag) diff --git a/standard_assets/shaders/vulkan_test.frag b/standard_assets/shaders/vulkan_test.frag new file mode 100644 index 0000000..33a2222 --- /dev/null +++ b/standard_assets/shaders/vulkan_test.frag @@ -0,0 +1,12 @@ +#version 450 + +// Temporary test shader for vulkan bringup... +// See https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Shader_modules + +layout(location = 0) in vec3 fragColor; + +layout(location = 0) out vec4 outColor; + +void main() { + outColor = vec4(fragColor, 1.0); +} diff --git a/standard_assets/shaders/vulkan_test.vert b/standard_assets/shaders/vulkan_test.vert new file mode 100644 index 0000000..56ec6dc --- /dev/null +++ b/standard_assets/shaders/vulkan_test.vert @@ -0,0 +1,23 @@ +#version 450 + +// Temporary test shader for vulkan bringup... +// See https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Shader_modules + +layout(location = 0) out vec3 fragColor; + +vec2 positions[3] = vec2[]( + vec2(0.0, -0.5), + vec2(0.5, 0.5), + vec2(-0.5, 0.5) +); + +vec3 colors[3] = vec3[]( + vec3(1.0, 0.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 0.0, 1.0) +); + +void main() { + gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); + fragColor = colors[gl_VertexIndex]; +}