164 lines
6.7 KiB
C++
164 lines
6.7 KiB
C++
#include "detail/graphics.h"
|
|
#include "detail/vertex_layout.h"
|
|
|
|
#include <fstream>
|
|
|
|
namespace deerith {
|
|
namespace graphics {
|
|
std::vector<char> read_file(const std::string& filename);
|
|
VkShaderModule create_shader_module(const std::vector<char>& code);
|
|
} // namespace graphics
|
|
|
|
void graphics::create_vulkan_graphics_pipeline() {
|
|
auto vert_shader_code = read_file("shaders/vert.spv");
|
|
auto frag_shader_code = read_file("shaders/frag.spv");
|
|
|
|
VkShaderModule vert_shader_module = create_shader_module(vert_shader_code);
|
|
VkShaderModule frag_shader_module = create_shader_module(frag_shader_code);
|
|
|
|
VkPipelineShaderStageCreateInfo vert_shader_stage_info{};
|
|
vert_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
|
vert_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
|
vert_shader_stage_info.module = vert_shader_module;
|
|
vert_shader_stage_info.pName = "main";
|
|
|
|
VkPipelineShaderStageCreateInfo frag_shader_stage_info{};
|
|
frag_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
|
frag_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
frag_shader_stage_info.module = frag_shader_module;
|
|
frag_shader_stage_info.pName = "main";
|
|
|
|
VkPipelineShaderStageCreateInfo shader_stages[] = {vert_shader_stage_info, frag_shader_stage_info};
|
|
|
|
VkPipelineVertexInputStateCreateInfo vertex_input_info{};
|
|
vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
|
vertex_input_info.vertexBindingDescriptionCount = 0;
|
|
vertex_input_info.pVertexBindingDescriptions = nullptr; // Optional
|
|
vertex_input_info.vertexAttributeDescriptionCount = 0;
|
|
vertex_input_info.pVertexAttributeDescriptions = nullptr; // Optional
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo input_assembly{};
|
|
input_assembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
|
input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
|
input_assembly.primitiveRestartEnable = VK_FALSE;
|
|
|
|
VkViewport viewport{};
|
|
viewport.x = 0.0f;
|
|
viewport.y = 0.0f;
|
|
viewport.width = (float)swap_chain_extent.width;
|
|
viewport.height = (float)swap_chain_extent.height;
|
|
viewport.minDepth = 0.0f;
|
|
viewport.maxDepth = 1.0f;
|
|
|
|
VkRect2D scissor{};
|
|
scissor.offset = {0, 0};
|
|
scissor.extent = swap_chain_extent;
|
|
|
|
VkPipelineViewportStateCreateInfo viewport_state{};
|
|
viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
|
viewport_state.viewportCount = 1;
|
|
viewport_state.pViewports = &viewport;
|
|
viewport_state.scissorCount = 1;
|
|
viewport_state.pScissors = &scissor;
|
|
|
|
VkPipelineRasterizationStateCreateInfo rasterizer{};
|
|
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
|
rasterizer.depthClampEnable = VK_FALSE;
|
|
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
|
rasterizer.depthBiasEnable = VK_FALSE;
|
|
rasterizer.lineWidth = 1.0f;
|
|
rasterizer.depthBiasConstantFactor = 0.0f; // Optional
|
|
rasterizer.depthBiasClamp = 0.0f; // Optional
|
|
rasterizer.depthBiasSlopeFactor = 0.0f; // Optional
|
|
|
|
VkPipelineColorBlendAttachmentState color_blend_attachment{};
|
|
color_blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
|
color_blend_attachment.blendEnable = VK_FALSE;
|
|
|
|
VkPipelineLayoutCreateInfo pipeline_layout_info{};
|
|
pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
|
pipeline_layout_info.setLayoutCount = 0; // Optional
|
|
pipeline_layout_info.pSetLayouts = nullptr; // Optional
|
|
pipeline_layout_info.pushConstantRangeCount = 0; // Optional
|
|
pipeline_layout_info.pPushConstantRanges = nullptr; // Optional
|
|
|
|
VkPipelineMultisampleStateCreateInfo multisampling{};
|
|
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
|
multisampling.sampleShadingEnable = VK_FALSE;
|
|
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
|
multisampling.minSampleShading = 1.0f; // Optional
|
|
multisampling.pSampleMask = nullptr; // Optional
|
|
multisampling.alphaToCoverageEnable = VK_FALSE; // Optional
|
|
multisampling.alphaToOneEnable = VK_FALSE; // Optional
|
|
|
|
VkPipelineColorBlendStateCreateInfo color_blending{};
|
|
color_blending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
|
color_blending.logicOpEnable = VK_FALSE;
|
|
color_blending.logicOp = VK_LOGIC_OP_COPY; // Optional
|
|
color_blending.attachmentCount = 1;
|
|
color_blending.pAttachments = &color_blend_attachment;
|
|
color_blending.blendConstants[0] = 0.0f; // Optional
|
|
color_blending.blendConstants[1] = 0.0f; // Optional
|
|
color_blending.blendConstants[2] = 0.0f; // Optional
|
|
color_blending.blendConstants[3] = 0.0f; // Optional
|
|
|
|
if (vkCreatePipelineLayout(device, &pipeline_layout_info, nullptr, &pipeline_layout) != VK_SUCCESS) {
|
|
deerith_graphics_error("failed to create pipeline layout!");
|
|
}
|
|
|
|
VkGraphicsPipelineCreateInfo pipline_info{};
|
|
pipline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
|
pipline_info.stageCount = 2;
|
|
pipline_info.pStages = shader_stages;
|
|
|
|
pipline_info.pVertexInputState = &vertex_input_info;
|
|
pipline_info.pInputAssemblyState = &input_assembly;
|
|
pipline_info.pViewportState = &viewport_state;
|
|
pipline_info.pRasterizationState = &rasterizer;
|
|
pipline_info.pMultisampleState = &multisampling;
|
|
pipline_info.pDepthStencilState = nullptr; // Optional
|
|
pipline_info.pColorBlendState = &color_blending;
|
|
pipline_info.pDynamicState = nullptr;
|
|
pipline_info.layout = pipeline_layout;
|
|
pipline_info.renderPass = render_pass;
|
|
pipline_info.subpass = 0;
|
|
|
|
if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipline_info, nullptr, &graphics_pipeline) != VK_SUCCESS) {
|
|
deerith_graphics_error("failed to create graphics pipeline!");
|
|
}
|
|
|
|
vkDestroyShaderModule(device, frag_shader_module, nullptr);
|
|
vkDestroyShaderModule(device, vert_shader_module, nullptr);
|
|
}
|
|
|
|
VkShaderModule graphics::create_shader_module(const std::vector<char>& code) {
|
|
VkShaderModuleCreateInfo create_info{};
|
|
create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
|
create_info.codeSize = code.size();
|
|
create_info.pCode = reinterpret_cast<const uint32_t*>(code.data());
|
|
|
|
VkShaderModule shader_module;
|
|
if (vkCreateShaderModule(device, &create_info, nullptr, &shader_module) != VK_SUCCESS) {
|
|
deerith_graphics_error("failed to create shader module!");
|
|
}
|
|
|
|
return shader_module;
|
|
}
|
|
|
|
std::vector<char> graphics::read_file(const std::string& filename) {
|
|
std::ifstream file(filename, std::ios::ate | std::ios::binary);
|
|
|
|
if (!file.is_open()) {
|
|
deerith_graphics_error("failed to open file!");
|
|
}
|
|
|
|
size_t file_size = (size_t)file.tellg();
|
|
std::vector<char> buffer(file_size);
|
|
|
|
file.seekg(0);
|
|
file.read(buffer.data(), file_size);
|
|
|
|
file.close();
|
|
return buffer;
|
|
}
|
|
} // namespace deerith
|