diff options
| author | Clement Sibille <clements@lisible.xyz> | 2024-12-11 07:51:49 +0100 | 
|---|---|---|
| committer | Clement Sibille <clements@lisible.xyz> | 2024-12-11 07:51:49 +0100 | 
| commit | 169b120b8de4de773a8ceaeee1c9d4309179b9d3 (patch) | |
| tree | e8a5a2ff7330ad916ff1e358520e1db8c2dbc673 | |
| parent | 75026a2930624b25e4e39be2439f933bd5bd6703 (diff) | |
Add shader module loading
| -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:  | 
