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
11
engine/program/CMakeLists.txt
Normal file
11
engine/program/CMakeLists.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
set(SOURCES
|
||||
pipeline.cpp
|
||||
program.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
pipeline.h
|
||||
program.h
|
||||
)
|
||||
|
||||
target_sources(engine PRIVATE ${SOURCES})
|
149
engine/program/pipeline.cpp
Normal file
149
engine/program/pipeline.cpp
Normal file
|
@ -0,0 +1,149 @@
|
|||
#include "pipeline.h"
|
||||
#include "logicaldevice.h"
|
||||
|
||||
Engine::Pipeline::Pipeline(const Program& program, LogicalDevice* device):
|
||||
device(device),
|
||||
program(program),
|
||||
vk(),
|
||||
layout()
|
||||
{
|
||||
createLayout();
|
||||
createPipeline();
|
||||
}
|
||||
|
||||
Engine::Pipeline::Pipeline(const Pipeline& other):
|
||||
device(other.device),
|
||||
program(other.program),
|
||||
vk(),
|
||||
layout()
|
||||
{
|
||||
createLayout();
|
||||
createPipeline();
|
||||
}
|
||||
|
||||
Engine::Pipeline::~Pipeline() {
|
||||
device->destroyPipeline(vk);
|
||||
device->destroyPipelineLayout(layout);
|
||||
}
|
||||
|
||||
void Engine::Pipeline::createLayout() {
|
||||
VkPipelineLayoutCreateInfo info{};
|
||||
info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
info.setLayoutCount = 0;
|
||||
info.pushConstantRangeCount = 0;
|
||||
|
||||
if (device->createPipelineLayout(info, layout) != VK_SUCCESS)
|
||||
throw std::runtime_error("failed to create pipeline layout!");
|
||||
}
|
||||
|
||||
VkShaderModule Engine::Pipeline::createShaderModule(Program::ShaderType type) {
|
||||
VkShaderModuleCreateInfo info{};
|
||||
info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
info.codeSize = program.codeSize(type);
|
||||
info.pCode = program.code(type);
|
||||
|
||||
VkShaderModule module;
|
||||
if (device->createShaderModule(info, module) != VK_SUCCESS)
|
||||
throw std::runtime_error("failed to create shader module!");
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
void Engine::Pipeline::createPipeline() {
|
||||
VkShaderModule vertShaderModule = createShaderModule(Program::vertex);
|
||||
VkShaderModule fragShaderModule = createShaderModule(Program::fragment);
|
||||
|
||||
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();
|
||||
|
||||
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 = layout;
|
||||
//pipelineInfo.renderPass = renderPass;
|
||||
pipelineInfo.subpass = 0;
|
||||
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
|
||||
if (device->createPipeline(pipelineInfo, vk) != VK_SUCCESS)
|
||||
throw std::runtime_error("failed to create graphics pipeline!");
|
||||
|
||||
device->destroyShaderModule(fragShaderModule);
|
||||
device->destroyShaderModule(vertShaderModule);
|
||||
}
|
||||
|
||||
void Engine::Pipeline::bind(const VkCommandBuffer& buffer) const {
|
||||
vkCmdBindPipeline(buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk);
|
||||
}
|
34
engine/program/pipeline.h
Normal file
34
engine/program/pipeline.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "program.h"
|
||||
|
||||
namespace Engine {
|
||||
class LogicalDevice;
|
||||
|
||||
class Pipeline {
|
||||
public:
|
||||
Pipeline(const Program& program, LogicalDevice* device);
|
||||
Pipeline(const Pipeline& other);
|
||||
~Pipeline();
|
||||
|
||||
void bind(const VkCommandBuffer& buffer) const;
|
||||
|
||||
private:
|
||||
void createLayout();
|
||||
void createPipeline();
|
||||
VkShaderModule createShaderModule(Program::ShaderType type);
|
||||
|
||||
private:
|
||||
LogicalDevice* device;
|
||||
const Program& program;
|
||||
VkPipeline vk;
|
||||
VkPipelineLayout layout;
|
||||
};
|
||||
|
||||
}
|
38
engine/program/program.cpp
Normal file
38
engine/program/program.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include "program.h"
|
||||
|
||||
Engine::Program::Program():
|
||||
vertexShader(),
|
||||
fragmentShader()
|
||||
{}
|
||||
|
||||
|
||||
std::size_t Engine::Program::codeSize(ShaderType type) const {
|
||||
switch (type) {
|
||||
case vertex:
|
||||
return vertexShader.size();
|
||||
case fragment:
|
||||
return fragmentShader.size();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint32_t* Engine::Program::code(ShaderType type) const {
|
||||
switch (type) {
|
||||
case vertex:
|
||||
return reinterpret_cast<const uint32_t*>(vertexShader.data());
|
||||
case fragment:
|
||||
return reinterpret_cast<const uint32_t*>(fragmentShader.data());
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Engine::Program::loadSPIRV(const std::string& path, ShaderType type) {
|
||||
switch (type) {
|
||||
case vertex:
|
||||
vertexShader = readFile(path);
|
||||
case fragment:
|
||||
fragmentShader = readFile(path);
|
||||
}
|
||||
}
|
30
engine/program/program.h
Normal file
30
engine/program/program.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Program {
|
||||
public:
|
||||
enum ShaderType {
|
||||
vertex,
|
||||
fragment
|
||||
};
|
||||
Program();
|
||||
|
||||
void loadSPIRV(const std::string& path, ShaderType type);
|
||||
std::size_t codeSize(ShaderType type) const;
|
||||
const uint32_t* code(ShaderType type) const;
|
||||
|
||||
private:
|
||||
std::vector<char> vertexShader;
|
||||
std::vector<char> fragmentShader;
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue