|
@@ -11,7 +11,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
static VkPhysicalDevice physicalDevice;
|
|
|
static u32 graphicsFamily = 0;
|
|
@@ -21,8 +20,14 @@ static VkQueue graphicsQueue;
|
|
|
static VkQueue presentQueue;
|
|
|
static VkSurfaceFormatKHR surfaceFormat;
|
|
|
static VkSurfaceKHR surface;
|
|
|
+static VkExtent2D swapchainSize;
|
|
|
static VkSwapchainKHR swapchain;
|
|
|
static VulkanSwapchainImages images;
|
|
|
+static VkShaderModule vertexShaderModule;
|
|
|
+static VkShaderModule fragmentShaderModule;
|
|
|
+static VkPipelineLayout pipelineLayout;
|
|
|
+static VkRenderPass renderPass;
|
|
|
+static VkPipeline pipeline;
|
|
|
|
|
|
static int getSurfaceFormatPoints(const VkSurfaceFormatKHR* sf) {
|
|
|
if(sf->format == VK_FORMAT_B8G8R8A8_UNORM &&
|
|
@@ -74,6 +79,7 @@ static bool initSwapchain() {
|
|
|
LOG_ERROR("Could not retrieve any swapchain size");
|
|
|
return true;
|
|
|
}
|
|
|
+ swapchainSize = d.size;
|
|
|
if(findVulkanSurfaceFormat(
|
|
|
&d.surfaceFormat, physicalDevice, surface, getSurfaceFormatPoints)) {
|
|
|
LOG_ERROR("Could not find surface format");
|
|
@@ -197,26 +203,172 @@ static bool initSwapchainImages() {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+static bool initShaders() {
|
|
|
+ return initVulkanShaderModule(
|
|
|
+ &vertexShaderModule, device, "shaders/vertex.spv") ||
|
|
|
+ initVulkanShaderModule(
|
|
|
+ &fragmentShaderModule, device, "shaders/fragment.spv");
|
|
|
+}
|
|
|
+
|
|
|
+static bool initPipeline() {
|
|
|
+ VkPipelineShaderStageCreateInfo stages[2] = {
|
|
|
+ {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
+ .stage = VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
+ .module = vertexShaderModule,
|
|
|
+ .pName = "main"},
|
|
|
+ {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
+ .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
|
+ .module = fragmentShaderModule,
|
|
|
+ .pName = "main"}};
|
|
|
+
|
|
|
+ VkPipelineVertexInputStateCreateInfo vertexInputState = {
|
|
|
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO};
|
|
|
+
|
|
|
+ VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = {
|
|
|
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
|
|
+ .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
|
|
|
+ .primitiveRestartEnable = false};
|
|
|
+
|
|
|
+ VkViewport viewport = {
|
|
|
+ .x = 0.0f,
|
|
|
+ .y = 0.0f,
|
|
|
+ .width = (float)swapchainSize.width,
|
|
|
+ .height = (float)swapchainSize.height,
|
|
|
+ .minDepth = 0.0f,
|
|
|
+ .maxDepth = 1.0f};
|
|
|
+ VkRect2D scissor = {.offset = {0, 0}, .extent = swapchainSize};
|
|
|
+ VkPipelineViewportStateCreateInfo viewportState = {
|
|
|
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
|
|
+ .viewportCount = 1,
|
|
|
+ .pViewports = &viewport,
|
|
|
+ .scissorCount = 1,
|
|
|
+ .pScissors = &scissor};
|
|
|
+
|
|
|
+ VkPipelineRasterizationStateCreateInfo rasterizationState = {
|
|
|
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
|
|
+ .depthClampEnable = false,
|
|
|
+ .rasterizerDiscardEnable = false,
|
|
|
+ .polygonMode = VK_POLYGON_MODE_FILL,
|
|
|
+ .cullMode = VK_CULL_MODE_BACK_BIT,
|
|
|
+ .frontFace = VK_FRONT_FACE_CLOCKWISE,
|
|
|
+ .depthBiasEnable = false,
|
|
|
+ .depthBiasConstantFactor = 0.0f,
|
|
|
+ .depthBiasClamp = 0.0f,
|
|
|
+ .depthBiasSlopeFactor = 0.0f,
|
|
|
+ .lineWidth = 1.0f};
|
|
|
+
|
|
|
+ VkPipelineMultisampleStateCreateInfo multisampleState = {
|
|
|
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
|
|
+ .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
|
|
|
+ .sampleShadingEnable = false,
|
|
|
+ .minSampleShading = 1.0f,
|
|
|
+ .pSampleMask = nullptr,
|
|
|
+ .alphaToCoverageEnable = false,
|
|
|
+ .alphaToOneEnable = false};
|
|
|
+
|
|
|
+ VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {
|
|
|
+ .blendEnable = false,
|
|
|
+ .srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
|
|
|
+ .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
|
|
|
+ .colorBlendOp = VK_BLEND_OP_ADD,
|
|
|
+ .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
|
|
+ .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
|
|
+ .alphaBlendOp = VK_BLEND_OP_ADD,
|
|
|
+ .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
|
|
+ VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT};
|
|
|
+
|
|
|
+ VkPipelineColorBlendStateCreateInfo colorBlendState = {
|
|
|
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
|
|
+ .logicOpEnable = false,
|
|
|
+ .logicOp = VK_LOGIC_OP_COPY,
|
|
|
+ .attachmentCount = 1,
|
|
|
+ .pAttachments = &colorBlendAttachmentState,
|
|
|
+ .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f}};
|
|
|
+
|
|
|
+ VkDynamicState dynamicStates[] = {
|
|
|
+ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
|
|
|
+
|
|
|
+ VkPipelineDynamicStateCreateInfo dynamicState = {
|
|
|
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
|
|
+ .dynamicStateCount = ARRAY_LENGTH(dynamicStates),
|
|
|
+ .pDynamicStates = dynamicStates};
|
|
|
+
|
|
|
+ VkGraphicsPipelineCreateInfo info = {
|
|
|
+ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
|
|
+ .stageCount = 2,
|
|
|
+ .pStages = stages,
|
|
|
+ .pVertexInputState = &vertexInputState,
|
|
|
+ .pInputAssemblyState = &inputAssemblyState,
|
|
|
+ .pTessellationState = nullptr,
|
|
|
+ .pViewportState = &viewportState,
|
|
|
+ .pRasterizationState = &rasterizationState,
|
|
|
+ .pMultisampleState = &multisampleState,
|
|
|
+ .pDepthStencilState = nullptr,
|
|
|
+ .pColorBlendState = &colorBlendState,
|
|
|
+ .pDynamicState = &dynamicState,
|
|
|
+ .layout = pipelineLayout,
|
|
|
+ .renderPass = renderPass,
|
|
|
+ .subpass = 0,
|
|
|
+ .basePipelineHandle = VK_NULL_HANDLE,
|
|
|
+ .basePipelineIndex = -1};
|
|
|
+
|
|
|
+ VK_ASSERT(vkCreateGraphicsPipelines(
|
|
|
+ device, VK_NULL_HANDLE, 1, &info, nullptr, &pipeline));
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+static bool initRenderPass() {
|
|
|
+ VkAttachmentDescription c = {
|
|
|
+ .format = surfaceFormat.format,
|
|
|
+ .samples = VK_SAMPLE_COUNT_1_BIT,
|
|
|
+ .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
|
|
+ .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
|
|
+ .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
|
|
+ .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
|
|
+ .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
|
+ .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR};
|
|
|
+ VkAttachmentReference ca = {
|
|
|
+ .attachment = 0, .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
|
|
|
+ VkSubpassDescription subpass = {
|
|
|
+ .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
|
|
+ .colorAttachmentCount = 1,
|
|
|
+ .pColorAttachments = &ca};
|
|
|
+ VkRenderPassCreateInfo info = {
|
|
|
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
|
|
+ .attachmentCount = 1,
|
|
|
+ .pAttachments = &c,
|
|
|
+ .subpassCount = 1,
|
|
|
+ .pSubpasses = &subpass};
|
|
|
+ VK_ASSERT(vkCreateRenderPass(device, &info, nullptr, &renderPass));
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
bool initVulkan() {
|
|
|
return initVulkanInstance() || initVulkanDebugging() ||
|
|
|
initVulkanSurface(&surface, getWindow()) || initPhysicalDevice() ||
|
|
|
- initDevice() || initSwapchain() || initSwapchainImages();
|
|
|
+ initDevice() || initSwapchain() || initSwapchainImages() ||
|
|
|
+ initShaders() || initVulkanPipelineLayout(&pipelineLayout, device) ||
|
|
|
+ initRenderPass() || initPipeline();
|
|
|
|
|
|
initSemaphore(&vk.renderSemaphore) || initCommandBuffers() ||
|
|
|
- initRenderPass() || initFramebuffers()*/
|
|
|
+ || initFramebuffers()*/
|
|
|
}
|
|
|
|
|
|
void renderVulkan() {
|
|
|
}
|
|
|
|
|
|
void destroyVulkan(void) {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ if(device != VK_NULL_HANDLE) {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ vkDestroyPipeline(device, pipeline, nullptr);
|
|
|
+ vkDestroyRenderPass(device, renderPass, nullptr);
|
|
|
+ }
|
|
|
+ destroyVulkanPipelineLayout(pipelineLayout, device);
|
|
|
+ destroyVulkanShaderModule(vertexShaderModule, device);
|
|
|
+ destroyVulkanShaderModule(fragmentShaderModule, device);
|
|
|
destroyVulkanSwapchainImages(&images, device);
|
|
|
destroyVulkanSwapchain(swapchain, device);
|
|
|
destroyVulkanDevice(device);
|