backup - missing some
[demo] / src / vulkan / vkutil-pipeline.cc
1 #include <stdio.h>
2 #include <string.h>
3
4 #include "vkutil.h"
5 #include "vkutil-pipeline.h"
6
7 VkuPipelineGenerator::VkuPipelineGenerator()
8 {
9         memset(sdri, 0, sizeof sdri);
10         sdri[0].sType = sdri[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
11         sdri[0].pName = sdri[1].pName = "main";
12         sdri[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
13         sdri[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
14
15         memset(&asmi, 0, sizeof asmi);
16         asmi.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
17         asmi.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
18
19         VkViewport viewport = {0, 0, 0, 0};
20         VkRect2D scissor = {0, 0};
21         memset(&viewpi, 0, sizeof viewpi);
22         viewpi.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
23         viewpi.viewportCount = 1;
24         viewpi.pViewports = &viewport;
25         viewpi.scissorCount = 1;
26         viewpi.pScissors = &scissor;
27
28         memset(&rasti, 0, sizeof rasti);
29         rasti.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
30         rasti.polygonMode = VK_POLYGON_MODE_FILL;
31         rasti.cullMode = VK_CULL_MODE_BACK_BIT;
32         rasti.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
33
34         memset(&multi, 0, sizeof multi);
35         multi.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
36
37         memset(&depthi, 0, sizeof depthi);
38         depthi.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
39         depthi.depthTestEnable = VK_TRUE;
40         depthi.depthWriteEnable = VK_TRUE;
41         depthi.depthCompareOp = VK_COMPARE_OP_LESS;
42
43         memset(&cblendi, 0, sizeof cblendi);
44         cblendi.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
45 }
46
47 VkuPipelineGenerator::~VkuPipelineGenerator()
48 {
49 }
50
51 VkPipeline VkuPipelineGenerator::generate(VkuDynState dyn_flags) const
52 {
53         VkPipelineDynamicStateCreateInfo dyni;
54         memset(&dyni, 0, sizeof dyni);
55         dyni.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
56
57         std::vector<VkDynamicState> dyn_states;
58         if(dyn_flags & VKU_DS_VIEWPORT) {
59                 dyn_states.push_back(VK_DYNAMIC_STATE_VIEWPORT);
60         }
61         if(dyn_flags & VKU_DS_SCISSOR) {
62                 dyn_states.push_back(VK_DYNAMIC_STATE_SCISSOR);
63         }
64         if(dyn_flags & VKU_DS_BLEND) {
65                 dyn_states.push_back(VK_DYNAMIC_STATE_BLEND_CONSTANTS);
66         }
67
68         dyni.dynamicStateCount = dyn_states.size();
69         dyni.pDynamicStates = dyn_states.data();
70
71         VkPipelineVertexInputStateCreateInfo verti;
72         memset(&verti, 0, sizeof verti);
73         verti.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
74         verti.vertexBindingDescriptionCount = bind_descriptions.size();
75         verti.pVertexBindingDescriptions = bind_descriptions.data();
76         verti.vertexAttributeDescriptionCount = attr_descriptions.size();
77         verti.pVertexAttributeDescriptions = attr_descriptions.data();
78
79         VkPipelineLayoutCreateInfo linf;
80         memset(&linf, 0, sizeof linf);
81         linf.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
82         linf.setLayoutCount = res_layouts.size();
83         linf.pSetLayouts = res_layouts.data();
84         //TODO find max num dsets vkGetPhysicalDeviceProperties
85         //maxBoundDescriptorSets of VkPhysicalDeviceLimits
86         //linf.pushConstantRangeCount = push_const_ranges.size();
87         //linf.pPushConstantRanges = push_const_ranges.data();
88         //maxPushConstantsSize from VkPhysicalDeviceLimits
89
90         VkPipelineLayout layout;
91         if(vkCreatePipelineLayout(vk_device, &linf, 0, &layout) != VK_SUCCESS) {
92                 fprintf(stderr, "Failed to create pipeline layout.\n");
93                 return 0;
94         }
95
96         VkGraphicsPipelineCreateInfo gpinf;
97         memset(&gpinf, 0, sizeof gpinf);
98         gpinf.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
99         gpinf.stageCount = 2;
100         gpinf.pStages = sdri;
101         gpinf.pVertexInputState = &verti;
102         gpinf.pInputAssemblyState = &asmi;
103         gpinf.pViewportState = &viewpi;
104         gpinf.pMultisampleState = &multi;
105         gpinf.pDepthStencilState = &depthi;
106         gpinf.pColorBlendState = &cblendi;
107         gpinf.pDynamicState = &dyni;
108         gpinf.layout = layout;
109         gpinf.renderPass = vk_renderpass;
110
111         VkPipelineCacheCreateInfo pcinf;
112         memset(&pcinf, 0, sizeof pcinf);
113         pcinf.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
114
115         VkPipelineCache pcache;
116         if(vkCreatePipelineCache(vk_device, &pcinf, 0, &pcache) != VK_SUCCESS) {
117                 fprintf(stderr, "Failed to create cache for pipeline.\n");
118                 return 0;
119         }
120
121         VkPipeline gpipeline;
122         if(vkCreateGraphicsPipelines(vk_device, pcache, 1, &gpinf, 0, &gpipeline) !=
123                 VK_SUCCESS) {
124                 fprintf(stderr, "Failed to create graphics pipeline.\n");
125                 return 0;
126         }
127
128         return gpipeline;
129 }
130
131 void VkuPipelineGenerator::set_shader_modules(VkShaderModule vs,
132         VkShaderModule fs)
133 {
134         sdri[0].module = vs;
135         sdri[1].module = fs;
136 }
137
138 void VkuPipelineGenerator::set_attribute(uint32_t binding, uint32_t stride,
139         uint32_t location, VkFormat format)
140 {
141         VkVertexInputBindingDescription bdsc;
142         bdsc.binding = binding;
143         bdsc.stride = stride;
144         bdsc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
145
146         bind_descriptions.push_back(bdsc);
147
148         VkVertexInputAttributeDescription adsc;
149         memset(&adsc, 0, sizeof adsc);
150         adsc.location = location;
151         adsc.binding = binding;
152         adsc.format = format;
153 }