diff --git a/client/Makefile b/client/Makefile index 1728e53..5d187fa 100644 --- a/client/Makefile +++ b/client/Makefile @@ -2,7 +2,7 @@ ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) CFLAGS = -I $(ROOT_DIR)/include -I/usr/local/include -O0 -g -Wall -Wextra -fsanitize=address LDFLAGS = -lfreetype -lz -lglfw -lvulkan -ldl -Xlinker -rpath -Xlinker /opt/homebrew/lib -SOURCES = src/main.c src/render.c src/ui.c src/command.c lib/spng.c lib/vma.cpp +SOURCES = src/main.c src/draw.c src/ui.c src/gpu.c lib/spng.c lib/vma.cpp OBJECTS = $(addsuffix .o, $(basename $(SOURCES))) VERT_SPV = $(addsuffix .vert.spv, $(basename $(wildcard shader_src/*.vert))) FRAG_SPV = $(addsuffix .frag.spv, $(basename $(wildcard shader_src/*.frag))) diff --git a/client/include/command.h b/client/include/command.h index ff4838c..959e93b 100644 --- a/client/include/command.h +++ b/client/include/command.h @@ -3,19 +3,4 @@ #include "vulkan/vulkan_core.h" -typedef struct QueueStruct { - VkQueue handle; - uint32_t family; - uint32_t index; -} Queue; - - -VkCommandBuffer command_begin_single(VkDevice device, VkCommandPool transfer_pool); - -VkResult command_end_single(VkDevice device, VkCommandBuffer command_buffer, VkCommandPool transfer_pool, Queue transfer_queue); - -void command_copy_buffer(VkCommandBuffer command_buffer, VkBuffer src, VkBuffer dst, VkDeviceSize src_offset, VkDeviceSize dst_offset, VkDeviceSize size); - -VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer_pool, Queue transfer_queue, VkImageLayout old_layout, VkImageLayout new_layout, VkImage image, VkAccessFlags src_mask, VkAccessFlags dst_mask, VkPipelineStageFlags source, VkPipelineStageFlags dest, uint32_t source_family, uint32_t dest_family, VkImageAspectFlags aspect_flags); - #endif diff --git a/client/include/draw.h b/client/include/draw.h new file mode 100644 index 0000000..5b5fa68 --- /dev/null +++ b/client/include/draw.h @@ -0,0 +1,13 @@ +#ifndef RENDER_H +#define RENDER_H + +#include "gpu.h" +#include "ui.h" + +VkResult draw_frame( + RenderContext* context, + UIContextStorage* ui_context, + UILayerStorage* ui_layers, + uint32_t ui_layer_count); + +#endif diff --git a/client/include/render.h b/client/include/gpu.h similarity index 74% rename from client/include/render.h rename to client/include/gpu.h index da94c26..a81e3c9 100644 --- a/client/include/render.h +++ b/client/include/gpu.h @@ -1,5 +1,5 @@ -#ifndef RENDER_H -#define RENDER_H +#ifndef GPU_H +#define GPU_H #define VK_USE_PLATFORM_MACOS_MVK #include "vulkan/vulkan_core.h" @@ -24,8 +24,20 @@ #include #include -#include "ui.h" -#include "command.h" +typedef struct QueueStruct { + VkQueue handle; + uint32_t family; + uint32_t index; +} Queue; + + +VkCommandBuffer command_begin_single(VkDevice device, VkCommandPool transfer_pool); + +VkResult command_end_single(VkDevice device, VkCommandBuffer command_buffer, VkCommandPool transfer_pool, Queue transfer_queue); + +void command_copy_buffer(VkCommandBuffer command_buffer, VkBuffer src, VkBuffer dst, VkDeviceSize src_offset, VkDeviceSize dst_offset, VkDeviceSize size); + +VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer_pool, Queue transfer_queue, VkImageLayout old_layout, VkImageLayout new_layout, VkImage image, VkAccessFlags src_mask, VkAccessFlags dst_mask, VkPipelineStageFlags source, VkPipelineStageFlags dest, uint32_t source_family, uint32_t dest_family, VkImageAspectFlags aspect_flags); #define VK_RESULT(x) {\ result = x;\ @@ -97,12 +109,6 @@ VkResult init_vulkan( GLFWwindow* window, RenderContext* context); -VkResult draw_frame( - RenderContext* context, - UIContextStorage* ui_context, - UILayerStorage* ui_layers, - uint32_t ui_layer_count); - VkResult create_transfer_buffer( VmaAllocator allocator, VkDeviceSize size, diff --git a/client/include/ui.h b/client/include/ui.h index c3f338f..9179c1e 100644 --- a/client/include/ui.h +++ b/client/include/ui.h @@ -4,7 +4,7 @@ #include "vulkan/vulkan_core.h" #include "cglm/types.h" #include "vk_mem_alloc.h" -#include "command.h" +#include "gpu.h" #include "ft2build.h" #include FT_FREETYPE_H @@ -130,6 +130,10 @@ typedef struct UIContainerStorageStruct { VkDeviceAddress address; UIContainer data; + + uint32_t id; + uint32_t layer_count; + UILayerStorage* layers; } UIContainerStorage; typedef struct UIContextStruct { @@ -169,37 +173,25 @@ typedef struct UIContextStorageStruct { } UIContextStorage; VkResult create_ui_context( - VkDevice device, - VmaAllocator allocator, - VkRenderPass render_pass, uint32_t max_fonts, uint32_t max_textures, - VkExtent2D swapchain_extent, - vec2 window_scale, - VkCommandPool transfer_pool, - Queue transfer_queue, + RenderContext* gpu, UIContextStorage* memory); VkResult load_font( - VkDevice device, - VmaAllocator allocator, - UIContextStorage* context, - VkCommandPool transfer_pool, - Queue transfer_queue, - FT_Library library, const char* ttf_file, uint32_t size, VkBool32 antialias, + FT_Library library, + RenderContext* gpu, + UIContextStorage* context, uint32_t* index, FontStorage* memory); VkResult load_texture( - VkDevice device, - VmaAllocator allocator, + const char* png_path, + RenderContext* gpu, UIContextStorage* context, - VkCommandPool transfer_pool, - Queue transfer_queue, - const char* png_file, uint32_t* index, TextureStorage* memory); @@ -208,10 +200,7 @@ VkResult create_container( float y, float width, float height, - VkDevice device, - VmaAllocator allocator, - VkCommandPool transfer_pool, - Queue transfer_queue, + RenderContext* gpu, UIContainerStorage* memory); VkResult create_layer( @@ -219,10 +208,7 @@ VkResult create_layer( uint32_t max_codes, uint32_t max_drawables, uint32_t font_index, - VkDevice device, - VmaAllocator allocator, - VkCommandPool transfer_pool, - Queue transfer_queue, + RenderContext* gpu, UIContainerStorage* container, UILayerStorage* memory); diff --git a/client/src/command.c b/client/src/command.c deleted file mode 100644 index a9d457e..0000000 --- a/client/src/command.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "command.h" - -VkCommandBuffer command_begin_single(VkDevice device, VkCommandPool transfer_pool) { - VkCommandBufferAllocateInfo command_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - .commandPool = transfer_pool, - .commandBufferCount = 1, - }; - - VkCommandBuffer command_buffer; - VkResult result = vkAllocateCommandBuffers(device, &command_info, &command_buffer); - if(result != VK_SUCCESS) { - return VK_NULL_HANDLE; - } - - VkCommandBufferBeginInfo begin_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, - }; - - result = vkBeginCommandBuffer(command_buffer, &begin_info); - if(result != VK_SUCCESS) { - vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); - return VK_NULL_HANDLE; - } - - return command_buffer; -} - -VkResult command_end_single(VkDevice device, VkCommandBuffer command_buffer, VkCommandPool transfer_pool, Queue transfer_queue) { - VkResult result = vkEndCommandBuffer(command_buffer); - if(result != VK_SUCCESS) { - vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); - return result; - } - - VkSubmitInfo submit_info = { - .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, - .commandBufferCount = 1, - .pCommandBuffers = &command_buffer, - }; - - result = vkQueueSubmit(transfer_queue.handle, 1, &submit_info, 0); - if(result != VK_SUCCESS) { - vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); - return result; - } - - result = vkQueueWaitIdle(transfer_queue.handle); - vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); - return result; -} - -void command_copy_buffer(VkCommandBuffer command_buffer, VkBuffer src, VkBuffer dst, VkDeviceSize src_offset, VkDeviceSize dst_offset, VkDeviceSize size) { - VkBufferCopy copy = { - .srcOffset = src_offset, - .dstOffset = dst_offset, - .size = size, - }; - vkCmdCopyBuffer(command_buffer, src, dst, 1, ©); -} - -VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer_pool, Queue transfer_queue, VkImageLayout old_layout, VkImageLayout new_layout, VkImage image, VkAccessFlags src_mask, VkAccessFlags dst_mask, VkPipelineStageFlags source, VkPipelineStageFlags dest, uint32_t source_family, uint32_t dest_family, VkImageAspectFlags aspect_flags) { - VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); - - VkImageMemoryBarrier barrier = { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .oldLayout = old_layout, - .newLayout = new_layout, - .srcQueueFamilyIndex = source_family, - .dstQueueFamilyIndex = dest_family, - .image = image, - .subresourceRange = { - .aspectMask = aspect_flags, - .levelCount = 1, - .layerCount = 1, - .baseMipLevel = 0, - .baseArrayLayer = 0, - }, - .srcAccessMask = src_mask, - .dstAccessMask = dst_mask, - }; - vkCmdPipelineBarrier(command_buffer, source, dest, 0, 0, 0, 0, 0, 1, &barrier); - - return command_end_single(device, command_buffer, transfer_pool, transfer_queue); -} - diff --git a/client/src/draw.c b/client/src/draw.c new file mode 100644 index 0000000..3d55c8f --- /dev/null +++ b/client/src/draw.c @@ -0,0 +1,170 @@ +#include "draw.h" + +VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILayerStorage* layers, uint32_t layer_count) { + VkResult result; + + result = vkWaitForFences(context->device, 1, &context->in_flight_fences[context->current_frame], VK_TRUE, UINT64_MAX); + if(result != VK_SUCCESS) { + return result; + } + + result = vkResetFences(context->device, 1, &context->in_flight_fences[context->current_frame]); + if(result != VK_SUCCESS) { + return result; + } + + uint32_t image_index; + VkCommandBuffer command_buffer = context->swapchain_command_buffers[context->current_frame]; + result = vkAcquireNextImageKHR(context->device, context->swapchain, UINT64_MAX, context->image_available_semaphores[context->current_frame], VK_NULL_HANDLE, &image_index); + if(result != VK_SUCCESS) { + return result; + } + + result = vkResetCommandBuffer(command_buffer, 0); + if(result != VK_SUCCESS) { + return result; + } + + VkCommandBufferBeginInfo begin_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + }; + result = vkBeginCommandBuffer(command_buffer, &begin_info); + if(result != VK_SUCCESS) { + return result; + } + + VkViewport viewport = { + .width = context->swapchain_extent.width, + .height = context->swapchain_extent.height, + .maxDepth = 1.0f, + .minDepth = 0.0f, + }; + vkCmdSetViewport(command_buffer, 0, 1, &viewport); + + VkRect2D scissor = { + .extent = context->swapchain_extent, + }; + vkCmdSetScissor(command_buffer, 0, 1, &scissor); + + VkClearValue clear_values[2] = {{.color={{0.0f, 0.0f, 0.0f, 0.0f}}}, {.depthStencil={1.0f, 0.0f}}}; + + VkRenderPassBeginInfo render_pass_begin = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .renderPass = context->render_pass, + .framebuffer = context->swapchain_framebuffers[image_index], + .renderArea.offset = {0, 0}, + .renderArea.extent = context->swapchain_extent, + .clearValueCount = 2, + .pClearValues = clear_values, + }; + + VkDeviceAddress push[2] = {ui_context->address, 0}; + + // Compute Pass + vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, ui_context->string_pipeline.pipeline); + for(uint32_t i = 0; i < layer_count; i++) { + push[1] = layers[i].address; + VkBufferMemoryBarrier draw_command_barrier_1 = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .buffer = layers[i].layer, + .offset = offsetof(UILayer, draw), + .size = sizeof(DrawCommand), + .srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + }; + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1, &draw_command_barrier_1, 0, NULL); + command_copy_buffer(command_buffer, layers[i].layer, layers[i].layer, offsetof(UILayer, num_drawables), offsetof(UILayer, draw) + offsetof(DrawCommand, instance_count), sizeof(uint32_t)); + VkBufferMemoryBarrier draw_command_barrier_2 = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .buffer = layers[i].layer, + .offset = offsetof(UILayer, draw), + .size = sizeof(DrawCommand), + .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT, + }; + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, NULL, 1, &draw_command_barrier_2, 0, NULL); + vkCmdPushConstants(command_buffer, ui_context->string_pipeline.layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 16, push); + vkCmdDispatchIndirect(command_buffer, layers[i].layer, offsetof(UILayer, dispatch_strings)); + VkBufferMemoryBarrier draw_command_barrier_3 = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .buffer = layers[i].layer, + .offset = offsetof(UILayer, draw), + .size = sizeof(DrawCommand), + .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, + }; + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0, 0, NULL, 1, &draw_command_barrier_3, 0, NULL); + + VkBufferMemoryBarrier drawables_barrier = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .buffer = layers[i].drawables, + .offset = 0, + .size = sizeof(UIDrawable)*layers[i].data.max_drawables, + .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, + }; + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, NULL, 1, &drawables_barrier, 0, NULL); + } + + + // Render Pass + vkCmdBeginRenderPass(command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); + // World subpass + vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE); + // UI subpass + for(uint32_t i = 0; i < layer_count; i++) { + push[1] = layers[i].address; + vkCmdPushConstants(command_buffer, ui_context->pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, push); + vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.pipeline); + if(i == 0) { + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 0, 1, &ui_context->font_samplers, 0, NULL); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 1, 1, &ui_context->font_textures, 0, NULL); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 2, 1, &ui_context->samplers, 0, NULL); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 3, 1, &ui_context->textures, 0, NULL); + } + vkCmdDrawIndirect(command_buffer, layers[i].layer, offsetof(UILayer, draw), 1, 0); + } + + vkCmdEndRenderPass(command_buffer); + + result = vkEndCommandBuffer(command_buffer); + if(result != VK_SUCCESS) { + return result; + } + + VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + VkSubmitInfo submit_info = { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .waitSemaphoreCount = 1, + .pWaitSemaphores = &context->image_available_semaphores[context->current_frame], + .pWaitDstStageMask = wait_stages, + .commandBufferCount = 1, + .pCommandBuffers = &command_buffer, + .signalSemaphoreCount = 1, + .pSignalSemaphores = &context->render_finished_semaphores[context->current_frame], + }; + + result = vkQueueSubmit(context->graphics_queue.handle, 1, &submit_info, context->in_flight_fences[context->current_frame]); + if(result != VK_SUCCESS) { + return result; + } + + VkPresentInfoKHR present_info = { + .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + .waitSemaphoreCount = 1, + .pWaitSemaphores = &context->render_finished_semaphores[context->current_frame], + .swapchainCount = 1, + .pSwapchains = &context->swapchain, + .pImageIndices = &image_index, + .pResults = 0, + }; + + result = vkQueuePresentKHR(context->present_queue.handle, &present_info); + if(result != VK_SUCCESS) { + return result; + } + + context->current_frame = (context->current_frame + 1) % MAX_FRAMES_IN_FLIGHT; + + return VK_SUCCESS; +} diff --git a/client/src/render.c b/client/src/gpu.c similarity index 84% rename from client/src/render.c rename to client/src/gpu.c index 3471648..92f027c 100644 --- a/client/src/render.c +++ b/client/src/gpu.c @@ -1,4 +1,4 @@ -#include "render.h" +#include "gpu.h" #include "GLFW/glfw3.h" #include "stdio.h" #include "string.h" @@ -978,175 +978,6 @@ VkResult init_vulkan(GLFWwindow* window, RenderContext* context) { return VK_SUCCESS; } -VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILayerStorage* layers, uint32_t layer_count) { - VkResult result; - - result = vkWaitForFences(context->device, 1, &context->in_flight_fences[context->current_frame], VK_TRUE, UINT64_MAX); - if(result != VK_SUCCESS) { - return result; - } - - result = vkResetFences(context->device, 1, &context->in_flight_fences[context->current_frame]); - if(result != VK_SUCCESS) { - return result; - } - - uint32_t image_index; - VkCommandBuffer command_buffer = context->swapchain_command_buffers[context->current_frame]; - result = vkAcquireNextImageKHR(context->device, context->swapchain, UINT64_MAX, context->image_available_semaphores[context->current_frame], VK_NULL_HANDLE, &image_index); - if(result != VK_SUCCESS) { - return result; - } - - result = vkResetCommandBuffer(command_buffer, 0); - if(result != VK_SUCCESS) { - return result; - } - - VkCommandBufferBeginInfo begin_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - }; - result = vkBeginCommandBuffer(command_buffer, &begin_info); - if(result != VK_SUCCESS) { - return result; - } - - VkViewport viewport = { - .width = context->swapchain_extent.width, - .height = context->swapchain_extent.height, - .maxDepth = 1.0f, - .minDepth = 0.0f, - }; - vkCmdSetViewport(command_buffer, 0, 1, &viewport); - - VkRect2D scissor = { - .extent = context->swapchain_extent, - }; - vkCmdSetScissor(command_buffer, 0, 1, &scissor); - - VkClearValue clear_values[2] = {{.color={{0.0f, 0.0f, 0.0f, 0.0f}}}, {.depthStencil={1.0f, 0.0f}}}; - - VkRenderPassBeginInfo render_pass_begin = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = context->render_pass, - .framebuffer = context->swapchain_framebuffers[image_index], - .renderArea.offset = {0, 0}, - .renderArea.extent = context->swapchain_extent, - .clearValueCount = 2, - .pClearValues = clear_values, - }; - - VkDeviceAddress push[2] = {ui_context->address, 0}; - - // Compute Pass - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, ui_context->string_pipeline.pipeline); - for(uint32_t i = 0; i < layer_count; i++) { - push[1] = layers[i].address; - VkBufferMemoryBarrier draw_command_barrier_1 = { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .buffer = layers[i].layer, - .offset = offsetof(UILayer, draw), - .size = sizeof(DrawCommand), - .srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, - .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - }; - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1, &draw_command_barrier_1, 0, NULL); - command_copy_buffer(command_buffer, layers[i].layer, layers[i].layer, offsetof(UILayer, num_drawables), offsetof(UILayer, draw) + offsetof(DrawCommand, instance_count), sizeof(uint32_t)); - VkBufferMemoryBarrier draw_command_barrier_2 = { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .buffer = layers[i].layer, - .offset = offsetof(UILayer, draw), - .size = sizeof(DrawCommand), - .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT, - }; - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, NULL, 1, &draw_command_barrier_2, 0, NULL); - vkCmdPushConstants(command_buffer, ui_context->string_pipeline.layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 16, push); - vkCmdDispatchIndirect(command_buffer, layers[i].layer, offsetof(UILayer, dispatch_strings)); - VkBufferMemoryBarrier draw_command_barrier_3 = { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .buffer = layers[i].layer, - .offset = offsetof(UILayer, draw), - .size = sizeof(DrawCommand), - .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, - }; - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0, 0, NULL, 1, &draw_command_barrier_3, 0, NULL); - - VkBufferMemoryBarrier drawables_barrier = { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .buffer = layers[i].drawables, - .offset = 0, - .size = sizeof(UIDrawable)*layers[i].data.max_drawables, - .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, - }; - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, NULL, 1, &drawables_barrier, 0, NULL); - } - - - // Render Pass - vkCmdBeginRenderPass(command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); - // World subpass - vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE); - // UI subpass - for(uint32_t i = 0; i < layer_count; i++) { - push[1] = layers[i].address; - vkCmdPushConstants(command_buffer, ui_context->pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, push); - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.pipeline); - if(i == 0) { - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 0, 1, &ui_context->font_samplers, 0, NULL); - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 1, 1, &ui_context->font_textures, 0, NULL); - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 2, 1, &ui_context->samplers, 0, NULL); - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 3, 1, &ui_context->textures, 0, NULL); - } - vkCmdDrawIndirect(command_buffer, layers[i].layer, offsetof(UILayer, draw), 1, 0); - } - - vkCmdEndRenderPass(command_buffer); - - result = vkEndCommandBuffer(command_buffer); - if(result != VK_SUCCESS) { - return result; - } - - VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; - VkSubmitInfo submit_info = { - .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, - .waitSemaphoreCount = 1, - .pWaitSemaphores = &context->image_available_semaphores[context->current_frame], - .pWaitDstStageMask = wait_stages, - .commandBufferCount = 1, - .pCommandBuffers = &command_buffer, - .signalSemaphoreCount = 1, - .pSignalSemaphores = &context->render_finished_semaphores[context->current_frame], - }; - - result = vkQueueSubmit(context->graphics_queue.handle, 1, &submit_info, context->in_flight_fences[context->current_frame]); - if(result != VK_SUCCESS) { - return result; - } - - VkPresentInfoKHR present_info = { - .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, - .waitSemaphoreCount = 1, - .pWaitSemaphores = &context->render_finished_semaphores[context->current_frame], - .swapchainCount = 1, - .pSwapchains = &context->swapchain, - .pImageIndices = &image_index, - .pResults = 0, - }; - - result = vkQueuePresentKHR(context->present_queue.handle, &present_info); - if(result != VK_SUCCESS) { - return result; - } - - context->current_frame = (context->current_frame + 1) % MAX_FRAMES_IN_FLIGHT; - - return VK_SUCCESS; -} - VkResult create_transfer_buffer( VmaAllocator allocator, VkDeviceSize size, @@ -1212,3 +1043,90 @@ VkDeviceAddress buffer_address(VkDevice device, VkBuffer buffer) { }; return vkGetBufferDeviceAddress(device, &info); } + +VkCommandBuffer command_begin_single(VkDevice device, VkCommandPool transfer_pool) { + VkCommandBufferAllocateInfo command_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandPool = transfer_pool, + .commandBufferCount = 1, + }; + + VkCommandBuffer command_buffer; + VkResult result = vkAllocateCommandBuffers(device, &command_info, &command_buffer); + if(result != VK_SUCCESS) { + return VK_NULL_HANDLE; + } + + VkCommandBufferBeginInfo begin_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, + }; + + result = vkBeginCommandBuffer(command_buffer, &begin_info); + if(result != VK_SUCCESS) { + vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); + return VK_NULL_HANDLE; + } + + return command_buffer; +} + +VkResult command_end_single(VkDevice device, VkCommandBuffer command_buffer, VkCommandPool transfer_pool, Queue transfer_queue) { + VkResult result = vkEndCommandBuffer(command_buffer); + if(result != VK_SUCCESS) { + vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); + return result; + } + + VkSubmitInfo submit_info = { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .commandBufferCount = 1, + .pCommandBuffers = &command_buffer, + }; + + result = vkQueueSubmit(transfer_queue.handle, 1, &submit_info, 0); + if(result != VK_SUCCESS) { + vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); + return result; + } + + result = vkQueueWaitIdle(transfer_queue.handle); + vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); + return result; +} + +void command_copy_buffer(VkCommandBuffer command_buffer, VkBuffer src, VkBuffer dst, VkDeviceSize src_offset, VkDeviceSize dst_offset, VkDeviceSize size) { + VkBufferCopy copy = { + .srcOffset = src_offset, + .dstOffset = dst_offset, + .size = size, + }; + vkCmdCopyBuffer(command_buffer, src, dst, 1, ©); +} + +VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer_pool, Queue transfer_queue, VkImageLayout old_layout, VkImageLayout new_layout, VkImage image, VkAccessFlags src_mask, VkAccessFlags dst_mask, VkPipelineStageFlags source, VkPipelineStageFlags dest, uint32_t source_family, uint32_t dest_family, VkImageAspectFlags aspect_flags) { + VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); + + VkImageMemoryBarrier barrier = { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .oldLayout = old_layout, + .newLayout = new_layout, + .srcQueueFamilyIndex = source_family, + .dstQueueFamilyIndex = dest_family, + .image = image, + .subresourceRange = { + .aspectMask = aspect_flags, + .levelCount = 1, + .layerCount = 1, + .baseMipLevel = 0, + .baseArrayLayer = 0, + }, + .srcAccessMask = src_mask, + .dstAccessMask = dst_mask, + }; + vkCmdPipelineBarrier(command_buffer, source, dest, 0, 0, 0, 0, 0, 1, &barrier); + + return command_end_single(device, command_buffer, transfer_pool, transfer_queue); +} + diff --git a/client/src/main.c b/client/src/main.c index 2b7ffc9..b92b296 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -1,7 +1,8 @@ -#include "command.h" -#include "render.h" -#include "arpa/inet.h" #include "ui.h" +#include "gpu.h" +#include "draw.h" + +#include "arpa/inet.h" #include "vk_mem_alloc.h" #include "vulkan/vk_enum_string_helper.h" #include "vulkan/vulkan_core.h" @@ -28,29 +29,23 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render) { VkResult result; VK_RESULT(create_ui_context( - render->device, - render->allocator, - render->render_pass, 10, 10, - render->swapchain_extent, - render->window_scale, - render->transfer_pool, - render->transfer_queue, + render, &ui)); if(FT_Init_FreeType(&library) != FT_Err_Ok) { return VK_ERROR_UNKNOWN; } - VK_RESULT(load_font(render->device, render->allocator, &ui, render->transfer_pool, render->transfer_queue, library, "test.ttf", 16, VK_TRUE, &font_index, &font)); + VK_RESULT(load_font("test.ttf", 16, VK_TRUE, library, render, &ui, &font_index, &font)); - VK_RESULT(load_texture(render->device, render->allocator, &ui, render->transfer_pool, render->transfer_queue, "test.png", &texture_index, &texture)); + VK_RESULT(load_texture("test.png", render, &ui, &texture_index, &texture)); - VK_RESULT(create_container(0, 0, 200, 200, render->device, render->allocator, render->transfer_pool, render->transfer_queue, &container)); + VK_RESULT(create_container(0, 0, 200, 200, render, &container)); - VK_RESULT(create_layer(10, 100, 10, font_index, render->device, render->allocator, render->transfer_pool, render->transfer_queue, &container, &layers[0])); - VK_RESULT(create_layer(10, 100, 10, font_index, render->device, render->allocator, render->transfer_pool, render->transfer_queue, &container, &layers[1])); + VK_RESULT(create_layer(10, 100, 10, font_index, render, &container, &layers[0])); + VK_RESULT(create_layer(10, 100, 10, font_index, render, &container, &layers[1])); VK_RESULT(create_transfer_buffer(render->allocator, 2*sizeof(uint32_t) + 2*sizeof(UIDrawable) + sizeof(UIString) + 100*sizeof(uint32_t), &transfer, &transfer_memory, &mapped)); diff --git a/client/src/ui.c b/client/src/ui.c index da0627e..ad574f6 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -1,8 +1,8 @@ #include "ui.h" +#include "gpu.h" + #include "cglm/affine.h" #include "cglm/mat4.h" -#include "command.h" -#include "render.h" #include "stdio.h" #include "stdlib.h" #include "string.h" @@ -279,19 +279,16 @@ VkResult create_container( float y, float width, float height, - VkDevice device, - VmaAllocator allocator, - VkCommandPool transfer_pool, - Queue transfer_queue, + RenderContext* gpu, UIContainerStorage* memory) { VkResult result; - VK_RESULT(create_storage_buffer(allocator, 0, sizeof(UIContainer), &memory->container, &memory->container_memory)); + VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(UIContainer), &memory->container, &memory->container_memory)); VkBuffer transfer; VmaAllocation transfer_memory; void* mapped; - VK_RESULT(create_transfer_buffer(allocator, sizeof(UIContainer), &transfer, &transfer_memory, &mapped)); + VK_RESULT(create_transfer_buffer(gpu->allocator, sizeof(UIContainer), &transfer, &transfer_memory, &mapped)); memory->data.pos[0] = x; memory->data.pos[1] = y; @@ -299,12 +296,12 @@ VkResult create_container( memory->data.size[1] = height; memcpy(mapped, &memory->data, sizeof(UIContainer)); - VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); + VkCommandBuffer command_buffer = command_begin_single(gpu->device, gpu->transfer_pool); command_copy_buffer(command_buffer, transfer, memory->container, 0, 0, sizeof(UIContainer)); - VK_RESULT(command_end_single(device, command_buffer, transfer_pool, transfer_queue)); - destroy_transfer_buffer(allocator, transfer, transfer_memory); + VK_RESULT(command_end_single(gpu->device, command_buffer, gpu->transfer_pool, gpu->transfer_queue)); + destroy_transfer_buffer(gpu->allocator, transfer, transfer_memory); - memory->address = buffer_address(device, memory->container); + memory->address = buffer_address(gpu->device, memory->container); return VK_SUCCESS; } @@ -314,28 +311,25 @@ VkResult create_layer( uint32_t max_codes, uint32_t max_drawables, uint32_t font_index, - VkDevice device, - VmaAllocator allocator, - VkCommandPool transfer_pool, - Queue transfer_queue, + RenderContext* gpu, UIContainerStorage* container, UILayerStorage* memory) { VkResult result; - VK_RESULT(create_storage_buffer(allocator, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, sizeof(UILayer), &memory->layer, &memory->layer_memory)); - VK_RESULT(create_storage_buffer(allocator, 0, sizeof(UIString)*max_strings, &memory->strings, &memory->strings_memory)) - VK_RESULT(create_storage_buffer(allocator, 0, sizeof(UIDrawable)*(max_drawables + max_codes), &memory->drawables, &memory->drawables_memory)); - VK_RESULT(create_storage_buffer(allocator, 0, sizeof(uint32_t)*max_codes, &memory->codes, &memory->codes_memory)); + VK_RESULT(create_storage_buffer(gpu->allocator, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, sizeof(UILayer), &memory->layer, &memory->layer_memory)); + VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(UIString)*max_strings, &memory->strings, &memory->strings_memory)) + VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(UIDrawable)*(max_drawables + max_codes), &memory->drawables, &memory->drawables_memory)); + VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(uint32_t)*max_codes, &memory->codes, &memory->codes_memory)); VkBuffer transfer; VmaAllocation transfer_memory; void* mapped; - VK_RESULT(create_transfer_buffer(allocator, sizeof(UILayer), &transfer, &transfer_memory, &mapped)); + VK_RESULT(create_transfer_buffer(gpu->allocator, sizeof(UILayer), &transfer, &transfer_memory, &mapped)); - memory->data.strings = buffer_address(device, memory->strings); - memory->data.codes = buffer_address(device, memory->codes); + memory->data.strings = buffer_address(gpu->device, memory->strings); + memory->data.codes = buffer_address(gpu->device, memory->codes); - memory->data.drawables = buffer_address(device, memory->drawables); + memory->data.drawables = buffer_address(gpu->device, memory->drawables); memory->data.draw.first_vertex = 0; memory->data.draw.vertex_count = 6; @@ -353,27 +347,24 @@ VkResult create_layer( memory->data.container = container->address; memcpy(mapped, &memory->data, sizeof(UILayer)); - VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); + VkCommandBuffer command_buffer = command_begin_single(gpu->device, gpu->transfer_pool); command_copy_buffer(command_buffer, transfer, memory->layer, 0, 0, sizeof(UILayer)); vkCmdFillBuffer(command_buffer, memory->strings, 0, sizeof(UIString)*max_strings, 0x00000000); vkCmdFillBuffer(command_buffer, memory->drawables, 0, sizeof(UIDrawable)*max_drawables, 0x00000000); vkCmdFillBuffer(command_buffer, memory->codes, 0, sizeof(uint32_t)*max_codes, 0x00000000); - VK_RESULT(command_end_single(device, command_buffer, transfer_pool, transfer_queue)); - vkQueueWaitIdle(transfer_queue.handle); - destroy_transfer_buffer(allocator, transfer, transfer_memory); + VK_RESULT(command_end_single(gpu->device, command_buffer, gpu->transfer_pool, gpu->transfer_queue)); + vkQueueWaitIdle(gpu->transfer_queue.handle); + destroy_transfer_buffer(gpu->allocator, transfer, transfer_memory); - memory->address = buffer_address(device, memory->layer); + memory->address = buffer_address(gpu->device, memory->layer); return VK_SUCCESS; } VkResult load_texture( - VkDevice device, - VmaAllocator allocator, - UIContextStorage* context, - VkCommandPool transfer_pool, - Queue transfer_queue, const char* png_path, + RenderContext* gpu, + UIContextStorage* context, uint32_t* index, TextureStorage* memory) { *index = 0xFFFFFFFF; @@ -464,10 +455,10 @@ VkResult load_texture( VmaAllocation transfer_memory; void* mapped; - VK_RESULT(vmaCreateImage(allocator, &image_info, &memory_info, &memory->image, &memory->image_memory, NULL)); - VK_RESULT(create_transfer_buffer(allocator, sizeof(uint32_t)*ihdr.width*ihdr.height, &transfer, &transfer_memory, &mapped)); + VK_RESULT(vmaCreateImage(gpu->allocator, &image_info, &memory_info, &memory->image, &memory->image_memory, NULL)); + VK_RESULT(create_transfer_buffer(gpu->allocator, sizeof(uint32_t)*ihdr.width*ihdr.height, &transfer, &transfer_memory, &mapped)); memcpy(mapped, image_buffer, sizeof(uint32_t)*ihdr.height*ihdr.width); - VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); + VkCommandBuffer command_buffer = command_begin_single(gpu->device, gpu->transfer_pool); VkImageMemoryBarrier first_barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, @@ -515,9 +506,9 @@ VkResult load_texture( vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, &second_barrier); - VK_RESULT(command_end_single(device, command_buffer, transfer_pool, transfer_queue)); - vkQueueWaitIdle(transfer_queue.handle); - destroy_transfer_buffer(allocator, transfer, transfer_memory); + VK_RESULT(command_end_single(gpu->device, command_buffer, gpu->transfer_pool, gpu->transfer_queue)); + vkQueueWaitIdle(gpu->transfer_queue.handle); + destroy_transfer_buffer(gpu->allocator, transfer, transfer_memory); free(image_buffer); free(png); spng_ctx_free(spng); @@ -534,7 +525,7 @@ VkResult load_texture( }, }; - VK_RESULT(vkCreateImageView(device, &view_info, NULL, &memory->view)); + VK_RESULT(vkCreateImageView(gpu->device, &view_info, NULL, &memory->view)); VkSamplerCreateInfo sampler_info = { .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, @@ -545,7 +536,7 @@ VkResult load_texture( .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT, }; - VK_RESULT(vkCreateSampler(device, &sampler_info, NULL, &memory->sampler)); + VK_RESULT(vkCreateSampler(gpu->device, &sampler_info, NULL, &memory->sampler)); VkDescriptorImageInfo desc_sampler_info = { .sampler = memory->sampler, @@ -577,23 +568,20 @@ VkResult load_texture( }, }; - vkUpdateDescriptorSets(device, sizeof(desc_writes)/sizeof(VkWriteDescriptorSet), desc_writes, 0, NULL); + vkUpdateDescriptorSets(gpu->device, sizeof(desc_writes)/sizeof(VkWriteDescriptorSet), desc_writes, 0, NULL); return VK_SUCCESS; } VkResult load_font( - VkDevice device, - VmaAllocator allocator, - UIContextStorage* context, - VkCommandPool transfer_pool, - Queue transfer_queue, - FT_Library library, const char* ttf_file, uint32_t size, VkBool32 antialias, + FT_Library library, + RenderContext* gpu, + UIContextStorage* context, uint32_t* index, - FontStorage* memory) { + FontStorage* memory){ FT_Face face; int error; @@ -690,7 +678,7 @@ VkResult load_font( } VkResult result; - VK_RESULT(create_storage_buffer(allocator, 0, sizeof(SymbolInfo)*info.num_symbols, &memory->symbols, &memory->symbol_memory)); + VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(SymbolInfo)*info.num_symbols, &memory->symbols, &memory->symbol_memory)); VkImageCreateInfo image_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, @@ -711,14 +699,14 @@ VkResult load_font( .usage = VMA_MEMORY_USAGE_GPU_ONLY, }; - VK_RESULT(vmaCreateImage(allocator, &image_info, &image_memory_info, &memory->image, &memory->image_memory, NULL)); + VK_RESULT(vmaCreateImage(gpu->allocator, &image_info, &image_memory_info, &memory->image, &memory->image_memory, NULL)); VkBuffer transfer; VmaAllocation transfer_memory; void* mapped; - VK_RESULT(create_transfer_buffer(allocator, sizeof(Font) + image_size*info.num_symbols + sizeof(SymbolInfo)*info.num_symbols, &transfer, &transfer_memory, &mapped)); + VK_RESULT(create_transfer_buffer(gpu->allocator, sizeof(Font) + image_size*info.num_symbols + sizeof(SymbolInfo)*info.num_symbols, &transfer, &transfer_memory, &mapped)); - info.symbol_list = buffer_address(device, memory->symbols); + info.symbol_list = buffer_address(gpu->device, memory->symbols); memcpy(mapped, images, image_size*info.num_symbols); memcpy(mapped + image_size*info.num_symbols, &info, sizeof(Font)); @@ -727,7 +715,7 @@ VkResult load_font( free(images); free(symbols); - VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); + VkCommandBuffer command_buffer = command_begin_single(gpu->device, gpu->transfer_pool); command_copy_buffer(command_buffer, transfer, context->font_infos, image_size*info.num_symbols, *index*sizeof(Font), sizeof(Font)); command_copy_buffer(command_buffer, transfer, memory->symbols, image_size*info.num_symbols + sizeof(Font), 0, sizeof(SymbolInfo)*info.num_symbols); @@ -768,12 +756,9 @@ VkResult load_font( }; vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, &second_barrier); - result = command_end_single(device, command_buffer, transfer_pool, transfer_queue); - if(result != VK_SUCCESS) { - return result; - } - vkQueueWaitIdle(transfer_queue.handle); - destroy_transfer_buffer(allocator, transfer, transfer_memory); + VK_RESULT(command_end_single(gpu->device, command_buffer, gpu->transfer_pool, gpu->transfer_queue)); + vkQueueWaitIdle(gpu->transfer_queue.handle); + destroy_transfer_buffer(gpu->allocator, transfer, transfer_memory); VkImageViewCreateInfo view_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, @@ -788,10 +773,7 @@ VkResult load_font( .baseArrayLayer = 0, }, }; - result = vkCreateImageView(device, &view_info, NULL, &memory->view); - if(result != VK_SUCCESS) { - return result; - } + VK_RESULT(vkCreateImageView(gpu->device, &view_info, NULL, &memory->view)) VkSamplerCreateInfo sampler_info = { .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, @@ -801,10 +783,7 @@ VkResult load_font( .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT, .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT, }; - result = vkCreateSampler(device, &sampler_info, NULL, &memory->sampler); - if(result != VK_SUCCESS) { - return result; - } + VK_RESULT(vkCreateSampler(gpu->device, &sampler_info, NULL, &memory->sampler)); VkDescriptorImageInfo desc_sampler_info = { .sampler = memory->sampler, @@ -836,7 +815,7 @@ VkResult load_font( }, }; - vkUpdateDescriptorSets(device, sizeof(descriptor_writes)/sizeof(VkWriteDescriptorSet), descriptor_writes, 0, NULL); + vkUpdateDescriptorSets(gpu->device, sizeof(descriptor_writes)/sizeof(VkWriteDescriptorSet), descriptor_writes, 0, NULL); return VK_SUCCESS; } @@ -1023,44 +1002,38 @@ VkResult create_ui_descriptor( } VkResult create_ui_context( - VkDevice device, - VmaAllocator allocator, - VkRenderPass render_pass, uint32_t max_fonts, uint32_t max_textures, - VkExtent2D swapchain_extent, - vec2 window_scale, - VkCommandPool transfer_pool, - Queue transfer_queue, + RenderContext* gpu, UIContextStorage* memory) { VkResult result; - VK_RESULT(create_storage_buffer(allocator, 0, sizeof(UIContext), &memory->context, &memory->context_memory)); - VK_RESULT(create_storage_buffer(allocator, 0, sizeof(Font)*max_fonts, &memory->font_infos, &memory->font_infos_memory)); + VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(UIContext), &memory->context, &memory->context_memory)); + VK_RESULT(create_storage_buffer(gpu->allocator, 0, sizeof(Font)*max_fonts, &memory->font_infos, &memory->font_infos_memory)); VkBuffer transfer; VmaAllocation transfer_memory; UIContext* mapped; - VK_RESULT(create_transfer_buffer(allocator, sizeof(UIContext), &transfer, &transfer_memory, (void**)&mapped)); + VK_RESULT(create_transfer_buffer(gpu->allocator, sizeof(UIContext), &transfer, &transfer_memory, (void**)&mapped)); - memory->data.font_infos = buffer_address(device, memory->font_infos); - memory->data.screen[0] = window_scale[0] / swapchain_extent.width; - memory->data.screen[1] = window_scale[1] / swapchain_extent.height; - memory->data.scale[0] = window_scale[0]; - memory->data.scale[1] = window_scale[1]; + memory->data.font_infos = buffer_address(gpu->device, memory->font_infos); + memory->data.screen[0] = gpu->window_scale[0] / gpu->swapchain_extent.width; + memory->data.screen[1] = gpu->window_scale[1] / gpu->swapchain_extent.height; + memory->data.scale[0] = gpu->window_scale[0]; + memory->data.scale[1] = gpu->window_scale[1]; memcpy(mapped, &memory->data, sizeof(UIContext)); - VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); + VkCommandBuffer command_buffer = command_begin_single(gpu->device, gpu->transfer_pool); command_copy_buffer(command_buffer, transfer, memory->context, 0, 0, sizeof(UIContext)); - VK_RESULT(command_end_single(device, command_buffer, transfer_pool, transfer_queue)); - destroy_transfer_buffer(allocator, transfer, transfer_memory); - memory->address = buffer_address(device, memory->context); + VK_RESULT(command_end_single(gpu->device, command_buffer, gpu->transfer_pool, gpu->transfer_queue)); + destroy_transfer_buffer(gpu->allocator, transfer, transfer_memory); + memory->address = buffer_address(gpu->device, memory->context); - VK_RESULT(create_ui_descriptor(device, max_fonts, max_textures, &memory->samplers_layout, &memory->textures_layout, &memory->samplers, &memory->textures, &memory->font_samplers, &memory->font_textures, &memory->fonts_pool, &memory->textures_pool)); + VK_RESULT(create_ui_descriptor(gpu->device, max_fonts, max_textures, &memory->samplers_layout, &memory->textures_layout, &memory->samplers, &memory->textures, &memory->font_samplers, &memory->font_textures, &memory->fonts_pool, &memory->textures_pool)); - VK_RESULT(create_ui_pipeline(device, render_pass, memory->samplers_layout, memory->textures_layout, &memory->pipeline, &memory->string_pipeline)); + VK_RESULT(create_ui_pipeline(gpu->device, gpu->render_pass, memory->samplers_layout, memory->textures_layout, &memory->pipeline, &memory->string_pipeline)); memory->max_textures = max_textures; memory->max_fonts = max_fonts;