|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|