diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rwxr-xr-x | shaders/compile.sh | 3 | ||||
| -rw-r--r-- | shaders/triangle.frag | 8 | ||||
| -rw-r--r-- | shaders/triangle.vert | 20 | ||||
| -rw-r--r-- | src/main.c | 98 |
5 files changed, 130 insertions, 0 deletions
@@ -1,2 +1,3 @@ .cache/ build/ +shaders/*.spv diff --git a/shaders/compile.sh b/shaders/compile.sh new file mode 100755 index 0000000..b60f97c --- /dev/null +++ b/shaders/compile.sh @@ -0,0 +1,3 @@ +#!/bin/sh +glslc triangle.vert -o triangle.vert.spv +glslc triangle.frag -o triangle.frag.spv diff --git a/shaders/triangle.frag b/shaders/triangle.frag new file mode 100644 index 0000000..75d5fcd --- /dev/null +++ b/shaders/triangle.frag @@ -0,0 +1,8 @@ +#version 450 + +layout(location = 0) in vec3 frag_color; +layout(location = 0) out vec4 out_color; + +void main() { + out_color = vec4(frag_color, 1.0); +} diff --git a/shaders/triangle.vert b/shaders/triangle.vert new file mode 100644 index 0000000..9f35e1a --- /dev/null +++ b/shaders/triangle.vert @@ -0,0 +1,20 @@ +#version 450 + +vec2 positions[3] = vec2[]( + vec2(0.0, -0.5), + vec2(0.5, 0.5), + vec2(-0.5, 0.5) +); + +vec3 colors[3] = vec3[]( + vec3(1.0, 0.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 0.0, 1.0) +); + +layout(location = 0) out vec3 frag_color; + +void main() { + gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); + frag_color = colors[gl_VertexIndex]; +} @@ -612,6 +612,91 @@ err: return false; } +char *load_shader_from_file(const char *path, size_t *out_size) { + FILE *file_handle = fopen(path, "rb"); + if (!file_handle) { + goto err; + } + + if (fseek(file_handle, 0, SEEK_END) < 0) { + goto close_file; + } + + long file_size = ftell(file_handle); + if (file_size < 0) { + goto close_file; + } + rewind(file_handle); + char *shader_file_content = malloc(file_size); + if (fread(shader_file_content, file_size, 1, file_handle) != 1) { + goto free_shader_file_content; + } + + if (fclose(file_handle) != 0) { + goto err; + } + + *out_size = file_size; + return shader_file_content; +free_shader_file_content: + free(shader_file_content); +close_file: + fclose(file_handle); +err: + return NULL; +} + +VkShaderModule create_shader_module(VkDevice device, char *code, + size_t code_size) { + VkShaderModule shader_module; + if (vkCreateShaderModule( + device, + &(const VkShaderModuleCreateInfo){ + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .codeSize = code_size, + .pCode = (const uint32_t *)code, + }, + NULL, &shader_module) != VK_SUCCESS) { + return NULL; + } + + return shader_module; +} + +bool vulkan_renderer_create_graphics_pipeline( + struct vulkan_renderer *renderer) { + size_t vertex_shader_code_size; + char *vertex_shader_code = load_shader_from_file("shaders/triangle.vert.spv", + &vertex_shader_code_size); + size_t fragment_shader_code_size; + char *fragment_shader_code = load_shader_from_file( + "shaders/triangle.frag.spv", &fragment_shader_code_size); + VkShaderModule vertex_shader_module = create_shader_module( + renderer->device, vertex_shader_code, vertex_shader_code_size); + VkShaderModule fragment_shader_module = create_shader_module( + renderer->device, fragment_shader_code, fragment_shader_code_size); + free(vertex_shader_code); + free(fragment_shader_code); + + VkPipelineShaderStageCreateInfo vertex_shader_stage_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = vertex_shader_module, + .pName = "main"}; + VkPipelineShaderStageCreateInfo fragment_shader_stage_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = fragment_shader_module, + .pName = "main"}; + + VkPipelineShaderStageCreateInfo shader_stages[] = { + vertex_shader_stage_info, fragment_shader_stage_info}; + + vkDestroyShaderModule(renderer->device, vertex_shader_module, NULL); + vkDestroyShaderModule(renderer->device, fragment_shader_module, NULL); + return true; +} + bool vulkan_renderer_init(struct vulkan_renderer *renderer, SDL_Window *window) { assert(renderer); @@ -666,8 +751,21 @@ bool vulkan_renderer_init(struct vulkan_renderer *renderer, goto destroy_swapchain; } + if (!vulkan_renderer_create_graphics_pipeline(renderer)) { + LOG("Couldn't create graphics pipeline"); + goto destroy_swapchain_image_views; + } + return true; +destroy_swapchain_image_views: + for (uint32_t swapchain_image_view_index = 0; + swapchain_image_view_index < renderer->swapchain_image_count; + swapchain_image_view_index++) { + vkDestroyImageView( + renderer->device, + renderer->swapchain_image_views[swapchain_image_view_index], NULL); + } destroy_swapchain: vkDestroySwapchainKHR(renderer->device, renderer->swapchain, NULL); destroy_logical_device: |
