fixes
[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         for(size_t i=0; i<res_layouts.size(); i++) {
50                 vkDestroyDescriptorSetLayout(vk_device, res_layouts[i], 0);
51         }
52         vkDestroyPipelineLayout(vk_device, layout, 0);
53 }
54
55 VkPipeline VkuPipelineGenerator::generate(VkuDynState dyn_flags)
56 {
57         VkPipelineDynamicStateCreateInfo dyni;
58         memset(&dyni, 0, sizeof dyni);
59         dyni.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
60
61         std::vector<VkDynamicState> dyn_states;
62         if(dyn_flags & VKU_DS_VIEWPORT) {
63                 dyn_states.push_back(VK_DYNAMIC_STATE_VIEWPORT);
64         }
65         if(dyn_flags & VKU_DS_SCISSOR) {
66                 dyn_states.push_back(VK_DYNAMIC_STATE_SCISSOR);
67         }
68         if(dyn_flags & VKU_DS_BLEND) {
69                 dyn_states.push_back(VK_DYNAMIC_STATE_BLEND_CONSTANTS);
70         }
71
72         dyni.dynamicStateCount = dyn_states.size();
73         dyni.pDynamicStates = dyn_states.data();
74
75         VkPipelineVertexInputStateCreateInfo verti;
76         memset(&verti, 0, sizeof verti);
77         verti.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
78         verti.vertexBindingDescriptionCount = bind_descriptions.size();
79         verti.pVertexBindingDescriptions = bind_descriptions.data();
80         verti.vertexAttributeDescriptionCount = attr_descriptions.size();
81         verti.pVertexAttributeDescriptions = attr_descriptions.data();
82
83         VkPipelineLayoutCreateInfo linf;
84         memset(&linf, 0, sizeof linf);
85         linf.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
86         linf.setLayoutCount = res_layouts.size();
87         linf.pSetLayouts = res_layouts.data();
88         //TODO find max num dsets vkGetPhysicalDeviceProperties
89         //maxBoundDescriptorSets of VkPhysicalDeviceLimits
90         //linf.pushConstantRangeCount = push_const_ranges.size();
91         //linf.pPushConstantRanges = push_const_ranges.data();
92         //maxPushConstantsSize from VkPhysicalDeviceLimits
93
94         if(vkCreatePipelineLayout(vk_device, &linf, 0, &layout) != VK_SUCCESS) {
95                 fprintf(stderr, "Failed to create pipeline layout.\n");
96                 return 0;
97         }
98
99         VkGraphicsPipelineCreateInfo gpinf;
100         memset(&gpinf, 0, sizeof gpinf);
101         gpinf.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
102         gpinf.stageCount = 2;
103         gpinf.pStages = sdri;
104         gpinf.pVertexInputState = &verti;
105         gpinf.pInputAssemblyState = &asmi;
106         gpinf.pViewportState = &viewpi;
107         gpinf.pMultisampleState = &multi;
108         gpinf.pDepthStencilState = &depthi;
109         gpinf.pColorBlendState = &cblendi;
110         gpinf.pDynamicState = &dyni;
111         gpinf.layout = layout;
112         gpinf.renderPass = vk_renderpass;
113
114         VkPipelineCacheCreateInfo pcinf;
115         memset(&pcinf, 0, sizeof pcinf);
116         pcinf.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
117
118         VkPipelineCache pcache;
119         if(vkCreatePipelineCache(vk_device, &pcinf, 0, &pcache) != VK_SUCCESS) {
120                 fprintf(stderr, "Failed to create cache for pipeline.\n");
121                 return 0;
122         }
123
124         VkPipeline gpipeline;
125         if(vkCreateGraphicsPipelines(vk_device, pcache, 1, &gpinf, 0, &gpipeline) !=
126                 VK_SUCCESS) {
127                 fprintf(stderr, "Failed to create graphics pipeline.\n");
128                 return 0;
129         }
130
131         return gpipeline;
132 }
133
134 void VkuPipelineGenerator::set_shader_modules(VkShaderModule vs,
135         VkShaderModule fs)
136 {
137         sdri[0].module = vs;
138         sdri[1].module = fs;
139 }
140
141 void VkuPipelineGenerator::set_attribute(uint32_t binding, uint32_t stride,
142         uint32_t location, VkFormat format)
143 {
144         VkVertexInputBindingDescription bdsc;
145         bdsc.binding = binding;
146         bdsc.stride = stride;
147         bdsc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
148
149         bind_descriptions.push_back(bdsc);
150
151         VkVertexInputAttributeDescription adsc;
152         memset(&adsc, 0, sizeof adsc);
153         adsc.location = location;
154         adsc.binding = binding;
155         adsc.format = format;
156 }
157
158 void VkuPipelineGenerator::set_resources_layout(VkDescriptorSetLayout layout)
159 {
160         res_layouts.push_back(layout);
161 }