diff --git a/client/include/command.h b/client/include/command.h index 88a79e0..ff4838c 100644 --- a/client/include/command.h +++ b/client/include/command.h @@ -14,6 +14,8 @@ VkCommandBuffer command_begin_single(VkDevice device, VkCommandPool transfer_poo 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/render.h b/client/include/render.h index 11ada1d..da94c26 100644 --- a/client/include/render.h +++ b/client/include/render.h @@ -27,6 +27,13 @@ #include "ui.h" #include "command.h" +#define VK_RESULT(x) {\ + result = x;\ + if(result != VK_SUCCESS) {\ + return x;\ + }\ +} + extern const uint32_t MAX_FRAMES_IN_FLIGHT; typedef struct SwapchainDetailsStruct { @@ -97,10 +104,26 @@ VkResult draw_frame( uint32_t ui_layer_count); VkResult create_transfer_buffer( - VkDeviceSize size, VmaAllocator allocator, + VkDeviceSize size, VkBuffer* buffer, VmaAllocation* memory, void** mapped); +void destroy_transfer_buffer( + VmaAllocator allocator, + VkBuffer buffer, + VmaAllocation memory); + +VkResult create_storage_buffer( + VmaAllocator allocator, + VkBufferUsageFlags usage, + VkDeviceSize size, + VkBuffer* buffer, + VmaAllocation* memory); + +VkDeviceAddress buffer_address( + VkDevice device, + VkBuffer buffer); + #endif diff --git a/client/include/ui.h b/client/include/ui.h index 278b63e..e29ec04 100644 --- a/client/include/ui.h +++ b/client/include/ui.h @@ -19,22 +19,6 @@ typedef struct GraphicsPipelineStruct { VkPipeline pipeline; } GraphicsPipeline; -typedef struct UIRectStruct { - vec3 pos; - float pad0; - vec2 size; - vec4 color; -} UIRect; - -typedef struct StringStruct { - vec3 pos; - float pad0; - vec4 color; - float size; - uint32_t offset; - uint32_t length; -} String; - typedef struct DrawCommandStruct { uint32_t vertex_count; uint32_t instance_count; @@ -48,14 +32,6 @@ typedef struct DispatchCommandStruct { uint32_t z; } DispatchCommand; -typedef struct CharacterStruct { - vec3 pos; - float pad0; - vec4 color; - float size; - uint32_t code; -} Character; - typedef struct FontStruct { uint32_t num_symbols; uint32_t width; @@ -78,33 +54,42 @@ typedef struct FontStorageStruct { VkImage image; VkImageView view; VkSampler sampler; + uint32_t* charmap; + uint32_t num_symbols; uint32_t index; } FontStorage; -typedef struct TextPointersMemoryStruct { - VmaAllocation pointers_memory; - VmaAllocation draw_memory; - VmaAllocation strings_memory; - VmaAllocation codes_memory; - VmaAllocation characters_memory; +typedef struct UIRectStruct { + vec2 pos; + vec2 size; + vec4 color; +} UIRect; - VkBuffer pointers_buffer; - VkBuffer draw_buffer; - VkBuffer strings_buffer; - VkBuffer codes_buffer; - VkBuffer characters_buffer; -} TextPointersMemory; +typedef struct UIStringStruct { + vec2 pos; + vec4 color; + float size; + uint32_t offset; + uint32_t length; +} UIString; + +typedef struct UIGlyphStruct { + vec2 pos; + vec4 color; + float size; + uint32_t code; +} UIGlyph; typedef struct UIlayerStorageStruct { VkBuffer strings; - VkBuffer chars; + VkBuffer glyphs; VkBuffer codes; VkBuffer rects; VkBuffer layer; VmaAllocation strings_memory; VmaAllocation rects_memory; - VmaAllocation chars_memory; + VmaAllocation glyphs_memory; VmaAllocation codes_memory; VmaAllocation layer_memory; @@ -112,13 +97,13 @@ typedef struct UIlayerStorageStruct { } UILayerStorage; typedef struct UILayerStruct { - VkDeviceAddress rects; - uint32_t rect_count; - VkDeviceAddress strings; - uint32_t font_index; + VkDeviceAddress codes; - DrawCommand draw_chars; + VkDeviceAddress rects; + VkDeviceAddress glyphs; + + DrawCommand draw_glyphs; DrawCommand draw_rects; DispatchCommand dispatch_strings; } UILayer; @@ -152,6 +137,11 @@ VkResult create_ui_context( VkDevice device, VmaAllocator allocator, VkRenderPass render_pass, + uint32_t max_fonts, + VkExtent2D swapchain_extent, + vec2 window_scale, + VkCommandPool transfer_pool, + Queue transfer_queue, UIContextStorage* memory); VkResult load_font( @@ -167,7 +157,6 @@ VkResult load_font( const char* ttf_file, uint32_t size, VkBool32 antialias, - uint32_t** charmap, FontStorage* memory); VkResult create_layer( @@ -178,6 +167,5 @@ VkResult create_layer( VmaAllocator allocator, VkCommandPool transfer_pool, Queue transfer_queue, - UILayerStorage* memory, - VkDeviceAddress* address); + UILayerStorage* memory); #endif diff --git a/client/shader_src/ui_rect.vert b/client/shader_src/ui_rect.vert index 4afbb78..0b7b479 100644 --- a/client/shader_src/ui_rect.vert +++ b/client/shader_src/ui_rect.vert @@ -1,8 +1,30 @@ #version 450 #extension GL_EXT_buffer_reference : require +struct String { + vec2 pos; + vec4 color; + float size; + uint code; +}; + +layout(std430, buffer_reference) readonly buffer StringList { + String s[]; +}; + +struct Glyph { + vec2 pos; + vec4 color; + float size; + uint code; +}; + +layout(std430, buffer_reference) readonly buffer GlyphList { + Glyph g[]; +}; + struct Rect { - vec3 pos; + vec2 pos; vec2 size; vec4 color; }; @@ -11,13 +33,69 @@ layout(std430, buffer_reference) readonly buffer RectList { Rect r[]; }; -layout(std430, buffer_reference) readonly buffer ScreenInfo { - mat4 bounds; +layout(std430, buffer_reference) readonly buffer CodeList { + uint c[]; }; -layout(std430, push_constant) uniform PushConstant { - ScreenInfo screen; +struct DrawCommand { + uint vertex_count; + uint instance_count; + uint fist_vertex; + uint first_instance; +}; + +struct DispatchCommand { + uint x; + uint y; + uint z; +}; + +layout(std430, buffer_reference) buffer UILayer { + StringList strings; + CodeList codes; + RectList rects; + GlyphList glyphs; + + DrawCommand draw_glyphs; + DrawCommand draw_rects; + + DispatchCommand dispatch_strings; +}; + +struct Symbol { + int top; + uint left; + uint width; + uint height; + uint advance; +}; + +layout(std430, buffer_reference) buffer SymbolList { + Symbol s[]; +}; + + +struct Font { + uint num_symbols; + uint width; + uint height; + SymbolList symbols; +}; + + +layout(std430, buffer_reference) buffer FontList { + Font f[]; +}; + +layout(std430, buffer_reference) buffer UIContext { + mat4 screen; + FontList fonts; +}; + +layout(std430, push_constant) uniform PushConstant { + UIContext context; + UILayer layer; } pc; layout(location = 0) out vec4 fragColor; @@ -32,8 +110,8 @@ const vec2 square[6] = { }; void main() { - Rect rect = pc.rects.r[gl_InstanceIndex]; - gl_Position = pc.screen.bounds * vec4(vec3(square[gl_VertexIndex] * rect.size, 0.0) + rect.pos.xyz, 1.0); + Rect rect = pc.layer.rects.r[gl_InstanceIndex]; + gl_Position = pc.context.screen * vec4(square[gl_VertexIndex] * rect.size + rect.pos, 0.0, 1.0); fragColor = rect.color; } diff --git a/client/shader_src/ui_text.frag b/client/shader_src/ui_text.frag index 813decd..66b4f28 100644 --- a/client/shader_src/ui_text.frag +++ b/client/shader_src/ui_text.frag @@ -1,8 +1,8 @@ #version 450 #extension GL_EXT_nonuniform_qualifier : enable -layout(set = 0, binding = 0) uniform sampler font_samplers[]; -layout(set = 1, binding = 0) uniform texture2DArray font_textures[]; +//layout(set = 0, binding = 0) uniform sampler font_samplers[]; +//layout(set = 1, binding = 0) uniform texture2DArray font_textures[]; layout(location = 0) in vec4 fragColor; layout(location = 1) in vec2 fragUV; @@ -11,6 +11,7 @@ layout(location = 2) flat in uint code; layout(location = 0) out vec4 outColor; void main() { - outColor = fragColor * texture(sampler2DArray(font_textures[0], font_samplers[0]), vec3(fragUV, code)); + //outColor = fragColor * texture(sampler2DArray(font_textures[0], font_samplers[0]), vec3(fragUV, code)); + outColor = vec4(1.0, 1.0, 1.0, 1.0); } diff --git a/client/src/command.c b/client/src/command.c index 73f9986..a9d457e 100644 --- a/client/src/command.c +++ b/client/src/command.c @@ -52,6 +52,15 @@ VkResult command_end_single(VkDevice device, VkCommandBuffer command_buffer, VkC 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); diff --git a/client/src/main.c b/client/src/main.c index a7df5d6..cbf78c5 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -1,3 +1,4 @@ +#include "command.h" #include "render.h" #include "arpa/inet.h" #include "ui.h" @@ -9,38 +10,61 @@ #include FT_FREETYPE_H VkResult render_thread(GLFWwindow* window, RenderContext* render_context) { - VkResult result; - UIContextStorage ui; FT_Library library; + + UIContextStorage ui; + UILayerStorage layer; + FontStorage font; - uint32_t* charmap; - VkBuffer temp_buffer; - VmaAllocation temp_memory; + + VkBuffer transfer; + VmaAllocation transfer_memory; void* mapped; - UILayerStorage layer = {}; - result = create_ui_context(render_context->device, render_context->allocator, render_context->render_pass, &ui); - if(result != VK_SUCCESS) { - return result; - } + VkResult result; + + VK_RESULT(create_ui_context( + render_context->device, + render_context->allocator, + render_context->render_pass, + 10, + render_context->swapchain_extent, + render_context->window_scale, + render_context->transfer_pool, + render_context->transfer_queue, + &ui)); if(FT_Init_FreeType(&library) != FT_Err_Ok) { return VK_ERROR_UNKNOWN; } - result = load_font(render_context->device, render_context->allocator, ui.font_infos, ui.font_samplers, ui.font_textures, 0, render_context->transfer_pool, render_context->transfer_queue, library, "test.ttf", 16, VK_TRUE, &charmap, &font); - if(result != VK_SUCCESS) { - return result; - } + VK_RESULT(load_font(render_context->device, render_context->allocator, ui.font_infos, ui.font_samplers, ui.font_textures, 0, render_context->transfer_pool, render_context->transfer_queue, library, "test.ttf", 16, VK_TRUE, &font)); - result = create_transfer_buffer(2*sizeof(String) + 100*sizeof(uint32_t), render_context->allocator, &temp_buffer, &temp_memory, (void**)&mapped); - if(result != VK_SUCCESS) { - return result; - } + VK_RESULT(create_layer(10, 100, 10, render_context->device, render_context->allocator, render_context->transfer_pool, render_context->transfer_queue, &layer)); + VK_RESULT(create_transfer_buffer(render_context->allocator, sizeof(uint32_t) + sizeof(UIRect), &transfer, &transfer_memory, &mapped)); + + uint32_t* mapped_count = (uint32_t*)(mapped); + *mapped_count = 1; + UIRect* mapped_rect = (UIRect*)(mapped + sizeof(uint32_t)); + mapped_rect->pos[0] = 0.0; + mapped_rect->pos[1] = 0.0; + mapped_rect->size[0] = 200.0; + mapped_rect->size[1] = 200.0; + mapped_rect->color[0] = 1.0; + mapped_rect->color[1] = 0.0; + mapped_rect->color[2] = 0.0; + mapped_rect->color[3] = 1.0; + + VkCommandBuffer command_buffer = command_begin_single(render_context->device, render_context->transfer_pool); + command_copy_buffer(command_buffer, transfer, layer.layer, 0, offsetof(UILayer, draw_rects) + offsetof(DrawCommand, instance_count), sizeof(uint32_t)); + command_copy_buffer(command_buffer, transfer, layer.rects, sizeof(uint32_t), 0, sizeof(UIRect)); + VK_RESULT(command_end_single(render_context->device, command_buffer, render_context->transfer_pool, render_context->transfer_queue)); vkQueueWaitIdle(render_context->transfer_queue.handle); - vmaUnmapMemory(render_context->allocator, temp_memory); - vmaDestroyBuffer(render_context->allocator, temp_buffer, temp_memory); + destroy_transfer_buffer(render_context->allocator, transfer, transfer_memory); + + fprintf(stderr, "%ld\n", sizeof(UILayer)); + fprintf(stderr, "%ld\n", sizeof(UIRect)); while(glfwWindowShouldClose(window) == 0) { glfwPollEvents(); diff --git a/client/src/render.c b/client/src/render.c index a00a2bc..025aaeb 100644 --- a/client/src/render.c +++ b/client/src/render.c @@ -1051,15 +1051,15 @@ VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILaye // World subpass vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE); // UI subpass - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->rect_pipeline.layout, 0, 1, &ui_context->font_samplers, 0, NULL); - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->rect_pipeline.layout, 1, 1, &ui_context->font_textures, 0, NULL); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->char_pipeline.layout, 0, 1, &ui_context->font_samplers, 0, NULL); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->char_pipeline.layout, 1, 1, &ui_context->font_textures, 0, NULL); for(uint32_t i = 0; i < ui_layer_count; i++) { push[1] = ui_layers[i].address; - vkCmdPushConstants(command_buffer, ui_context->rect_pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 16, push); + vkCmdPushConstants(command_buffer, ui_context->rect_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->rect_pipeline.pipeline); vkCmdDrawIndirect(command_buffer, ui_layers[i].layer, offsetof(UILayer, draw_rects), 1, 0); vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->char_pipeline.pipeline); - vkCmdDrawIndirect(command_buffer, ui_layers[i].layer, offsetof(UILayer, draw_chars), 1, 0); + vkCmdDrawIndirect(command_buffer, ui_layers[i].layer, offsetof(UILayer, draw_glyphs), 1, 0); } vkCmdEndRenderPass(command_buffer); @@ -1106,7 +1106,12 @@ VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILaye return VK_SUCCESS; } -VkResult create_transfer_buffer(VkDeviceSize size, VmaAllocator allocator, VkBuffer* buffer, VmaAllocation* memory, void** mapped) { +VkResult create_transfer_buffer( + VmaAllocator allocator, + VkDeviceSize size, + VkBuffer* buffer, + VmaAllocation* memory, + void** mapped) { VkBufferCreateInfo buffer_info = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, @@ -1130,3 +1135,39 @@ VkResult create_transfer_buffer(VkDeviceSize size, VmaAllocator allocator, VkBuf return VK_SUCCESS; } + + +VkResult create_storage_buffer( + VmaAllocator allocator, + VkBufferUsageFlags usage, + VkDeviceSize size, + VkBuffer* buffer, + VmaAllocation* memory) { + VkBufferCreateInfo buffer_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .size = size, + .usage = usage | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + }; + + VmaAllocationCreateInfo memory_info = { + .usage = VMA_MEMORY_USAGE_GPU_ONLY, + }; + + return vmaCreateBuffer(allocator, &buffer_info, &memory_info, buffer, memory, NULL); +}; + +void destroy_transfer_buffer( + VmaAllocator allocator, + VkBuffer buffer, + VmaAllocation memory) { + vmaUnmapMemory(allocator, memory); + vmaDestroyBuffer(allocator, buffer, memory); +} + +VkDeviceAddress buffer_address(VkDevice device, VkBuffer buffer) { + VkBufferDeviceAddressInfo info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + .buffer = buffer, + }; + return vkGetBufferDeviceAddress(device, &info); +} diff --git a/client/src/ui.c b/client/src/ui.c index 3db8c14..2e07e54 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -2,6 +2,7 @@ #include "cglm/affine.h" #include "cglm/mat4.h" #include "command.h" +#include "render.h" #include "stdio.h" #include "stdlib.h" #include "string.h" @@ -338,16 +339,58 @@ VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDe VkResult create_layer( uint32_t max_strings, - uint32_t max_characters, + uint32_t max_glyphs, uint32_t max_rects, VkDevice device, VmaAllocator allocator, VkCommandPool transfer_pool, Queue transfer_queue, - UILayerStorage* memory, - VkDeviceAddress* address) { + UILayerStorage* memory) { VkResult result; + VK_RESULT(create_storage_buffer(allocator, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, sizeof(UILayer), &memory->layer, &memory->layer_memory)); + VK_RESULT(create_storage_buffer(allocator, 0, sizeof(UIRect)*max_rects, &memory->rects, &memory->rects_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(UIGlyph)*max_glyphs, &memory->glyphs, &memory->glyphs_memory)); + VK_RESULT(create_storage_buffer(allocator, 0, sizeof(uint32_t)*max_glyphs, &memory->codes, &memory->codes_memory)); + + VkBuffer transfer; + VmaAllocation transfer_memory; + UILayer* mapped; + VK_RESULT(create_transfer_buffer(allocator, sizeof(UILayer), &transfer, &transfer_memory, (void**)&mapped)); + + mapped->strings = buffer_address(device, memory->strings); + mapped->codes = buffer_address(device, memory->codes); + + mapped->glyphs = buffer_address(device, memory->glyphs); + mapped->rects = buffer_address(device, memory->rects); + + mapped->draw_glyphs.first_vertex = 0; + mapped->draw_glyphs.vertex_count = 6; + mapped->draw_glyphs.first_instance = 0; + mapped->draw_glyphs.instance_count = 0; + + mapped->draw_rects.first_vertex = 0; + mapped->draw_rects.vertex_count = 6; + mapped->draw_rects.first_instance = 0; + mapped->draw_rects.instance_count = 0; + + mapped->dispatch_strings.x = 0; + mapped->dispatch_strings.y = 0; + mapped->dispatch_strings.z = 0; + + VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); + command_copy_buffer(command_buffer, transfer, memory->layer, 0, 0, sizeof(UILayer)); + vkCmdFillBuffer(command_buffer, memory->rects, 0, sizeof(UIRect)*max_rects, 0x00000000); + vkCmdFillBuffer(command_buffer, memory->strings, 0, sizeof(UIString)*max_strings, 0x00000000); + vkCmdFillBuffer(command_buffer, memory->glyphs, 0, sizeof(UIGlyph)*max_glyphs, 0x00000000); + vkCmdFillBuffer(command_buffer, memory->codes, 0, sizeof(uint32_t)*max_glyphs, 0x00000000); + VK_RESULT(command_end_single(device, command_buffer, transfer_pool, transfer_queue)); + vkQueueWaitIdle(transfer_queue.handle); + destroy_transfer_buffer(allocator, transfer, transfer_memory); + + memory->address = buffer_address(device, memory->layer); + return VK_SUCCESS; } @@ -364,7 +407,6 @@ VkResult load_font( const char* ttf_file, uint32_t size, VkBool32 antialias, - uint32_t** charmap, FontStorage* memory) { FT_Face face; @@ -419,15 +461,16 @@ VkResult load_font( info.width = max_width; info.height = max_height; info.num_symbols = symbol_count; + memory->num_symbols = symbol_count; uint32_t image_size = max_width*max_height*sizeof(uint32_t); uint32_t* images = malloc(image_size*symbol_count); memset(images, 0x00, image_size*symbol_count); - *charmap = malloc(sizeof(uint32_t)*symbol_count); - memcpy(*charmap, tmp_charmap, sizeof(uint32_t)*symbol_count); + memory->charmap = malloc(sizeof(uint32_t)*symbol_count); + memcpy(memory->charmap, tmp_charmap, sizeof(uint32_t)*symbol_count); free(tmp_charmap); for(uint32_t i = 0; i < symbol_count; i++) { - glyph_index = FT_Get_Char_Index(face, (*charmap)[i]); + glyph_index = FT_Get_Char_Index(face, memory->charmap[i]); FT_Load_Glyph(face, glyph_index, load_flags); for(uint32_t y = 0; y < face->glyph->bitmap.rows; y++) { for(uint32_t x = 0; x < face->glyph->bitmap.width; x++) { @@ -780,23 +823,49 @@ VkResult create_ui_descriptor(VkDevice device, VmaAllocator allocator, uint32_t return VK_SUCCESS; } -VkResult create_ui_context(VkDevice device, VmaAllocator allocator, VkRenderPass render_pass, UIContextStorage* memory) { +VkResult create_ui_context( + VkDevice device, + VmaAllocator allocator, + VkRenderPass render_pass, + uint32_t max_fonts, + VkExtent2D swapchain_extent, + vec2 window_scale, + VkCommandPool transfer_pool, + Queue transfer_queue, + UIContextStorage* memory) { VkResult result; - result = create_ui_descriptor(device, allocator, 10, &memory->font_infos, &memory->font_infos_memory, &memory->font_samplers, &memory->font_textures, &memory->font_samplers_layout, &memory->font_textures_layout, &memory->fonts_pool); - if(result != VK_SUCCESS) { - return result; - } - result = create_ui_rect_pipeline(device, render_pass, memory->font_samplers_layout, memory->font_textures_layout, &memory->rect_pipeline); - if(result != VK_SUCCESS) { - return 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)); - result = create_ui_text_pipeline(device, render_pass, memory->font_samplers_layout, memory->font_textures_layout, &memory->char_pipeline, &memory->string_pipeline); - if(result != VK_SUCCESS) { - return result; - } + + VkBuffer transfer; + VmaAllocation transfer_memory; + UIContext* mapped; + + VK_RESULT(create_transfer_buffer(allocator, sizeof(UIContext), &transfer, &transfer_memory, (void**)&mapped)); + + mapped->font_infos = buffer_address(device, memory->font_infos); + vec3 screen_offset = {-1.0, -1.0, 0.0}; + vec3 screen_scale = { + 1.0/(float)swapchain_extent.width*window_scale[0], + 1.0/(float)swapchain_extent.height*window_scale[1], 1.0}; + glm_mat4_identity(mapped->screen); + glm_translate(mapped->screen, screen_offset); + glm_scale(mapped->screen, screen_scale); + + VkCommandBuffer command_buffer = command_begin_single(device, 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(create_ui_descriptor(device, allocator, max_fonts, &memory->font_infos, &memory->font_infos_memory, &memory->font_samplers, &memory->font_textures, &memory->font_samplers_layout, &memory->font_textures_layout, &memory->fonts_pool)); + + VK_RESULT(create_ui_rect_pipeline(device, render_pass, memory->font_samplers_layout, memory->font_textures_layout, &memory->rect_pipeline)); + + VK_RESULT(create_ui_text_pipeline(device, render_pass, memory->font_samplers_layout, memory->font_textures_layout, &memory->char_pipeline, &memory->string_pipeline)); return VK_SUCCESS; }