+#include <stdio.h>
+#include <string.h>
+
+#include "vkutil.h"
+#include "vkutil-pipeline.h"
+
+VkuPipelineGenerator::VkuPipelineGenerator()
+{
+ memset(sdri, 0, sizeof sdri);
+ sdri[0].sType = sdri[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+ sdri[0].pName = sdri[1].pName = "main";
+ sdri[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
+ sdri[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
+
+ memset(&verti, 0, sizeof verti);
+ verti.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+
+ memset(&asmi, 0, sizeof asmi);
+ asmi.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+ asmi.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+
+ VkViewport viewport = {0, 0, 0, 0};
+ VkRect2D scissor = {0, 0};
+ memset(&viewpi, 0, sizeof viewpi);
+ viewpi.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+ viewpi.viewportCount = 1;
+ viewpi.pViewports = &viewport;
+ viewpi.scissorCount = 1;
+ viewpi.pScissors = &scissor;
+
+ memset(&rasti, 0, sizeof rasti);
+ rasti.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+ rasti.polygonMode = VK_POLYGON_MODE_FILL;
+ rasti.cullMode = VK_CULL_MODE_BACK_BIT;
+ rasti.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
+
+ memset(&multi, 0, sizeof multi);
+ multi.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+
+ memset(&depthi, 0, sizeof depthi);
+ depthi.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+ depthi.depthTestEnable = VK_TRUE;
+ depthi.depthWriteEnable = VK_TRUE;
+ depthi.depthCompareOp = VK_COMPARE_OP_LESS;
+
+ memset(&cblendi, 0, sizeof cblendi);
+ cblendi.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+}
+
+VkuPipelineGenerator::~VkuPipelineGenerator()
+{
+}
+
+VkPipeline VkuPipelineGenerator::generate(VkuDynState dyn_flags) const
+{
+ VkPipelineDynamicStateCreateInfo dyni;
+ memset(&dyni, 0, sizeof dyni);
+ dyni.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
+
+ std::vector<VkDynamicState> dyn_states;
+ if(dyn_flags & VKU_DS_VIEWPORT) {
+ dyn_states.push_back(VK_DYNAMIC_STATE_VIEWPORT);
+ }
+ if(dyn_flags & VKU_DS_SCISSOR) {
+ dyn_states.push_back(VK_DYNAMIC_STATE_SCISSOR);
+ }
+ if(dyn_flags & VKU_DS_BLEND) {
+ dyn_states.push_back(VK_DYNAMIC_STATE_BLEND_CONSTANTS);
+ }
+
+ dyni.dynamicStateCount = dyn_states.size();
+ dyni.pDynamicStates = dyn_states.data();
+
+ VkGraphicsPipelineCreateInfo gpinf;
+ memset(&gpinf, 0, sizeof gpinf);
+ gpinf.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+ gpinf.stageCount = 2;
+ gpinf.pStages = sdri;
+ gpinf.pVertexInputState = &verti;
+ gpinf.pInputAssemblyState = &asmi;
+ gpinf.pViewportState = &viewpi;
+ gpinf.pMultisampleState = &multi;
+ gpinf.pDepthStencilState = &depthi;
+ gpinf.pColorBlendState = &cblendi;
+ gpinf.pDynamicState = &dyni;
+ gpinf.layout = layout;
+ gpinf.renderPass = vk_renderpass;
+
+ VkPipelineCacheCreateInfo pcinf;
+ memset(&pcinf, 0, sizeof pcinf);
+ pcinf.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
+
+ VkPipelineCache pcache;
+ if(vkCreatePipelineCache(vk_device, &pcinf, 0, &pcache) != VK_SUCCESS) {
+ fprintf(stderr, "Failed to create cache for pipeline.\n");
+ return 0;
+ }
+
+ VkPipeline gpipeline;
+ if(vkCreateGraphicsPipelines(vk_device, pcache, 1, &gpinf, 0, &gpipeline) !=
+ VK_SUCCESS) {
+ fprintf(stderr, "Failed to create graphics pipeline.\n");
+ return 0;
+ }
+
+ return gpipeline;
+}
+
+void VkuPipelineGenerator::set_shader_modules(VkShaderModule vs,
+ VkShaderModule fs)
+{
+ sdri[0].module = vs;
+ sdri[1].module = fs;
+}
+
+void VkuPipelineGenerator::set_vertex_attributes()
+{
+}