basic rendering for both opengl and vulkan
This commit is contained in:
parent
4b18afa040
commit
dadd2edaf1
29 changed files with 1140 additions and 38 deletions
198
rendering/vk/pipeline.c
Normal file
198
rendering/vk/pipeline.c
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/* SPDX-License-Identifier:BSD-3-Clause */
|
||||
#include "pipeline.h"
|
||||
#include "../../core/log.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static u8 *read_file(const char *path, usize *size)
|
||||
{
|
||||
FILE *file = fopen(path, "rb");
|
||||
if (!file) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
*size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
u8 *data = malloc(*size);
|
||||
fread(data, 1, *size, file);
|
||||
fclose(file);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static VkShaderModule create_shader_module(VkDevice device, u8 *code, usize size)
|
||||
{
|
||||
VkShaderModuleCreateInfo create_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||
.codeSize = size,
|
||||
.pCode = (u32 *)code
|
||||
};
|
||||
|
||||
VkShaderModule module;
|
||||
if (vkCreateShaderModule(device, &create_info, NULL, &module) != VK_SUCCESS) {
|
||||
fatal("Can't create shader module.\n");
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
void vk_pipeline_init(struct renderer_context *context)
|
||||
{
|
||||
usize vert_size, frag_size;
|
||||
u8 *vert_code = read_file("assets/shaders/quad.vert.spv", &vert_size);
|
||||
u8 *frag_code = read_file("assets/shaders/quad.frag.spv", &frag_size);
|
||||
|
||||
if (!vert_code || !frag_code) {
|
||||
fatal("Can't read shader files.\n");
|
||||
}
|
||||
|
||||
VkShaderModule vert_module = create_shader_module(context->device, vert_code, vert_size);
|
||||
VkShaderModule frag_module = create_shader_module(context->device, frag_code, frag_size);
|
||||
|
||||
free(vert_code);
|
||||
free(frag_code);
|
||||
|
||||
VkPipelineShaderStageCreateInfo shader_stages[] = {
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.module = vert_module,
|
||||
.pName = "main"
|
||||
},
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.module = frag_module,
|
||||
.pName = "main"
|
||||
}
|
||||
};
|
||||
|
||||
VkVertexInputBindingDescription binding = {
|
||||
.binding = 0,
|
||||
.stride = sizeof(f32) * 5,
|
||||
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
|
||||
};
|
||||
|
||||
VkVertexInputAttributeDescription attributes[] = {
|
||||
{
|
||||
.binding = 0,
|
||||
.location = 0,
|
||||
.format = VK_FORMAT_R32G32_SFLOAT,
|
||||
.offset = 0
|
||||
},
|
||||
{
|
||||
.binding = 0,
|
||||
.location = 1,
|
||||
.format = VK_FORMAT_R32G32B32_SFLOAT,
|
||||
.offset = sizeof(f32) * 2
|
||||
}
|
||||
};
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertex_input = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||
.vertexBindingDescriptionCount = 1,
|
||||
.pVertexBindingDescriptions = &binding,
|
||||
.vertexAttributeDescriptionCount = 2,
|
||||
.pVertexAttributeDescriptions = attributes
|
||||
};
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo input_assembly = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
||||
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
|
||||
.primitiveRestartEnable = VK_FALSE
|
||||
};
|
||||
|
||||
VkViewport viewport = {
|
||||
.x = 0.0f,
|
||||
.y = 0.0f,
|
||||
.width = (f32)context->swapchain.extent.width,
|
||||
.height = (f32)context->swapchain.extent.height,
|
||||
.minDepth = 0.0f,
|
||||
.maxDepth = 1.0f
|
||||
};
|
||||
|
||||
VkRect2D scissor = {
|
||||
.offset = { 0, 0 },
|
||||
.extent = context->swapchain.extent
|
||||
};
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewport_state = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
||||
.viewportCount = 1,
|
||||
.pViewports = &viewport,
|
||||
.scissorCount = 1,
|
||||
.pScissors = &scissor
|
||||
};
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterizer = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||
.depthClampEnable = VK_FALSE,
|
||||
.rasterizerDiscardEnable = VK_FALSE,
|
||||
.polygonMode = VK_POLYGON_MODE_FILL,
|
||||
.lineWidth = 1.0f,
|
||||
.cullMode = VK_CULL_MODE_BACK_BIT,
|
||||
.frontFace = VK_FRONT_FACE_CLOCKWISE,
|
||||
.depthBiasEnable = VK_FALSE
|
||||
};
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisampling = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
||||
.sampleShadingEnable = VK_FALSE,
|
||||
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT
|
||||
};
|
||||
|
||||
VkPipelineColorBlendAttachmentState blend_attachment = {
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
|
||||
.blendEnable = VK_FALSE
|
||||
};
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo color_blend = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
||||
.logicOpEnable = VK_FALSE,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments = &blend_attachment
|
||||
};
|
||||
|
||||
VkPipelineLayoutCreateInfo layout_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
.setLayoutCount = 0,
|
||||
.pushConstantRangeCount = 0
|
||||
};
|
||||
|
||||
if (vkCreatePipelineLayout(context->device, &layout_info, NULL, &context->pipeline_layout) != VK_SUCCESS) {
|
||||
fatal("Can't create pipeline layout.\n");
|
||||
}
|
||||
|
||||
VkGraphicsPipelineCreateInfo pipeline_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
.stageCount = 2,
|
||||
.pStages = shader_stages,
|
||||
.pVertexInputState = &vertex_input,
|
||||
.pInputAssemblyState = &input_assembly,
|
||||
.pViewportState = &viewport_state,
|
||||
.pRasterizationState = &rasterizer,
|
||||
.pMultisampleState = &multisampling,
|
||||
.pColorBlendState = &color_blend,
|
||||
.layout = context->pipeline_layout,
|
||||
.renderPass = context->render_pass,
|
||||
.subpass = 0
|
||||
};
|
||||
|
||||
if (vkCreateGraphicsPipelines(context->device, VK_NULL_HANDLE, 1, &pipeline_info, NULL, &context->pipeline) != VK_SUCCESS) {
|
||||
fatal("Can't create graphics pipeline.\n");
|
||||
}
|
||||
|
||||
vkDestroyShaderModule(context->device, vert_module, NULL);
|
||||
vkDestroyShaderModule(context->device, frag_module, NULL);
|
||||
|
||||
log_info("Graphics pipeline created.\n");
|
||||
}
|
||||
|
||||
void vk_pipeline_deinit(struct renderer_context *context)
|
||||
{
|
||||
vkDestroyPipeline(context->device, context->pipeline, NULL);
|
||||
vkDestroyPipelineLayout(context->device, context->pipeline_layout, NULL);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue