vkQuake2 doxygen  1.0 dev
vk_pipeline.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 2018-2019 Krzysztof Kondrak
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 */
20 
21 #include "vk_local.h"
22 
23 qvkshader_t QVk_CreateShader(const uint32_t *shaderSrc, size_t shaderCodeSize, VkShaderStageFlagBits shaderStage)
24 {
25  qvkshader_t shader;
26  VkShaderModuleCreateInfo smCreateInfo = {
27  .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
28  .pNext = NULL,
29  .flags = 0,
30  .codeSize = shaderCodeSize,
31  .pCode = shaderSrc
32  };
33 
34  VK_VERIFY(vkCreateShaderModule(vk_device.logical, &smCreateInfo, NULL, &shader.module));
35 
36  VkPipelineShaderStageCreateInfo vssCreateInfo = {
37  .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
38  .pNext = NULL,
39  .flags = 0,
40  .stage = shaderStage,
41  .module = shader.module,
42  .pName = "main",
43  .pSpecializationInfo = NULL
44  };
45 
46  shader.createInfo = vssCreateInfo;
47 
48  return shader;
49 }
50 
51 void QVk_CreatePipeline(const VkDescriptorSetLayout *descriptorLayout, const uint32_t descLayoutCount, const VkPipelineVertexInputStateCreateInfo *vertexInputInfo,
52  qvkpipeline_t *pipeline, const qvkrenderpass_t *renderpass, const qvkshader_t *shaders, uint32_t shaderCount, VkPushConstantRange *pcRange)
53 {
54  VkPipelineShaderStageCreateInfo *ssCreateInfos = (VkPipelineShaderStageCreateInfo *)malloc(shaderCount * sizeof(VkPipelineShaderStageCreateInfo));
55  for (int i = 0; i < shaderCount; i++)
56  {
57  ssCreateInfos[i] = shaders[i].createInfo;
58  }
59 
60  VkPipelineInputAssemblyStateCreateInfo iaCreateInfo = {
61  .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
62  .pNext = NULL,
63  .flags = 0,
64  .topology = pipeline->topology,
65  .primitiveRestartEnable = VK_FALSE
66  };
67 
68  VkViewport viewport = {
69  .x = 0.f,
70  .y = 0.f,
71  .width = (float)vid.width,
72  .height = (float)vid.height,
73  .minDepth = 0.f,
74  .maxDepth = 1.f,
75  };
76 
77  VkRect2D scissor = {
78  .offset.x = 0,
79  .offset.y = 0,
80  .extent = vk_swapchain.extent
81  };
82 
83  VkPipelineViewportStateCreateInfo vpCreateInfo = {
84  .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
85  .pNext = NULL,
86  .flags = 0,
87  .viewportCount = 1,
88  .pViewports = &viewport,
89  .scissorCount = 1,
90  .pScissors = &scissor
91  };
92 
93  VkPipelineRasterizationStateCreateInfo rCreateInfo = {
94  .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
95  .pNext = NULL,
96  .flags = 0,
97  .depthClampEnable = VK_FALSE,
98  .rasterizerDiscardEnable = VK_FALSE,
99  .polygonMode = pipeline->mode,
100  .cullMode = pipeline->cullMode,
101  .frontFace = VK_FRONT_FACE_CLOCKWISE,
102  .depthBiasEnable = VK_FALSE,
103  .depthBiasConstantFactor = 0.f,
104  .depthBiasClamp = 0.f,
105  .depthBiasSlopeFactor = 0.f,
106  .lineWidth = 1.f
107  };
108 
109  VkPipelineMultisampleStateCreateInfo msCreateInfo = {
110  .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
111  .pNext = NULL,
112  .flags = 0,
113  .rasterizationSamples = renderpass->sampleCount,
114  .sampleShadingEnable = (vk_sampleshading->value > 0 && vk_device.features.sampleRateShading) ? VK_TRUE : VK_FALSE,
115  .minSampleShading = (vk_sampleshading->value > 0 && vk_device.features.sampleRateShading) ? 1.f : 0.f,
116  .pSampleMask = NULL,
117  .alphaToCoverageEnable = VK_FALSE,
118  .alphaToOneEnable = VK_FALSE
119  };
120 
121  VkPipelineDepthStencilStateCreateInfo dCreateInfo = {
122  .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
123  .pNext = NULL,
124  .flags = 0,
125  .depthTestEnable = pipeline->depthTestEnable,
126  .depthWriteEnable = pipeline->depthTestEnable == VK_TRUE ? pipeline->depthWriteEnable : VK_FALSE, // there should be NO depth writes if depthTestEnable is false but Intel seems to not follow the specs fully...
127  .depthCompareOp = VK_COMPARE_OP_LESS,
128  .depthBoundsTestEnable = VK_FALSE,
129  .stencilTestEnable = VK_FALSE,
130  .front = { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0, 0, 0 },
131  .back = { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0, 0, 0 },
132  .minDepthBounds = 0.f,
133  .maxDepthBounds = 1.f
134  };
135 
136  VkPipelineColorBlendStateCreateInfo cbsCreateInfo = {
137  .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
138  .pNext = NULL,
139  .flags = 0,
140  .logicOpEnable = VK_FALSE,
141  .logicOp = VK_LOGIC_OP_COPY,
142  .attachmentCount = 1,
143  .pAttachments = &pipeline->blendOpts,
144  .blendConstants[0] = 0.f,
145  .blendConstants[1] = 0.f,
146  .blendConstants[2] = 0.f,
147  .blendConstants[3] = 0.f
148  };
149 
150  VkDynamicState dynamicStates[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
151  VkPipelineDynamicStateCreateInfo dsCreateInfo = {
152  .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
153  .pNext = NULL,
154  .flags = 0,
155  .dynamicStateCount = 2,
156  .pDynamicStates = dynamicStates
157  };
158 
159  VkPipelineLayoutCreateInfo plCreateInfo = {
160  .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
161  .pNext = NULL,
162  .flags = 0,
163  .setLayoutCount = descLayoutCount,
164  .pSetLayouts = descriptorLayout,
165  .pushConstantRangeCount = pcRange ? 1 : 0, // for simplicity assume only one push constant range is passed, so it's not the most flexible approach
166  .pPushConstantRanges = pcRange
167  };
168 
169  VK_VERIFY(vkCreatePipelineLayout(vk_device.logical, &plCreateInfo, NULL, &pipeline->layout));
170 
171  // create THE pipeline
172  VkGraphicsPipelineCreateInfo pCreateInfo = {
173  .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
174  .pNext = NULL,
175  .flags = pipeline->flags,
176  .stageCount = shaderCount,
177  .pStages = ssCreateInfos,
178  .pVertexInputState = vertexInputInfo,
179  .pInputAssemblyState = &iaCreateInfo,
180  .pTessellationState = NULL,
181  .pViewportState = &vpCreateInfo,
182  .pRasterizationState = &rCreateInfo,
183  .pMultisampleState = &msCreateInfo,
184  .pDepthStencilState = &dCreateInfo,
185  .pColorBlendState = &cbsCreateInfo,
186  .pDynamicState = &dsCreateInfo,
187  .layout = pipeline->layout,
188  .renderPass = renderpass->rp,
189  .subpass = 0,
190  .basePipelineHandle = VK_NULL_HANDLE,
191  .basePipelineIndex = -1
192  };
193 
194  VK_VERIFY(vkCreateGraphicsPipelines(vk_device.logical, VK_NULL_HANDLE, 1, &pCreateInfo, NULL, &pipeline->pl));
195  free(ssCreateInfos);
196 }
197 
199 {
200  if (pipeline->layout != VK_NULL_HANDLE)
201  vkDestroyPipelineLayout(vk_device.logical, pipeline->layout, NULL);
202  if (pipeline->pl != VK_NULL_HANDLE)
203  vkDestroyPipeline(vk_device.logical, pipeline->pl, NULL);
204 
205  pipeline->layout = VK_NULL_HANDLE;
206  pipeline->pl = VK_NULL_HANDLE;
207 }
qvkshader_t
Definition: qvk.h:166
qvkpipeline_t::mode
VkPolygonMode mode
Definition: qvk.h:157
qvkdevice_t::logical
VkDevice logical
Definition: qvk.h:40
qvkpipeline_t::flags
VkPipelineCreateFlags flags
Definition: qvk.h:156
vk_local.h
qvkrenderpass_t::rp
VkRenderPass rp
Definition: qvk.h:118
qvkshader_t::createInfo
VkPipelineShaderStageCreateInfo createInfo
Definition: qvk.h:168
qvkpipeline_t
Definition: qvk.h:152
i
int i
Definition: q_shared.c:305
qvkrenderpass_t
Definition: qvk.h:116
qvkpipeline_t::pl
VkPipeline pl
Definition: qvk.h:155
qvkshader_t::module
VkShaderModule module
Definition: qvk.h:169
vk_device
qvkdevice_t vk_device
Definition: vk_common.c:51
qvkpipeline_t::topology
VkPrimitiveTopology topology
Definition: qvk.h:159
QVk_CreateShader
qvkshader_t QVk_CreateShader(const uint32_t *shaderSrc, size_t shaderCodeSize, VkShaderStageFlagBits shaderStage)
Definition: vk_pipeline.c:23
qvkswapchain_t::extent
VkExtent2D extent
Definition: qvk.h:57
viddef_t::width
unsigned width
Definition: vid.h:29
qvkpipeline_t::depthTestEnable
VkBool32 depthTestEnable
Definition: qvk.h:161
qvkpipeline_t::cullMode
VkCullModeFlags cullMode
Definition: qvk.h:158
qvkpipeline_t::blendOpts
VkPipelineColorBlendAttachmentState blendOpts
Definition: qvk.h:160
vk_swapchain
qvkswapchain_t vk_swapchain
Definition: vk_common.c:63
viddef_t::height
unsigned height
Definition: vid.h:29
cvar_s::value
float value
Definition: q_shared.h:331
qvkdevice_t::features
VkPhysicalDeviceFeatures features
Definition: qvk.h:42
NULL
#define NULL
Definition: q_shared.h:67
qvkpipeline_t::depthWriteEnable
VkBool32 depthWriteEnable
Definition: qvk.h:162
qvkpipeline_t::layout
VkPipelineLayout layout
Definition: qvk.h:154
VK_VERIFY
#define VK_VERIFY(x)
Definition: vk_local.h:59
QVk_DestroyPipeline
void QVk_DestroyPipeline(qvkpipeline_t *pipeline)
Definition: vk_pipeline.c:198
vk_sampleshading
static cvar_t * vk_sampleshading
Definition: vid_menu.c:45
qvkrenderpass_t::sampleCount
VkSampleCountFlagBits sampleCount
Definition: qvk.h:120
QVk_CreatePipeline
void QVk_CreatePipeline(const VkDescriptorSetLayout *descriptorLayout, const uint32_t descLayoutCount, const VkPipelineVertexInputStateCreateInfo *vertexInputInfo, qvkpipeline_t *pipeline, const qvkrenderpass_t *renderpass, const qvkshader_t *shaders, uint32_t shaderCount, VkPushConstantRange *pcRange)
Definition: vk_pipeline.c:51
vid
viddef_t vid
Definition: r_main.c:24