diff --git a/client/include/ui.h b/client/include/ui.h index e96883e..2cc59d1 100644 --- a/client/include/ui.h +++ b/client/include/ui.h @@ -33,10 +33,10 @@ typedef struct DispatchCommandStruct { } DispatchCommand; typedef struct FontStruct { + VkDeviceAddress symbol_list; uint32_t num_symbols; uint32_t width; uint32_t height; - VkDeviceAddress symbol_list; } Font; typedef struct SymbolInfoStruct { @@ -94,6 +94,10 @@ typedef struct UIlayerStorageStruct { VmaAllocation layer_memory; VkDeviceAddress address; + + uint32_t max_glyphs; + uint32_t max_string; + uint32_t max_rects; } UILayerStorage; typedef struct UILayerStruct { @@ -106,11 +110,12 @@ typedef struct UILayerStruct { DrawCommand draw_glyphs; DrawCommand draw_rects; DispatchCommand dispatch_strings; + uint32_t font_index; } UILayer; typedef struct UIContextStruct { - mat4 screen; VkDeviceAddress font_infos; + mat4 screen; } UIContext; typedef struct UIContextStorageStruct { @@ -147,9 +152,7 @@ VkResult create_ui_context( VkResult load_font( VkDevice device, VmaAllocator allocator, - VkBuffer font_infos, - VkDescriptorSet font_samplers, - VkDescriptorSet font_textures, + UIContextStorage* context, uint32_t index, VkCommandPool transfer_pool, Queue transfer_queue, @@ -163,6 +166,7 @@ VkResult create_layer( uint32_t max_strings, uint32_t max_characters, uint32_t max_rects, + uint32_t font_index, VkDevice device, VmaAllocator allocator, VkCommandPool transfer_pool, diff --git a/client/shader_src/ui_rect.vert b/client/shader_src/ui_rect.vert index 0b7b479..760ba8e 100644 --- a/client/shader_src/ui_rect.vert +++ b/client/shader_src/ui_rect.vert @@ -5,7 +5,8 @@ struct String { vec2 pos; vec4 color; float size; - uint code; + uint offset; + uint length; }; layout(std430, buffer_reference) readonly buffer StringList { @@ -61,6 +62,8 @@ layout(std430, buffer_reference) buffer UILayer { DrawCommand draw_rects; DispatchCommand dispatch_strings; + + uint font_index; }; struct Symbol { @@ -89,8 +92,8 @@ layout(std430, buffer_reference) buffer FontList { }; layout(std430, buffer_reference) buffer UIContext { - mat4 screen; FontList fonts; + mat4 screen; }; layout(std430, push_constant) uniform PushConstant { diff --git a/client/shader_src/ui_text.comp b/client/shader_src/ui_text.comp index 5c527a8..a92f4ec 100644 --- a/client/shader_src/ui_text.comp +++ b/client/shader_src/ui_text.comp @@ -1,95 +1,121 @@ #version 450 #extension GL_EXT_buffer_reference : require -layout(buffer_reference, std430) buffer Symbol { - int top; - uint left; - uint width; - uint height; - uint advance; +struct String { + vec2 pos; + vec4 color; + float size; + uint offset; + uint len; +}; + +layout(std430, buffer_reference) readonly buffer StringList { + String s[]; }; -layout(buffer_reference, std430) buffer Character { - vec3 pos; +struct Glyph { + vec2 pos; vec4 color; float size; uint code; }; -layout(buffer_reference, std430) buffer String { - vec3 pos; +layout(std430, buffer_reference) readonly buffer GlyphList { + Glyph g[]; +}; + +struct Rect { + vec2 pos; + vec2 size; vec4 color; - float size; - uint offset; - uint len; }; -layout(buffer_reference, std430) readonly buffer SymbolList{ - Symbol symbols[]; +layout(std430, buffer_reference) readonly buffer RectList { + Rect r[]; }; -layout(buffer_reference, std430) writeonly buffer CharacterList{ - Character characters[]; +layout(std430, buffer_reference) readonly buffer CodeList { + uint c[]; }; -layout(buffer_reference, std430) readonly buffer Characters{ - uint codes[]; +struct DrawCommand { + uint vertex_count; + uint instance_count; + uint fist_vertex; + uint first_instance; }; -layout(buffer_reference, std430) readonly buffer Strings{ - String strings[]; +struct DispatchCommand { + uint x; + uint y; + uint z; }; -layout(buffer_reference, std430) readonly buffer Font { - uint num_symbols; +layout(std430, buffer_reference) buffer UILayer { + StringList strings; + CodeList codes; + + RectList rects; + GlyphList glyphs; + + DrawCommand draw_glyphs; + DrawCommand draw_rects; + + DispatchCommand dispatch_strings; + + uint font_index; +}; + +struct Symbol { + int top; + uint left; uint width; uint height; - SymbolList symbol_list; + uint advance; }; -layout(buffer_reference, std430) buffer DrawCommand { - uint vertex_count; - uint instance_count; - uint first_vertx; - uint first_instance; +layout(std430, buffer_reference) buffer SymbolList { + Symbol s[]; }; -layout(buffer_reference, std430) readonly buffer Pointers { - Strings strings; - Characters codes; - CharacterList characters; - DrawCommand draw; + +struct Font { + SymbolList symbols; + uint num_symbols; + uint width; + uint height; }; -layout(buffer_reference, std430) readonly buffer FontList { - Font fonts[]; + +layout(std430, buffer_reference) buffer FontList { + Font f[]; }; -layout(buffer_reference, std430) readonly buffer UIContext { - mat4 screen; +layout(std430, buffer_reference) buffer UIContext { FontList fonts; + mat4 screen; }; -layout(std430, push_constant) uniform Push { - UIContext ui; - Pointers pointers; -} push; +layout(std430, push_constant) uniform PushConstant { + UIContext context; + UILayer layer; +} pc; layout(local_size_x = 1) in; void main() { uint gID = gl_GlobalInvocationID.x; - String string = push.pointers.strings.strings[gID]; - Font font = push.ui.fonts.fonts[0]; + String string = pc.layer.strings.s[gID]; + Font font = pc.context.fonts.f[pc.layer.font_index]; - uint buffer_pos = atomicAdd(push.pointers.draw.instance_count, string.len); + uint buffer_pos = atomicAdd(pc.layer.draw_glyphs.instance_count, string.len); float x = 0; for(uint i = 0; i < string.len; i++) { - Symbol symbol = font.symbol_list.symbols[push.pointers.codes.codes[string.offset + i]]; - push.pointers.characters.characters[buffer_pos + i].pos = string.pos + vec3(x, 0, 0); + Symbol symbol = font.symbols.s[pc.layer.codes.c[string.offset + i]]; + pc.layer.glyphs.g[buffer_pos + i].pos = string.pos + vec2(x, 0); x += string.size*symbol.advance/font.width; - push.pointers.characters.characters[buffer_pos + i].size = string.size; - push.pointers.characters.characters[buffer_pos + i].color = string.color; - push.pointers.characters.characters[buffer_pos + i].code = push.pointers.codes.codes[string.offset + i]; + pc.layer.glyphs.g[buffer_pos + i].size = string.size; + pc.layer.glyphs.g[buffer_pos + i].color = string.color; + pc.layer.glyphs.g[buffer_pos + i].code = pc.layer.codes.c[string.offset + i]; } } diff --git a/client/shader_src/ui_text.vert b/client/shader_src/ui_text.vert index 50a5b8e..8bfa8dd 100644 --- a/client/shader_src/ui_text.vert +++ b/client/shader_src/ui_text.vert @@ -1,55 +1,105 @@ #version 450 #extension GL_EXT_buffer_reference : require -layout(buffer_reference, std430) buffer Symbol { - int top; - uint left; - uint width; - uint height; - uint advance; +struct String { + vec2 pos; + vec4 color; + float size; + uint offset; + uint length; +}; + +layout(std430, buffer_reference) readonly buffer StringList { + String s[]; }; -layout(buffer_reference, std430) buffer Character { - vec3 pos; +struct Glyph { + vec2 pos; vec4 color; float size; uint code; }; -layout(buffer_reference, std430) readonly buffer SymbolList{ - Symbol symbols[]; +layout(std430, buffer_reference) readonly buffer GlyphList { + Glyph g[]; }; -layout(buffer_reference, std430) readonly buffer CharacterList{ - Character characters[]; +struct Rect { + vec2 pos; + vec2 size; + vec4 color; }; -layout(buffer_reference, std430) readonly buffer Font { - uint num_symbols; +layout(std430, buffer_reference) readonly buffer RectList { + Rect r[]; +}; + +layout(std430, buffer_reference) readonly buffer CodeList { + uint c[]; +}; + +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; + + uint font_index; +}; + +struct Symbol { + int top; + uint left; uint width; uint height; - SymbolList symbol_list; + uint advance; +}; + +layout(std430, buffer_reference) buffer SymbolList { + Symbol s[]; }; -layout(buffer_reference, std430) readonly buffer Pointers { - uint padding[4]; - CharacterList characters; +struct Font { + SymbolList symbols; + uint num_symbols; + uint width; + uint height; }; -layout(buffer_reference, std430) readonly buffer FontList { - Font fonts[]; + +layout(std430, buffer_reference) buffer FontList { + Font f[]; }; -layout(buffer_reference, std430) readonly buffer UIContext { - mat4 screen; +layout(std430, buffer_reference) buffer UIContext { FontList fonts; + mat4 screen; }; -layout(std430, push_constant) uniform Push { - UIContext ui; - Pointers pointers; -} push; +layout(std430, push_constant) uniform PushConstant { + UIContext context; + UILayer layer; +} pc; layout(location = 0) out vec4 fragColor; layout(location = 1) out vec2 fragUV; @@ -66,19 +116,19 @@ const vec2 square[6] = { }; void main() { - Character character = push.pointers.characters.characters[gl_InstanceIndex]; - Font font = push.ui.fonts.fonts[0]; - Symbol symbol = font.symbol_list.symbols[character.code]; + Glyph glyph = pc.layer.glyphs.g[gl_InstanceIndex]; + Font font = pc.context.fonts.f[pc.layer.font_index]; + Symbol symbol = font.symbols.s[glyph.code]; float fragU = square[gl_VertexIndex].x * symbol.width/font.width; float fragV = square[gl_VertexIndex].y * symbol.height/font.height; - float x = (square[gl_VertexIndex].x * symbol.width + symbol.left) * character.size / font.width; - float y = (square[gl_VertexIndex].y * symbol.height - symbol.top) * character.size / font.height; + float x = (square[gl_VertexIndex].x * symbol.width + symbol.left) * glyph.size / font.width; + float y = (square[gl_VertexIndex].y * symbol.height - symbol.top) * glyph.size / font.height; fragUV = vec2(fragU, fragV); - fragColor = character.color; - gl_Position = push.ui.screen * vec4(vec3(x, y, 0.0) + character.pos, 1.0); - code = character.code; - font_index = 0; + fragColor = glyph.color; + gl_Position = pc.context.screen * vec4(vec2(x, y) + glyph.pos, 0.0, 1.0); + code = glyph.code; + font_index = pc.layer.font_index; } diff --git a/client/src/main.c b/client/src/main.c index a24e8e5..f6b0cc6 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -9,7 +9,7 @@ #include "ft2build.h" #include FT_FREETYPE_H -VkResult render_thread(GLFWwindow* window, RenderContext* render_context) { +VkResult render_thread(GLFWwindow* window, RenderContext* render) { FT_Library library; UIContextStorage ui; @@ -24,26 +24,26 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render_context) { VkResult result; VK_RESULT(create_ui_context( - render_context->device, - render_context->allocator, - render_context->render_pass, + render->device, + render->allocator, + render->render_pass, 10, - render_context->swapchain_extent, - render_context->window_scale, - render_context->transfer_pool, - render_context->transfer_queue, + render->swapchain_extent, + render->window_scale, + render->transfer_pool, + render->transfer_queue, &ui)); if(FT_Init_FreeType(&library) != FT_Err_Ok) { return VK_ERROR_UNKNOWN; } - 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)); + VK_RESULT(load_font(render->device, render->allocator, &ui, 0, render->transfer_pool, render->transfer_queue, library, "test.ttf", 16, VK_TRUE, &font)); - VK_RESULT(create_layer(10, 100, 10, render_context->device, render_context->allocator, render_context->transfer_pool, render_context->transfer_queue, &layers[0])); - VK_RESULT(create_layer(10, 100, 10, render_context->device, render_context->allocator, render_context->transfer_pool, render_context->transfer_queue, &layers[1])); + VK_RESULT(create_layer(10, 100, 10, 0, render->device, render->allocator, render->transfer_pool, render->transfer_queue, &layers[0])); + VK_RESULT(create_layer(10, 100, 10, 0, render->device, render->allocator, render->transfer_pool, render->transfer_queue, &layers[1])); - VK_RESULT(create_transfer_buffer(render_context->allocator, sizeof(uint32_t) + 2*sizeof(UIRect), &transfer, &transfer_memory, &mapped)); + VK_RESULT(create_transfer_buffer(render->allocator, sizeof(uint32_t) + 2*sizeof(UIRect) + sizeof(UIString) + 100*sizeof(uint32_t), &transfer, &transfer_memory, &mapped)); uint32_t* mapped_count = (uint32_t*)(mapped); mapped_count[0] = 1; @@ -66,19 +66,39 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render_context) { mapped_rect[1].color[2] = 0.0; mapped_rect[1].color[3] = 1.0; - VkCommandBuffer command_buffer = command_begin_single(render_context->device, render_context->transfer_pool); + UIString* mapped_string = (UIString*)(mapped + sizeof(uint32_t) + 2*sizeof(UIRect)); + mapped_string->pos[0] = 0.0; + mapped_string->pos[1] = 200.0; + mapped_string->size = 100.0; + mapped_string->color[0] = 1.0; + mapped_string->color[1] = 1.0; + mapped_string->color[2] = 1.0; + mapped_string->color[3] = 1.0; + mapped_string->length = 100; + mapped_string->offset = 0; + uint32_t* mapped_codes = (uint32_t*)(mapped + sizeof(uint32_t) + 2*sizeof(UIRect) + sizeof(UIString)); + for(uint32_t i = 0; i < 100; i++) { + mapped_codes[i] = i; + } + + VkCommandBuffer command_buffer = command_begin_single(render->device, render->transfer_pool); command_copy_buffer(command_buffer, transfer, layers[0].layer, 0, offsetof(UILayer, draw_rects) + offsetof(DrawCommand, instance_count), sizeof(uint32_t)); command_copy_buffer(command_buffer, transfer, layers[1].layer, 0, offsetof(UILayer, draw_rects) + offsetof(DrawCommand, instance_count), sizeof(uint32_t)); + command_copy_buffer(command_buffer, transfer, layers[1].layer, 0, offsetof(UILayer, dispatch_strings) + offsetof(DispatchCommand, x), sizeof(uint32_t)); + command_copy_buffer(command_buffer, transfer, layers[0].rects, sizeof(uint32_t), 0, sizeof(UIRect)); command_copy_buffer(command_buffer, transfer, layers[1].rects, sizeof(uint32_t) + sizeof(UIRect), 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); - destroy_transfer_buffer(render_context->allocator, transfer, transfer_memory); + + command_copy_buffer(command_buffer, transfer, layers[1].strings, sizeof(uint32_t) + 2*sizeof(UIRect), 0, sizeof(UIString)); + command_copy_buffer(command_buffer, transfer, layers[1].codes, sizeof(uint32_t) + 2*sizeof(UIRect) + sizeof(UIString), 0, 100*sizeof(uint32_t)); + VK_RESULT(command_end_single(render->device, command_buffer, render->transfer_pool, render->transfer_queue)); + vkQueueWaitIdle(render->transfer_queue.handle); + destroy_transfer_buffer(render->allocator, transfer, transfer_memory); while(glfwWindowShouldClose(window) == 0) { glfwPollEvents(); - result = draw_frame(render_context, &ui, layers, 2); + result = draw_frame(render, &ui, layers, sizeof(layers)/sizeof(UILayerStorage)); if(result != VK_SUCCESS) { fprintf(stderr, "draw_frame error: %s\n", string_VkResult(result)); return result; @@ -101,12 +121,12 @@ int main() { return 1; } - RenderContext render_context = {}; - if(init_vulkan(window, &render_context) != VK_SUCCESS) { + RenderContext render = {}; + if(init_vulkan(window, &render) != VK_SUCCESS) { return 2; } - if(render_thread(window, &render_context) != VK_SUCCESS) { + if(render_thread(window, &render) != VK_SUCCESS) { return 3; } diff --git a/client/src/render.c b/client/src/render.c index 005da54..e14a759 100644 --- a/client/src/render.c +++ b/client/src/render.c @@ -1041,8 +1041,46 @@ VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILaye vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, ui_context->string_pipeline.pipeline); for(uint32_t i = 0; i < ui_layer_count; i++) { push[1] = ui_layers[i].address; + VkBufferMemoryBarrier draw_command_barrier_1 = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .buffer = ui_layers[i].layer, + .offset = offsetof(UILayer, draw_glyphs), + .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); + vkCmdFillBuffer(command_buffer, ui_layers[i].layer, offsetof(UILayer, draw_glyphs) + offsetof(DrawCommand, instance_count), sizeof(uint32_t), 0x00000000); + VkBufferMemoryBarrier draw_command_barrier_2 = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .buffer = ui_layers[i].layer, + .offset = offsetof(UILayer, draw_glyphs), + .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, ui_layers[i].layer, offsetof(UILayer, dispatch_strings)); + VkBufferMemoryBarrier draw_command_barrier_3 = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .buffer = ui_layers[i].layer, + .offset = offsetof(UILayer, draw_glyphs), + .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 glyphs_barrier = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .buffer = ui_layers[i].glyphs, + .offset = 0, + .size = sizeof(UIGlyph)*ui_layers[i].max_glyphs, + .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, &glyphs_barrier, 0, NULL); } diff --git a/client/src/ui.c b/client/src/ui.c index a6cc416..3136e41 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -341,6 +341,7 @@ VkResult create_layer( uint32_t max_strings, uint32_t max_glyphs, uint32_t max_rects, + uint32_t font_index, VkDevice device, VmaAllocator allocator, VkCommandPool transfer_pool, @@ -348,6 +349,10 @@ VkResult create_layer( UILayerStorage* memory) { VkResult result; + memory->max_string = max_strings; + memory->max_glyphs = max_glyphs; + memory->max_rects = max_rects; + 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)) @@ -376,8 +381,10 @@ VkResult create_layer( mapped->draw_rects.instance_count = 0; mapped->dispatch_strings.x = 0; - mapped->dispatch_strings.y = 0; - mapped->dispatch_strings.z = 0; + mapped->dispatch_strings.y = 1; + mapped->dispatch_strings.z = 1; + + mapped->font_index = font_index; VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); command_copy_buffer(command_buffer, transfer, memory->layer, 0, 0, sizeof(UILayer)); @@ -397,9 +404,7 @@ VkResult create_layer( VkResult load_font( VkDevice device, VmaAllocator allocator, - VkBuffer font_infos, - VkDescriptorSet font_samplers, - VkDescriptorSet font_textures, + UIContextStorage* context, uint32_t index, VkCommandPool transfer_pool, Queue transfer_queue, @@ -488,19 +493,7 @@ VkResult load_font( } VkResult result; - VkBufferCreateInfo symbol_buffer_info = { - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .size = sizeof(SymbolInfo)*info.num_symbols, - }; - VmaAllocationCreateInfo symbol_memory_info = { - .usage = VMA_MEMORY_USAGE_GPU_ONLY, - }; - result = vmaCreateBuffer(allocator, &symbol_buffer_info, &symbol_memory_info, &memory->symbols, &memory->symbol_memory, NULL); - if(result != VK_SUCCESS) { - return result; - } + VK_RESULT(create_storage_buffer(allocator, 0, sizeof(SymbolInfo)*info.num_symbols, &memory->symbols, &memory->symbol_memory)); VkImageCreateInfo image_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, @@ -522,61 +515,25 @@ VkResult load_font( .usage = VMA_MEMORY_USAGE_GPU_ONLY, }; - result = vmaCreateImage(allocator, &image_info, &image_memory_info, &memory->image, &memory->image_memory, NULL); - if(result != VK_SUCCESS) { - return result; - } + VK_RESULT(vmaCreateImage(allocator, &image_info, &image_memory_info, &memory->image, &memory->image_memory, NULL)); - VkBufferCreateInfo staging_info = { - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .size = sizeof(Font) + image_size*info.num_symbols + sizeof(SymbolInfo)*info.num_symbols, - }; + 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)); + + info.symbol_list = buffer_address(device, memory->symbols); - VmaAllocationCreateInfo staging_memory_info = { - .usage = VMA_MEMORY_USAGE_CPU_TO_GPU, - }; + memcpy(mapped, images, image_size*info.num_symbols); + memcpy(mapped + image_size*info.num_symbols, &info, sizeof(Font)); + memcpy(mapped + image_size*info.num_symbols + sizeof(Font), symbols, sizeof(SymbolInfo)*info.num_symbols); - VkBuffer staging_buffer; - VmaAllocation staging_memory; - result = vmaCreateBuffer(allocator, &staging_info, &staging_memory_info, &staging_buffer, &staging_memory, NULL); - if(result != VK_SUCCESS) { - return result; - } - - void* mapped_staging; - result = vmaMapMemory(allocator, staging_memory, &mapped_staging); - if(result != VK_SUCCESS) { - return result; - } - memcpy(mapped_staging + image_size*info.num_symbols + sizeof(Font), symbols, sizeof(SymbolInfo)*info.num_symbols); - VkBufferDeviceAddressInfo address_info = { - .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, - .buffer = memory->symbols, - }; - info.symbol_list = vkGetBufferDeviceAddress(device, &address_info); - memcpy(mapped_staging + image_size*info.num_symbols, &info, sizeof(Font)); - memcpy(mapped_staging, images, image_size*info.num_symbols); - vmaUnmapMemory(allocator, staging_memory); free(images); free(symbols); VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); - - VkBufferCopy info_copy = { - .size = sizeof(Font), - .srcOffset = image_size*info.num_symbols, - .dstOffset = index*sizeof(Font), - }; - vkCmdCopyBuffer(command_buffer, staging_buffer, font_infos, 1, &info_copy); - - VkBufferCopy symbol_copy = { - .size = sizeof(SymbolInfo)*info.num_symbols, - .srcOffset = image_size*info.num_symbols + sizeof(Font), - .dstOffset = 0, - }; - vkCmdCopyBuffer(command_buffer, staging_buffer, memory->symbols, 1, &symbol_copy); + 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); VkImageMemoryBarrier first_barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, @@ -598,7 +555,7 @@ VkResult load_font( .imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .imageExtent = image_info.extent, }; - vkCmdCopyBufferToImage(command_buffer, staging_buffer, memory->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); + vkCmdCopyBufferToImage(command_buffer, transfer, memory->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); VkImageMemoryBarrier second_barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, @@ -619,7 +576,8 @@ VkResult load_font( if(result != VK_SUCCESS) { return result; } - vmaDestroyBuffer(allocator, staging_buffer, staging_memory); + vkQueueWaitIdle(transfer_queue.handle); + destroy_transfer_buffer(allocator, transfer, transfer_memory); VkImageViewCreateInfo view_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, @@ -664,7 +622,7 @@ VkResult load_font( VkWriteDescriptorSet descriptor_writes[] = { { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = font_textures, + .dstSet = context->font_textures, .dstBinding = 0, .dstArrayElement = index, .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, @@ -673,7 +631,7 @@ VkResult load_font( }, { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = font_samplers, + .dstSet = context->font_samplers, .dstBinding = 0, .dstArrayElement = index, .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, @@ -686,23 +644,8 @@ VkResult load_font( return VK_SUCCESS; } -VkResult create_ui_descriptor(VkDevice device, VmaAllocator allocator, uint32_t max_fonts, VkBuffer* font_infos, VmaAllocation* font_infos_memory, VkDescriptorSet* font_samplers, VkDescriptorSet* font_textures, VkDescriptorSetLayout* font_sampler_layout, VkDescriptorSetLayout* font_texture_layout, VkDescriptorPool* font_pool) { - VkBufferCreateInfo font_infos_buffer = { - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .size = sizeof(Font)*max_fonts, - .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, - }; - - VmaAllocationCreateInfo font_infos_memory_info = { - .usage = VMA_MEMORY_USAGE_GPU_ONLY, - }; - +VkResult create_ui_descriptor(VkDevice device, uint32_t max_fonts, VkDescriptorSet* font_samplers, VkDescriptorSet* font_textures, VkDescriptorSetLayout* font_sampler_layout, VkDescriptorSetLayout* font_texture_layout, VkDescriptorPool* font_pool) { VkResult result; - result = vmaCreateBuffer(allocator, &font_infos_buffer, &font_infos_memory_info, font_infos, font_infos_memory, NULL); - if(result != VK_SUCCESS) { - return result; - } - VkDescriptorSetLayoutBinding font_sampler_bindings[] = { { .binding = 0, @@ -839,7 +782,6 @@ VkResult create_ui_context( 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)); - VkBuffer transfer; VmaAllocation transfer_memory; UIContext* mapped; @@ -861,7 +803,7 @@ VkResult create_ui_context( 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_descriptor(device, max_fonts, &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));