diff --git a/README b/README index 9772202..b41d637 100644 --- a/README +++ b/README @@ -1 +1,4 @@ Project to learn the vulkan API. + +Checkpoints: +`#2deb04f9ed8c9af493e9a922ebc2ea678954d9a3`: first triangle rendering complete diff --git a/notes.md b/notes.md index 521a7d1..001be4b 100644 --- a/notes.md +++ b/notes.md @@ -24,11 +24,20 @@ content will be treated, to draw a simple triangle we can tell vulkan that there will be a single image that's a color target and that it needs to be cleared to a solid color before drawing. Note: a render pass describes the type of images, a `VkFramebuffer` binds specific images to slots. + Render passes have subpasses, while a render pass describes which images are going to be used the subpasses + describe which ones will be used for what. - `VkPipeline`, describes the configuration of the graphics card, like viewport size, depth buffer operations, the programmable state is specified using `VkShaderModule` objects, which are created from shader bytecode. The driver also needs to know which render targets are going to be used in the pipeline. All of the settings are configured in advance, and changing them requires creating a new `VkPipeline`. + Each pipeline is bound to a compatible render pass to it, at a specific subpass of it, the reason for this + is twofold: things such as fragment shaders will end up writing to the attachments, so it makes sense that + a pipeline, which among other things holds shaders, should know which ones and how, secondarily this allows + for optimizations on tiled gpus, which are sometimes able to merge subpasses. + Another important details is that as of later versions of vulkan render passes are not required when enabling + an extension (`VK_KHR_dynamic_rendering`), this simplifies the code at the potential cost of performance on some + hardware. - Commands are recorded into a `VkCommandBuffer`, the buffers are allocated out of a `VkCommandPool` associated with a queue family, in order to do some simple drawing we need to do the following: diff --git a/src/main.c b/src/main.c index 9066938..8891e5f 100644 --- a/src/main.c +++ b/src/main.c @@ -54,9 +54,6 @@ typedef struct ApplicationState { VkExtent2D swapchain_extent; //describes how to access an image and allows access to it VkImageView* swapchain_image_views; - //shaders - VkShaderModule vertex_shader_module; - VkShaderModule fragment_shader_module; VkRenderPass render_pass; VkPipelineLayout pipeline_layout; @@ -656,24 +653,27 @@ void create_render_pass(ApplicationState* state) { //color blending : applies operations to mix different fragments that map to the same pixel void create_graphics_pipeline(ApplicationState* state) { + //shaders + VkShaderModule vertex_shader_module; + VkShaderModule fragment_shader_module; size_t vertex_shader_size; size_t fragment_shader_size; char* vertex_shader = load_file("./vertex_simple.spv", &vertex_shader_size); char* fragment_shader = load_file("./fragment_simple.spv", &fragment_shader_size); - state->vertex_shader_module = create_shader_module(state, vertex_shader, vertex_shader_size); - state->fragment_shader_module = create_shader_module(state, fragment_shader, fragment_shader_size); + vertex_shader_module = create_shader_module(state, vertex_shader, vertex_shader_size); + fragment_shader_module = create_shader_module(state, fragment_shader, fragment_shader_size); VkPipelineShaderStageCreateInfo vertex_shader_stage_info = {0}; 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 = state->vertex_shader_module; + vertex_shader_stage_info.module = vertex_shader_module; vertex_shader_stage_info.pName = "main"; VkPipelineShaderStageCreateInfo fragment_shader_stage_info = {0}; 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 = state->fragment_shader_module; + fragment_shader_stage_info.module = fragment_shader_module; fragment_shader_stage_info.pName = "main"; VkPipelineShaderStageCreateInfo shader_stages[] = {vertex_shader_stage_info, fragment_shader_stage_info}; @@ -820,6 +820,9 @@ void create_graphics_pipeline(ApplicationState* state) { exit(1); } printf("created graphics pipeline\n"); + + vkDestroyShaderModule(state->device, vertex_shader_module, NULL); + vkDestroyShaderModule(state->device, fragment_shader_module, NULL); } void create_framebuffers(ApplicationState* state) { @@ -1034,6 +1037,8 @@ void main_loop(ApplicationState* state) { draw_frame(state, current_frame); glfwPollEvents(); } + + vkDeviceWaitIdle(state->device); } void terminate(ApplicationState* state) {