16 VkAttachmentDescription colorAttachment{};
19 colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
20 colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
21 colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
22 colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
23 colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
24 colorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
26 VkAttachmentDescription depthAttachment{};
29 depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
30 depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
31 depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
32 depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
33 depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
34 depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
36 VkAttachmentDescription colorAttachmentResolve{};
38 colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT;
39 colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
40 colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
41 colorAttachmentResolve.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
42 colorAttachmentResolve.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
43 colorAttachmentResolve.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
44 colorAttachmentResolve.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
46 VkAttachmentReference colorAttachmentRef{};
47 colorAttachmentRef.attachment = 0;
48 colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
50 VkAttachmentReference depthAttachmentRef{};
51 depthAttachmentRef.attachment = 1;
52 depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
54 VkAttachmentReference colorAttachmentResolveRef{};
55 colorAttachmentResolveRef.attachment = 2;
56 colorAttachmentResolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
58 VkSubpassDescription subpass{};
59 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
60 subpass.colorAttachmentCount = 1;
61 subpass.pColorAttachments = &colorAttachmentRef;
62 subpass.pDepthStencilAttachment = &depthAttachmentRef;
63 subpass.pResolveAttachments = &colorAttachmentResolveRef;
65 VkSubpassDependency dependency{};
66 dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
67 dependency.dstSubpass = 0;
68 dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
69 dependency.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
70 dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
71 dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
73 std::array<VkAttachmentDescription, 3> attachments = {colorAttachment, depthAttachment, colorAttachmentResolve };
74 VkRenderPassCreateInfo renderPassInfo{};
75 renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
76 renderPassInfo.attachmentCount =
static_cast<uint32_t
>(attachments.size());
77 renderPassInfo.pAttachments = attachments.data();
78 renderPassInfo.subpassCount = 1;
79 renderPassInfo.pSubpasses = &subpass;
80 renderPassInfo.dependencyCount = 1;
81 renderPassInfo.pDependencies = &dependency;
83 if (vkCreateRenderPass(
device, &renderPassInfo,
nullptr, &
renderPass) != VK_SUCCESS) {
84 throw std::runtime_error(
"Failed to create render pass !");
104 auto vertShaderCode =
readFile(
"../shaders/vert.spv");
105 auto fragShaderCode =
readFile(
"../shaders/frag.spv");
107 auto vertShaderCode =
readFile(
"shaders/vert.spv");
108 auto fragShaderCode =
readFile(
"shaders/frag.spv");
114 VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
115 vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
116 vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
117 vertShaderStageInfo.module = vertShaderModule;
118 vertShaderStageInfo.pName =
"main";
120 VkPipelineShaderStageCreateInfo fragShaderStageInfo{};
121 fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
122 fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
123 fragShaderStageInfo.module = fragShaderModule;
124 fragShaderStageInfo.pName =
"main";
126 VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
128 VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
129 vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
134 VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
135 inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
137 inputAssembly.primitiveRestartEnable = VK_FALSE;
139 VkPipelineViewportStateCreateInfo viewportState{};
140 viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
141 viewportState.viewportCount = 1;
142 viewportState.scissorCount = 1;
144 vertexInputInfo.vertexBindingDescriptionCount = 1;
145 vertexInputInfo.vertexAttributeDescriptionCount =
static_cast<uint32_t
>(attributeDescriptions.size());
146 vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
147 vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
149 VkPipelineRasterizationStateCreateInfo rasterizer{};
150 rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
151 rasterizer.depthClampEnable = VK_FALSE;
152 rasterizer.rasterizerDiscardEnable = VK_FALSE;
153 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
154 rasterizer.lineWidth = 1.0f;
155 rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
156 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
157 rasterizer.depthBiasEnable = VK_FALSE;
159 VkPipelineMultisampleStateCreateInfo multisampling{};
160 multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
161 multisampling.sampleShadingEnable = VK_FALSE;
162 multisampling.minSampleShading = 0.2f;
165 VkPipelineDepthStencilStateCreateInfo depthStencil{};
166 depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
167 depthStencil.depthTestEnable = VK_TRUE;
168 depthStencil.depthWriteEnable = VK_TRUE;
169 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
170 depthStencil.depthBoundsTestEnable = VK_FALSE;
171 depthStencil.stencilTestEnable = VK_FALSE;
173 VkPipelineColorBlendAttachmentState colorBlendAttachment{};
174 colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
175 colorBlendAttachment.blendEnable = VK_TRUE;
176 colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
177 colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
178 colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
179 colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
180 colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
181 colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
183 VkPipelineColorBlendStateCreateInfo colorBlending{};
184 colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
185 colorBlending.logicOpEnable = VK_FALSE;
186 colorBlending.logicOp = VK_LOGIC_OP_COPY;
187 colorBlending.attachmentCount = 1;
188 colorBlending.pAttachments = &colorBlendAttachment;
189 colorBlending.blendConstants[0] = 0.0f;
190 colorBlending.blendConstants[1] = 0.0f;
191 colorBlending.blendConstants[2] = 0.0f;
192 colorBlending.blendConstants[3] = 0.0f;
194 std::vector<VkDynamicState> dynamicStates = {
195 VK_DYNAMIC_STATE_VIEWPORT,
196 VK_DYNAMIC_STATE_SCISSOR
198 VkPipelineDynamicStateCreateInfo dynamicState{};
199 dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
200 dynamicState.dynamicStateCount =
static_cast<uint32_t
>(dynamicStates.size());
201 dynamicState.pDynamicStates = dynamicStates.data();
203 VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
204 pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
205 pipelineLayoutInfo.setLayoutCount = 1;
208 if (vkCreatePipelineLayout(
device, &pipelineLayoutInfo,
nullptr, &
pipelineLayout) != VK_SUCCESS) {
209 throw std::runtime_error(
"Failed to create pipeline layout !");
212 VkGraphicsPipelineCreateInfo pipelineInfo{};
213 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
214 pipelineInfo.stageCount = 2;
215 pipelineInfo.pStages = shaderStages;
216 pipelineInfo.pVertexInputState = &vertexInputInfo;
217 pipelineInfo.pInputAssemblyState = &inputAssembly;
218 pipelineInfo.pViewportState = &viewportState;
219 pipelineInfo.pRasterizationState = &rasterizer;
220 pipelineInfo.pMultisampleState = &multisampling;
221 pipelineInfo.pDepthStencilState = &depthStencil;
222 pipelineInfo.pColorBlendState = &colorBlending;
223 pipelineInfo.pDynamicState = &dynamicState;
226 pipelineInfo.subpass = 0;
227 pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
229 if (vkCreateGraphicsPipelines(
device, VK_NULL_HANDLE, 1, &pipelineInfo,
nullptr, &
graphicsPipeline) != VK_SUCCESS) {
230 throw std::runtime_error(
"Failed to create graphics pipeline !");
233 vkDestroyShaderModule(
device, fragShaderModule,
nullptr);
234 vkDestroyShaderModule(
device, vertShaderModule,
nullptr);
238 VkDescriptorSetLayoutBinding uboLayoutBinding{};
239 uboLayoutBinding.binding = 0;
240 uboLayoutBinding.descriptorCount = 1;
241 uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
242 uboLayoutBinding.pImmutableSamplers =
nullptr;
243 uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
245 VkDescriptorSetLayoutBinding samplerLayoutBinding{};
246 samplerLayoutBinding.binding = 1;
247 samplerLayoutBinding.descriptorCount = 1;
248 samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
249 samplerLayoutBinding.pImmutableSamplers =
nullptr;
250 samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
252 std::array<VkDescriptorSetLayoutBinding, 2> bindings = {uboLayoutBinding, samplerLayoutBinding};
253 VkDescriptorSetLayoutCreateInfo layoutInfo{};
254 layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
255 layoutInfo.bindingCount =
static_cast<uint32_t
>(bindings.size());
256 layoutInfo.pBindings = bindings.data();
259 throw std::runtime_error(
"Failed to create descriptor set layout !");
323 VkDescriptorSetAllocateInfo allocInfo{};
324 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
327 allocInfo.pSetLayouts = layouts.data();
331 throw std::runtime_error(
"Failed to allocate descriptor sets !");
335 VkDescriptorBufferInfo bufferInfo{};
337 bufferInfo.offset = 0;
340 VkDescriptorImageInfo imageInfo{};
341 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
345 std::array<VkWriteDescriptorSet, 2> descriptorWrites{};
347 descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
349 descriptorWrites[0].dstBinding = 0;
350 descriptorWrites[0].dstArrayElement = 0;
351 descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
352 descriptorWrites[0].descriptorCount = 1;
353 descriptorWrites[0].pBufferInfo = &bufferInfo;
355 descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
357 descriptorWrites[1].dstBinding = 1;
358 descriptorWrites[1].dstArrayElement = 0;
359 descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
360 descriptorWrites[1].descriptorCount = 1;
361 descriptorWrites[1].pImageInfo = &imageInfo;
363 vkUpdateDescriptorSets(
device,
static_cast<uint32_t
>(descriptorWrites.size()), descriptorWrites.data(), 0,
nullptr);