Starting to unhardcode, pipelines are now created from outside

This commit is contained in:
Blue 2023-10-16 15:47:47 -03:00
parent 2b33897b4a
commit dc3ac2fdf5
Signed by: blue
GPG key ID: 9B203B252A63EE38
16 changed files with 386 additions and 159 deletions

View file

@ -17,8 +17,6 @@ Engine::LogicalDevice::LogicalDevice(
graphicsQueue(),
presentQueue(),
renderPass(),
pipelineLayout(),
graphicsPipeline(),
commandPool(),
commandBuffers(),
imageAvailableSemaphores(),
@ -26,7 +24,6 @@ Engine::LogicalDevice::LogicalDevice(
inFlightFences(),
currentFrame(0),
framebufferResized(false),
hasPipeline(false),
surface(surface),
surfaceFormat(surface->chooseSwapSurfaceFormat(phys->swapChainSupport)),
swapChain(nullptr)
@ -45,10 +42,7 @@ Engine::LogicalDevice::LogicalDevice(
Engine::LogicalDevice::~LogicalDevice() {
clearSwapChain();
if (hasPipeline) {
vkDestroyPipeline(vk, graphicsPipeline, nullptr);
vkDestroyPipelineLayout(vk, pipelineLayout, nullptr);
}
pipelines.clear();
vkDestroyRenderPass(vk, renderPass, nullptr);
@ -64,6 +58,10 @@ Engine::LogicalDevice::~LogicalDevice() {
vkDestroyDevice(vk, nullptr);
}
void Engine::LogicalDevice::addProgram(const Program& program) {
pipelines.emplace_back(program, this);
}
void Engine::LogicalDevice::createSwapChain() {
clearSwapChain();
swapChain = new SwapChain(this);
@ -126,25 +124,6 @@ VkResult Engine::LogicalDevice::queuePresent(const VkSemaphore& signal, uint32_t
return vkQueuePresentKHR(presentQueue, &presentInfo);
}
VkShaderModule Engine::LogicalDevice::createShaderModule(const std::string& path) {
std::vector<char> code = readFile(path);
VkShaderModuleCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = code.size();
createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
VkShaderModule shaderModule;
if (vkCreateShaderModule(vk, &createInfo, nullptr, &shaderModule) != VK_SUCCESS)
throw std::runtime_error("failed to create shader module!");
return shaderModule;
}
void Engine::LogicalDevice::destroyShaderModule(VkShaderModule shaderModule) {
vkDestroyShaderModule(vk, shaderModule, nullptr);
}
void Engine::LogicalDevice::createDevice(
VkPhysicalDevice physicalDevice,
const QueueFamilyIndices& indices,
@ -154,7 +133,6 @@ void Engine::LogicalDevice::createDevice(
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
std::set<uint32_t> uniqueQueueFamilies = {indices.graphicsFamily.value(), indices.presentFamily.value()};
for (uint32_t queueFamily : uniqueQueueFamilies) {
VkDeviceQueueCreateInfo queueCreateInfo{};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@ -248,8 +226,12 @@ void Engine::LogicalDevice::drawFrame() {
resetFence(inFlightFences[currentFrame]);
vkResetCommandBuffer(commandBuffers[currentFrame], /*VkCommandBufferResetFlagBits*/ 0);
recordCommandBuffer(commandBuffers[currentFrame], imageIndex);
if (!pipelines.empty()) {
vkResetCommandBuffer(commandBuffers[currentFrame], /*VkCommandBufferResetFlagBits*/ 0);
recordCommandBuffer(commandBuffers[currentFrame], imageIndex);
} else {
std::cout << "no pipelines attached, skipping command buffer record" << std::endl;
}
if (queueSubmitGraphics(
imageAvailableSemaphores[currentFrame],
@ -413,114 +395,6 @@ void Engine::LogicalDevice::createRenderPass(VkFormat format) {
throw std::runtime_error("failed to create render pass!");
}
void Engine::LogicalDevice::createGraphicsPipeline(const std::string& vertexShaderPath, const std::string& fragmentShaderPath) {
if (hasPipeline)
throw std::runtime_error("an attempt to create graphics pipeline for the second time");
VkShaderModule vertShaderModule = createShaderModule(vertexShaderPath);
VkShaderModule fragShaderModule = createShaderModule(fragmentShaderPath);
VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
vertShaderStageInfo.module = vertShaderModule;
vertShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo fragShaderStageInfo{};
fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
fragShaderStageInfo.module = fragShaderModule;
fragShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputInfo.vertexBindingDescriptionCount = 0;
vertexInputInfo.vertexAttributeDescriptionCount = 0;
VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
inputAssembly.primitiveRestartEnable = VK_FALSE;
VkPipelineViewportStateCreateInfo viewportState{};
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportState.viewportCount = 1;
viewportState.scissorCount = 1;
VkPipelineRasterizationStateCreateInfo rasterizer{};
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterizer.depthClampEnable = VK_FALSE;
rasterizer.rasterizerDiscardEnable = VK_FALSE;
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
rasterizer.lineWidth = 1.0f;
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
rasterizer.depthBiasEnable = VK_FALSE;
VkPipelineMultisampleStateCreateInfo multisampling{};
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisampling.sampleShadingEnable = VK_FALSE;
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
colorBlendAttachment.blendEnable = VK_FALSE;
VkPipelineColorBlendStateCreateInfo colorBlending{};
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
colorBlending.logicOpEnable = VK_FALSE;
colorBlending.logicOp = VK_LOGIC_OP_COPY;
colorBlending.attachmentCount = 1;
colorBlending.pAttachments = &colorBlendAttachment;
colorBlending.blendConstants[0] = 0.0f;
colorBlending.blendConstants[1] = 0.0f;
colorBlending.blendConstants[2] = 0.0f;
colorBlending.blendConstants[3] = 0.0f;
std::vector<VkDynamicState> dynamicStates = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR
};
VkPipelineDynamicStateCreateInfo dynamicState{};
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
dynamicState.pDynamicStates = dynamicStates.data();
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 0;
pipelineLayoutInfo.pushConstantRangeCount = 0;
if (vkCreatePipelineLayout(vk, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS)
throw std::runtime_error("failed to create pipeline layout!");
VkGraphicsPipelineCreateInfo pipelineInfo{};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineInfo.stageCount = 2;
pipelineInfo.pStages = shaderStages;
pipelineInfo.pVertexInputState = &vertexInputInfo;
pipelineInfo.pInputAssemblyState = &inputAssembly;
pipelineInfo.pViewportState = &viewportState;
pipelineInfo.pRasterizationState = &rasterizer;
pipelineInfo.pMultisampleState = &multisampling;
pipelineInfo.pColorBlendState = &colorBlending;
pipelineInfo.pDynamicState = &dynamicState;
pipelineInfo.layout = pipelineLayout;
pipelineInfo.renderPass = renderPass;
pipelineInfo.subpass = 0;
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
if (vkCreateGraphicsPipelines(vk, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &graphicsPipeline) != VK_SUCCESS)
throw std::runtime_error("failed to create graphics pipeline!");
destroyShaderModule(fragShaderModule);
destroyShaderModule(vertShaderModule);
hasPipeline = true;
}
void Engine::LogicalDevice::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
VkExtent2D extent = swapChain->getExtent();
VkCommandBufferBeginInfo beginInfo{};
@ -542,7 +416,8 @@ void Engine::LogicalDevice::recordCommandBuffer(VkCommandBuffer commandBuffer, u
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
for (const Pipeline& pipeline: pipelines) {
pipeline.bind(commandBuffer);
VkViewport viewport{};
viewport.x = 0.0f;
@ -559,6 +434,7 @@ void Engine::LogicalDevice::recordCommandBuffer(VkCommandBuffer commandBuffer, u
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
}
vkCmdEndRenderPass(commandBuffer);
@ -572,3 +448,28 @@ void Engine::LogicalDevice::recreateSwapChain() {
phys->recreateSwapChainSupportDetails(surface);
createSwapChain();
}
VkResult Engine::LogicalDevice::createPipelineLayout(const VkPipelineLayoutCreateInfo& info, VkPipelineLayout& out) {
return vkCreatePipelineLayout(vk, &info, nullptr, &out);
}
VkResult Engine::LogicalDevice::createPipeline(VkGraphicsPipelineCreateInfo& info, VkPipeline& out) {
info.renderPass = renderPass;
return vkCreateGraphicsPipelines(vk, VK_NULL_HANDLE, 1, &info, nullptr, &out);
}
VkResult Engine::LogicalDevice::createShaderModule(const VkShaderModuleCreateInfo& info, VkShaderModule& out) {
return vkCreateShaderModule(vk, &info, nullptr, &out);
}
void Engine::LogicalDevice::destroyPipeline(VkPipeline& pipline) {
vkDestroyPipeline(vk, pipline, nullptr);
}
void Engine::LogicalDevice::destroyPipelineLayout(VkPipelineLayout& layout) {
vkDestroyPipelineLayout(vk, layout, nullptr);
}
void Engine::LogicalDevice::destroyShaderModule(VkShaderModule& module) {
vkDestroyShaderModule(vk, module, nullptr);
}