mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-11 19:28:40 +00:00
196 lines
7.7 KiB
C
196 lines
7.7 KiB
C
/**
|
|
* Jingga
|
|
*
|
|
* @copyright Jingga
|
|
* @license OMS License 2.0
|
|
* @version 1.0.0
|
|
* @link https://jingga.app
|
|
*/
|
|
#ifndef TOS_GPUAPI_VULKAN_SHADER_UTILS_H
|
|
#define TOS_GPUAPI_VULKAN_SHADER_UTILS_H
|
|
|
|
#include <vulkan/vulkan.h>
|
|
|
|
#include "../../stdlib/Types.h"
|
|
#include "../../memory/RingMemory.h"
|
|
#include "../../log/Log.h"
|
|
|
|
inline uint32_t shader_get_uniform_location(
|
|
VkWriteDescriptorSet* descriptor,
|
|
VkDescriptorSet descriptorSet, uint32_t binding, VkDescriptorType descriptorType
|
|
) {
|
|
descriptor->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
descriptor->dstSet = descriptorSet;
|
|
descriptor->dstBinding = binding;
|
|
descriptor->dstArrayElement = 0;
|
|
descriptor->descriptorType = descriptorType;
|
|
descriptor->descriptorCount = 1;
|
|
}
|
|
|
|
inline void shader_set_value(VkDevice device, VkDescriptorSet descriptorSet, uint32_t binding, VkDescriptorType descriptorType, int32_t value)
|
|
{
|
|
VkDescriptorBufferInfo bufferInfo = {};
|
|
bufferInfo.buffer = {}; // You should have a buffer holding the value
|
|
bufferInfo.offset = 0;
|
|
bufferInfo.range = sizeof(value);
|
|
|
|
VkWriteDescriptorSet descriptorWrite = {};
|
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
descriptorWrite.dstSet = descriptorSet;
|
|
descriptorWrite.dstBinding = binding;
|
|
descriptorWrite.dstArrayElement = 0;
|
|
descriptorWrite.descriptorType = descriptorType;
|
|
descriptorWrite.descriptorCount = 1;
|
|
descriptorWrite.pBufferInfo = &bufferInfo;
|
|
|
|
vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, NULL);
|
|
}
|
|
|
|
VkShaderModule shader_make(VkDevice device, const char* source, int32 source_size)
|
|
{
|
|
// Create shader module create info
|
|
VkShaderModuleCreateInfo create_info = {};
|
|
create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
|
create_info.codeSize = source_size;
|
|
create_info.pCode = (uint32 *) source;
|
|
|
|
// Create shader module
|
|
VkShaderModule shader_module;
|
|
VkResult result = vkCreateShaderModule(device, &create_info, NULL, &shader_module);
|
|
|
|
if (result != VK_SUCCESS) {
|
|
LOG_FORMAT(true, "Vulkan vkCreateShaderModule: %d", LOG_DATA_INT32, (int32 *) &result);
|
|
ASSERT_SIMPLE(false);
|
|
|
|
return VK_NULL_HANDLE;
|
|
}
|
|
|
|
return shader_module;
|
|
}
|
|
|
|
inline
|
|
void pipeline_use(VkCommandBuffer command_buffer, VkPipeline pipeline)
|
|
{
|
|
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
|
}
|
|
|
|
VkPipeline program_make(
|
|
VkDevice device, VkRenderPass render_pass, VkPipelineLayout* pipeline_layout, VkPipeline* pipeline,
|
|
VkShaderModule vertex_shader,
|
|
VkShaderModule fragment_shader,
|
|
VkShaderModule
|
|
) {
|
|
VkPipelineShaderStageCreateInfo vertex_shader_stage_info = {};
|
|
vertex_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
|
vertex_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
|
vertex_shader_stage_info.module = vertex_shader;
|
|
vertex_shader_stage_info.pName = "main";
|
|
|
|
VkPipelineShaderStageCreateInfo fragment_shader_stage_info = {};
|
|
fragment_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
|
fragment_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
fragment_shader_stage_info.module = fragment_shader;
|
|
fragment_shader_stage_info.pName = "main";
|
|
|
|
VkPipelineShaderStageCreateInfo shader_stages[] = {vertex_shader_stage_info, fragment_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.vertexAttributeDescriptionCount = 0;
|
|
|
|
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;
|
|
|
|
VkPipelineViewportStateCreateInfo viewport_state = {};
|
|
viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
|
viewport_state.viewportCount = 1;
|
|
viewport_state.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 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;
|
|
|
|
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;
|
|
color_blending.attachmentCount = 1;
|
|
color_blending.pAttachments = &color_blend_attachment;
|
|
color_blending.blendConstants[0] = 0.0f;
|
|
color_blending.blendConstants[1] = 0.0f;
|
|
color_blending.blendConstants[2] = 0.0f;
|
|
color_blending.blendConstants[3] = 0.0f;
|
|
|
|
VkDynamicState dynamic_states[] = {
|
|
VK_DYNAMIC_STATE_VIEWPORT,
|
|
VK_DYNAMIC_STATE_SCISSOR
|
|
};
|
|
|
|
VkPipelineDynamicStateCreateInfo dynamic_state = {};
|
|
dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
|
dynamic_state.dynamicStateCount = ARRAY_COUNT(dynamic_states);
|
|
dynamic_state.pDynamicStates = dynamic_states;
|
|
|
|
VkPipelineLayoutCreateInfo pipeline_info_layout = {};
|
|
pipeline_info_layout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
|
pipeline_info_layout.setLayoutCount = 0;
|
|
pipeline_info_layout.pushConstantRangeCount = 0;
|
|
|
|
VkResult result;
|
|
if ((result = vkCreatePipelineLayout(device, &pipeline_info_layout, NULL, pipeline_layout)) != VK_SUCCESS) {
|
|
LOG_FORMAT(true, "Vulkan vkCreatePipelineLayout: %d", LOG_DATA_INT32, (int32 *) &result);
|
|
ASSERT_SIMPLE(false);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
VkGraphicsPipelineCreateInfo pipeline_info = {};
|
|
pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
|
pipeline_info.stageCount = 2;
|
|
pipeline_info.pStages = shader_stages;
|
|
pipeline_info.pVertexInputState = &vertex_input_info;
|
|
pipeline_info.pInputAssemblyState = &input_assembly;
|
|
pipeline_info.pViewportState = &viewport_state;
|
|
pipeline_info.pRasterizationState = &rasterizer;
|
|
pipeline_info.pMultisampleState = &multisampling;
|
|
pipeline_info.pColorBlendState = &color_blending;
|
|
pipeline_info.pDynamicState = &dynamic_state;
|
|
pipeline_info.layout = *pipeline_layout;
|
|
pipeline_info.renderPass = render_pass;
|
|
pipeline_info.subpass = 0;
|
|
pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
|
|
|
|
if ((result = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_info, NULL, pipeline)) != VK_SUCCESS) {
|
|
LOG_FORMAT(true, "Vulkan vkCreateGraphicsPipelines: %d", LOG_DATA_INT32, (int32 *) &result);
|
|
ASSERT_SIMPLE(false);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
vkDestroyShaderModule(device, fragment_shader, NULL);
|
|
vkDestroyShaderModule(device, vertex_shader, NULL);
|
|
|
|
// @question Do we want to return the value or the pointer?
|
|
// I think the value is already a pointer?
|
|
return *pipeline;
|
|
}
|
|
|
|
#endif |