Starting to unhardcode, pipelines are now created from outside
This commit is contained in:
parent
2b33897b4a
commit
dc3ac2fdf5
16 changed files with 386 additions and 159 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue