diff --git a/kitty.c b/kitty.c index 98ff79d..f6f36eb 100644 --- a/kitty.c +++ b/kitty.c @@ -4,60 +4,10 @@ #include #include "dynarray.h" -#include "image.h" #include "io.h" -#include "vulkan.h" +#include "kitty.h" #include "vulkan_helpers.c" -enum AttatchType { - CAT_ATTATCH_IMAGE, - CAT_ATTATCH_UBO, -}; - -struct Attatchment { - enum AttatchType type; - union { - struct { - const char *path; - uchar *pixels; - struct IVec2 dims; - VkDeviceSize size; - VkImage image; - VkImageView view; - VkSampler sampler; - VkDeviceMemory memory; - } image; - struct { - uint32_t size; - void *mapped[MAX_FRAMES_IN_FLIGHT]; - VkBuffer buffer[MAX_FRAMES_IN_FLIGHT]; - VkDeviceMemory memory[MAX_FRAMES_IN_FLIGHT]; - } ubo; - }; -}; - -dyn_array_define(da_Attatchment, struct Attatchment); - -struct Kitty { - VkPipeline pipeline; - VkPipelineLayout pipeline_layout; - - const char *vertex_path; - const char *fragment_path; - - struct VertexBuffer vertex_buffer; - struct IndexBuffer index_buffer; - - struct da_Attatchment attatchments; - - uint32_t push_constant_size; - void *next_push_constant; - - VkDescriptorPool descriptor_pool; - VkDescriptorSetLayout descriptor_set_layout; - VkDescriptorSet descriptor_sets[MAX_FRAMES_IN_FLIGHT]; -}; - struct Kitty *kitty_make() { struct Kitty *kitty = malloc(sizeof(struct Kitty)); memset(kitty, 0, sizeof(struct Kitty)); @@ -111,17 +61,100 @@ int kitty_attatch_ubo(struct Kitty *kitty, uint32_t size) { } void kitty_finalise(struct Vk *state, struct Kitty *kitty) { - meow("this kitty has %d attatchments", kitty->attatchments.count); + kitty_create_layout_bindings(kitty, state); + kitty_create_pipeline(kitty, state); + kitty_create_descriptor_pool(kitty, state); + kitty_create_image_attatchments(kitty, state); + kitty_create_ubo_attatchments(kitty, state); + kitty_create_descriptor_sets(kitty, state); + kitty_create_vertex_buffer(kitty, state); - if (kitty->vertex_path == NULL) { - meow("a kitty has no vertex shader :c"); - return; - } - if (kitty->fragment_path == NULL) { - meow("a kitty has no fragment shader :c"); - return; + dyn_array_append(&state->kitties, kitty); +} + +void free_kitty(struct Vk *state, struct Kitty *kitty) { + vkDeviceWaitIdle(state->device); + vkDestroyBuffer(state->device, kitty->vertex_buffer.buffer, NULL); + vkFreeMemory(state->device, kitty->vertex_buffer.memory, NULL); + vkDestroyDescriptorPool(state->device, kitty->descriptor_pool, NULL); + vkDestroyDescriptorSetLayout(state->device, kitty->descriptor_set_layout, + NULL); + vkDestroyPipelineLayout(state->device, kitty->pipeline_layout, NULL); + vkDestroyPipeline(state->device, kitty->pipeline, NULL); + for (int i = 0; i < kitty->attatchments.count; i++) { + switch (kitty->attatchments.items[i].type) { + case CAT_ATTATCH_UBO: + for (int j = 0; j < MAX_FRAMES_IN_FLIGHT; j++) { + vkDestroyBuffer(state->device, + kitty->attatchments.items[i].ubo.buffer[j], NULL); + vkFreeMemory(state->device, kitty->attatchments.items[i].ubo.memory[j], + NULL); + } + break; + case CAT_ATTATCH_IMAGE: + vkDestroyImage(state->device, kitty->attatchments.items[i].image.image, + NULL); + vkFreeMemory(state->device, kitty->attatchments.items[i].image.memory, + NULL); + vkDestroyImageView(state->device, kitty->attatchments.items[i].image.view, + NULL); + vkDestroySampler(state->device, + kitty->attatchments.items[i].image.sampler, NULL); + break; + } } + dyn_array_destroy(&kitty->vertex_buffer.format); + dyn_array_destroy(&kitty->attatchments); + + memset(kitty, 0, sizeof(struct Kitty)); + free(kitty); +} + +void kitty_set_next_push_constant(struct Kitty *kitty, void *data) { + kitty->next_push_constant = data; +} + +void kitty_set_next_ubo(struct Vk *state, struct Kitty *kitty, int index, + void *data) { + void *dst = kitty->attatchments.items[index].ubo.mapped[state->current_frame]; + void *src = data; + int size = kitty->attatchments.items[index].ubo.size; + memcpy(dst, src, size); +} + +void kitty_draw(struct Vk *state, uint32_t image_index, struct Kitty *kitty) { + struct InFlightObjects flight = state->flights[state->current_frame]; + vkCmdBindPipeline(flight.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + kitty->pipeline); + + VkViewport viewport = {0}; + viewport.x = 0.0f; + viewport.y = 0.0f; + viewport.width = state->width; + viewport.height = state->heigh; + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + vkCmdSetViewport(flight.command_buffer, 0, 1, &viewport); + + VkRect2D scissor = {0}; + scissor.offset = (VkOffset2D){0, 0}; + scissor.extent = (VkExtent2D){state->width, state->heigh}; + vkCmdSetScissor(flight.command_buffer, 0, 1, &scissor); + + VkBuffer vertex_buffer[] = {kitty->vertex_buffer.buffer}; + VkDeviceSize offsets[] = {0}; + vkCmdBindVertexBuffers(flight.command_buffer, 0, 1, vertex_buffer, offsets); + + vkCmdBindDescriptorSets( + flight.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + kitty->pipeline_layout, 0, 1, + &kitty->descriptor_sets[state->current_frame], 0, NULL); + + vkCmdDraw(flight.command_buffer, kitty->vertex_buffer.count, 1, 0, 0); +} + +void kitty_create_layout_bindings(struct Kitty *kitty, struct Vk *state) { VkDescriptorSetLayoutBinding descriptor_set_layout_binding[kitty->attatchments.count]; memset(descriptor_set_layout_binding, 0, @@ -149,7 +182,9 @@ void kitty_finalise(struct Vk *state, struct Kitty *kitty) { layout_info.pBindings = descriptor_set_layout_binding; CHECK_VK_RESULT(vkCreateDescriptorSetLayout(state->device, &layout_info, NULL, &kitty->descriptor_set_layout)); +} +void kitty_create_pipeline(struct Kitty *kitty, struct Vk *state) { int vert_size, frag_size; uint32_t *vert_shader = read_binary_file((char *)kitty->vertex_path, &vert_size); @@ -291,6 +326,14 @@ void kitty_finalise(struct Vk *state, struct Kitty *kitty) { CHECK_VK_RESULT(vkCreateGraphicsPipelines( state->device, NULL, 1, &pipeline_info, NULL, &kitty->pipeline)); + vkDestroyShaderModule(state->device, vert_module, NULL); + vkDestroyShaderModule(state->device, frag_module, NULL); + + free(vert_shader); + free(frag_shader); +} + +void kitty_create_descriptor_pool(struct Kitty *kitty, struct Vk *state) { int ubo_count = 0; int image_count = 0; for (int i = 0; i < kitty->attatchments.count; i++) { @@ -318,7 +361,9 @@ void kitty_finalise(struct Vk *state, struct Kitty *kitty) { CHECK_VK_RESULT(vkCreateDescriptorPool(state->device, &pool_info, NULL, &kitty->descriptor_pool)); +} +void kitty_create_image_attatchments(struct Kitty *kitty, struct Vk *state) { for (int index = 0; index < kitty->attatchments.count; index++) { if (kitty->attatchments.items[index].type != CAT_ATTATCH_IMAGE) { continue; @@ -391,7 +436,9 @@ void kitty_finalise(struct Vk *state, struct Kitty *kitty) { CHECK_VK_RESULT(vkCreateSampler(state->device, &sampler_info, NULL, &atch->image.sampler)); } +} +void kitty_create_ubo_attatchments(struct Kitty *kitty, struct Vk *state) { for (int index = 0; index < kitty->attatchments.count; index++) { if (kitty->attatchments.items[index].type != CAT_ATTATCH_UBO) { continue; @@ -411,7 +458,9 @@ void kitty_finalise(struct Vk *state, struct Kitty *kitty) { kitty->attatchments.items[index].ubo.mapped[i] = pointer_to_mapped; } } +} +void kitty_create_descriptor_sets(struct Kitty *kitty, struct Vk *state) { VkDescriptorSetLayout set_layouts[MAX_FRAMES_IN_FLIGHT]; for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { set_layouts[i] = kitty->descriptor_set_layout; @@ -464,7 +513,9 @@ void kitty_finalise(struct Vk *state, struct Kitty *kitty) { } } } +} +void kitty_create_vertex_buffer(struct Kitty *kitty, struct Vk *state) { VkDeviceSize size = kitty->vertex_buffer.count * kitty->vertex_buffer.vertex_size; VkBuffer staging_buffer; @@ -491,95 +542,4 @@ void kitty_finalise(struct Vk *state, struct Kitty *kitty) { vkDestroyBuffer(state->device, staging_buffer, NULL); vkFreeMemory(state->device, staging_buffer_memory, NULL); kitty->vertex_buffer.data = NULL; - - vkDestroyShaderModule(state->device, vert_module, NULL); - vkDestroyShaderModule(state->device, frag_module, NULL); - - free(vert_shader); - free(frag_shader); - - dyn_array_append(&state->kitties, kitty); - meow("appended a kitty, len is now %d", state->kitties.count); -} - -void free_kitty(struct Vk *state, struct Kitty *kitty) { - vkDeviceWaitIdle(state->device); - vkDestroyBuffer(state->device, kitty->vertex_buffer.buffer, NULL); - vkFreeMemory(state->device, kitty->vertex_buffer.memory, NULL); - vkDestroyDescriptorPool(state->device, kitty->descriptor_pool, NULL); - vkDestroyDescriptorSetLayout(state->device, kitty->descriptor_set_layout, - NULL); - vkDestroyPipelineLayout(state->device, kitty->pipeline_layout, NULL); - vkDestroyPipeline(state->device, kitty->pipeline, NULL); - for (int i = 0; i < kitty->attatchments.count; i++) { - switch (kitty->attatchments.items[i].type) { - case CAT_ATTATCH_UBO: - for (int j = 0; j < MAX_FRAMES_IN_FLIGHT; j++) { - vkDestroyBuffer(state->device, - kitty->attatchments.items[i].ubo.buffer[j], NULL); - vkFreeMemory(state->device, kitty->attatchments.items[i].ubo.memory[j], - NULL); - } - break; - case CAT_ATTATCH_IMAGE: - vkDestroyImage(state->device, kitty->attatchments.items[i].image.image, - NULL); - vkFreeMemory(state->device, kitty->attatchments.items[i].image.memory, - NULL); - vkDestroyImageView(state->device, kitty->attatchments.items[i].image.view, - NULL); - vkDestroySampler(state->device, - kitty->attatchments.items[i].image.sampler, NULL); - break; - } - } - - dyn_array_destroy(&kitty->vertex_buffer.format); - dyn_array_destroy(&kitty->attatchments); - - memset(kitty, 0, sizeof(struct Kitty)); - free(kitty); -} - -void kitty_set_next_push_constant(struct Kitty *kitty, void *data) { - kitty->next_push_constant = data; -} - -void kitty_set_next_ubo(struct Vk *state, struct Kitty *kitty, int index, - void *data) { - void *dst = kitty->attatchments.items[index].ubo.mapped[state->current_frame]; - void *src = data; - int size = kitty->attatchments.items[index].ubo.size; - memcpy(dst, src, size); -} - -void kitty_draw(struct Vk *state, uint32_t image_index, struct Kitty *kitty) { - struct InFlightObjects flight = state->flights[state->current_frame]; - vkCmdBindPipeline(flight.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - kitty->pipeline); - - VkViewport viewport = {0}; - viewport.x = 0.0f; - viewport.y = 0.0f; - viewport.width = state->width; - viewport.height = state->heigh; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - vkCmdSetViewport(flight.command_buffer, 0, 1, &viewport); - - VkRect2D scissor = {0}; - scissor.offset = (VkOffset2D){0, 0}; - scissor.extent = (VkExtent2D){state->width, state->heigh}; - vkCmdSetScissor(flight.command_buffer, 0, 1, &scissor); - - VkBuffer vertex_buffer[] = {kitty->vertex_buffer.buffer}; - VkDeviceSize offsets[] = {0}; - vkCmdBindVertexBuffers(flight.command_buffer, 0, 1, vertex_buffer, offsets); - - vkCmdBindDescriptorSets( - flight.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - kitty->pipeline_layout, 0, 1, - &kitty->descriptor_sets[state->current_frame], 0, NULL); - - vkCmdDraw(flight.command_buffer, kitty->vertex_buffer.count, 1, 0, 0); } diff --git a/kitty.h b/kitty.h index 593c8b7..e635e45 100644 --- a/kitty.h +++ b/kitty.h @@ -1,9 +1,58 @@ #ifndef INCLUDE_KITTY #define INCLUDE_KITTY +#include "image.h" +#include "vulkan.h" #include -struct Kitty; +enum AttatchType { + CAT_ATTATCH_IMAGE, + CAT_ATTATCH_UBO, +}; + +struct Attatchment { + enum AttatchType type; + union { + struct { + const char *path; + uchar *pixels; + struct IVec2 dims; + VkDeviceSize size; + VkImage image; + VkImageView view; + VkSampler sampler; + VkDeviceMemory memory; + } image; + struct { + uint32_t size; + void *mapped[MAX_FRAMES_IN_FLIGHT]; + VkBuffer buffer[MAX_FRAMES_IN_FLIGHT]; + VkDeviceMemory memory[MAX_FRAMES_IN_FLIGHT]; + } ubo; + }; +}; + +dyn_array_define(da_Attatchment, struct Attatchment); + +struct Kitty { + VkPipeline pipeline; + VkPipelineLayout pipeline_layout; + + const char *vertex_path; + const char *fragment_path; + + struct VertexBuffer vertex_buffer; + struct IndexBuffer index_buffer; + + struct da_Attatchment attatchments; + + uint32_t push_constant_size; + void *next_push_constant; + + VkDescriptorPool descriptor_pool; + VkDescriptorSetLayout descriptor_set_layout; + VkDescriptorSet descriptor_sets[MAX_FRAMES_IN_FLIGHT]; +}; struct Kitty *kitty_make(); void kitty_set_vertex_shader(struct Kitty *thingy, const char *path); @@ -36,4 +85,12 @@ void kitty_draw(struct Vk *state, uint32_t image_index, struct Kitty *thingy); void free_kitty(struct Vk *state, struct Kitty *kitty); +void kitty_create_layout_bindings(struct Kitty *kitty, struct Vk *state); +void kitty_create_pipeline(struct Kitty *kitty, struct Vk *state); +void kitty_create_descriptor_pool(struct Kitty *kitty, struct Vk *state); +void kitty_create_image_attatchments(struct Kitty *kitty, struct Vk *state); +void kitty_create_ubo_attatchments(struct Kitty *kitty, struct Vk *state); +void kitty_create_descriptor_sets(struct Kitty *kitty, struct Vk *state); +void kitty_create_vertex_buffer(struct Kitty *kitty, struct Vk *state); + #endif // INCLUDE_KITTY