Got GPU rendering of rects working

main
noah metz 2024-10-18 16:15:00 -06:00
parent 6129e9c5b9
commit 5e1720dc71
9 changed files with 337 additions and 102 deletions

@ -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); 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); 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 #endif

@ -27,6 +27,13 @@
#include "ui.h" #include "ui.h"
#include "command.h" #include "command.h"
#define VK_RESULT(x) {\
result = x;\
if(result != VK_SUCCESS) {\
return x;\
}\
}
extern const uint32_t MAX_FRAMES_IN_FLIGHT; extern const uint32_t MAX_FRAMES_IN_FLIGHT;
typedef struct SwapchainDetailsStruct { typedef struct SwapchainDetailsStruct {
@ -97,10 +104,26 @@ VkResult draw_frame(
uint32_t ui_layer_count); uint32_t ui_layer_count);
VkResult create_transfer_buffer( VkResult create_transfer_buffer(
VkDeviceSize size,
VmaAllocator allocator, VmaAllocator allocator,
VkDeviceSize size,
VkBuffer* buffer, VkBuffer* buffer,
VmaAllocation* memory, VmaAllocation* memory,
void** mapped); 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 #endif

@ -19,22 +19,6 @@ typedef struct GraphicsPipelineStruct {
VkPipeline pipeline; VkPipeline pipeline;
} GraphicsPipeline; } 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 { typedef struct DrawCommandStruct {
uint32_t vertex_count; uint32_t vertex_count;
uint32_t instance_count; uint32_t instance_count;
@ -48,14 +32,6 @@ typedef struct DispatchCommandStruct {
uint32_t z; uint32_t z;
} DispatchCommand; } DispatchCommand;
typedef struct CharacterStruct {
vec3 pos;
float pad0;
vec4 color;
float size;
uint32_t code;
} Character;
typedef struct FontStruct { typedef struct FontStruct {
uint32_t num_symbols; uint32_t num_symbols;
uint32_t width; uint32_t width;
@ -78,33 +54,42 @@ typedef struct FontStorageStruct {
VkImage image; VkImage image;
VkImageView view; VkImageView view;
VkSampler sampler; VkSampler sampler;
uint32_t* charmap;
uint32_t num_symbols;
uint32_t index; uint32_t index;
} FontStorage; } FontStorage;
typedef struct TextPointersMemoryStruct { typedef struct UIRectStruct {
VmaAllocation pointers_memory; vec2 pos;
VmaAllocation draw_memory; vec2 size;
VmaAllocation strings_memory; vec4 color;
VmaAllocation codes_memory; } UIRect;
VmaAllocation characters_memory;
VkBuffer pointers_buffer; typedef struct UIStringStruct {
VkBuffer draw_buffer; vec2 pos;
VkBuffer strings_buffer; vec4 color;
VkBuffer codes_buffer; float size;
VkBuffer characters_buffer; uint32_t offset;
} TextPointersMemory; uint32_t length;
} UIString;
typedef struct UIGlyphStruct {
vec2 pos;
vec4 color;
float size;
uint32_t code;
} UIGlyph;
typedef struct UIlayerStorageStruct { typedef struct UIlayerStorageStruct {
VkBuffer strings; VkBuffer strings;
VkBuffer chars; VkBuffer glyphs;
VkBuffer codes; VkBuffer codes;
VkBuffer rects; VkBuffer rects;
VkBuffer layer; VkBuffer layer;
VmaAllocation strings_memory; VmaAllocation strings_memory;
VmaAllocation rects_memory; VmaAllocation rects_memory;
VmaAllocation chars_memory; VmaAllocation glyphs_memory;
VmaAllocation codes_memory; VmaAllocation codes_memory;
VmaAllocation layer_memory; VmaAllocation layer_memory;
@ -112,13 +97,13 @@ typedef struct UIlayerStorageStruct {
} UILayerStorage; } UILayerStorage;
typedef struct UILayerStruct { typedef struct UILayerStruct {
VkDeviceAddress rects;
uint32_t rect_count;
VkDeviceAddress strings; VkDeviceAddress strings;
uint32_t font_index; VkDeviceAddress codes;
DrawCommand draw_chars; VkDeviceAddress rects;
VkDeviceAddress glyphs;
DrawCommand draw_glyphs;
DrawCommand draw_rects; DrawCommand draw_rects;
DispatchCommand dispatch_strings; DispatchCommand dispatch_strings;
} UILayer; } UILayer;
@ -152,6 +137,11 @@ VkResult create_ui_context(
VkDevice device, VkDevice device,
VmaAllocator allocator, VmaAllocator allocator,
VkRenderPass render_pass, VkRenderPass render_pass,
uint32_t max_fonts,
VkExtent2D swapchain_extent,
vec2 window_scale,
VkCommandPool transfer_pool,
Queue transfer_queue,
UIContextStorage* memory); UIContextStorage* memory);
VkResult load_font( VkResult load_font(
@ -167,7 +157,6 @@ VkResult load_font(
const char* ttf_file, const char* ttf_file,
uint32_t size, uint32_t size,
VkBool32 antialias, VkBool32 antialias,
uint32_t** charmap,
FontStorage* memory); FontStorage* memory);
VkResult create_layer( VkResult create_layer(
@ -178,6 +167,5 @@ VkResult create_layer(
VmaAllocator allocator, VmaAllocator allocator,
VkCommandPool transfer_pool, VkCommandPool transfer_pool,
Queue transfer_queue, Queue transfer_queue,
UILayerStorage* memory, UILayerStorage* memory);
VkDeviceAddress* address);
#endif #endif

@ -1,8 +1,30 @@
#version 450 #version 450
#extension GL_EXT_buffer_reference : require #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 { struct Rect {
vec3 pos; vec2 pos;
vec2 size; vec2 size;
vec4 color; vec4 color;
}; };
@ -11,13 +33,69 @@ layout(std430, buffer_reference) readonly buffer RectList {
Rect r[]; Rect r[];
}; };
layout(std430, buffer_reference) readonly buffer ScreenInfo { layout(std430, buffer_reference) readonly buffer CodeList {
mat4 bounds; uint c[];
}; };
layout(std430, push_constant) uniform PushConstant { struct DrawCommand {
ScreenInfo screen; 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; 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; } pc;
layout(location = 0) out vec4 fragColor; layout(location = 0) out vec4 fragColor;
@ -32,8 +110,8 @@ const vec2 square[6] = {
}; };
void main() { void main() {
Rect rect = pc.rects.r[gl_InstanceIndex]; Rect rect = pc.layer.rects.r[gl_InstanceIndex];
gl_Position = pc.screen.bounds * vec4(vec3(square[gl_VertexIndex] * rect.size, 0.0) + rect.pos.xyz, 1.0); gl_Position = pc.context.screen * vec4(square[gl_VertexIndex] * rect.size + rect.pos, 0.0, 1.0);
fragColor = rect.color; fragColor = rect.color;
} }

@ -1,8 +1,8 @@
#version 450 #version 450
#extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_nonuniform_qualifier : enable
layout(set = 0, binding = 0) uniform sampler font_samplers[]; //layout(set = 0, binding = 0) uniform sampler font_samplers[];
layout(set = 1, binding = 0) uniform texture2DArray font_textures[]; //layout(set = 1, binding = 0) uniform texture2DArray font_textures[];
layout(location = 0) in vec4 fragColor; layout(location = 0) in vec4 fragColor;
layout(location = 1) in vec2 fragUV; layout(location = 1) in vec2 fragUV;
@ -11,6 +11,7 @@ layout(location = 2) flat in uint code;
layout(location = 0) out vec4 outColor; layout(location = 0) out vec4 outColor;
void main() { 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);
} }

@ -52,6 +52,15 @@ VkResult command_end_single(VkDevice device, VkCommandBuffer command_buffer, VkC
return result; 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, &copy);
}
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) { 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); VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool);

@ -1,3 +1,4 @@
#include "command.h"
#include "render.h" #include "render.h"
#include "arpa/inet.h" #include "arpa/inet.h"
#include "ui.h" #include "ui.h"
@ -9,38 +10,61 @@
#include FT_FREETYPE_H #include FT_FREETYPE_H
VkResult render_thread(GLFWwindow* window, RenderContext* render_context) { VkResult render_thread(GLFWwindow* window, RenderContext* render_context) {
VkResult result;
UIContextStorage ui;
FT_Library library; FT_Library library;
UIContextStorage ui;
UILayerStorage layer;
FontStorage font; FontStorage font;
uint32_t* charmap;
VkBuffer temp_buffer; VkBuffer transfer;
VmaAllocation temp_memory; VmaAllocation transfer_memory;
void* mapped; void* mapped;
UILayerStorage layer = {};
result = create_ui_context(render_context->device, render_context->allocator, render_context->render_pass, &ui); VkResult result;
if(result != VK_SUCCESS) {
return 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) { if(FT_Init_FreeType(&library) != FT_Err_Ok) {
return VK_ERROR_UNKNOWN; 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); 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));
if(result != VK_SUCCESS) {
return result;
}
result = create_transfer_buffer(2*sizeof(String) + 100*sizeof(uint32_t), render_context->allocator, &temp_buffer, &temp_memory, (void**)&mapped); VK_RESULT(create_layer(10, 100, 10, render_context->device, render_context->allocator, render_context->transfer_pool, render_context->transfer_queue, &layer));
if(result != VK_SUCCESS) {
return result; 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); vkQueueWaitIdle(render_context->transfer_queue.handle);
vmaUnmapMemory(render_context->allocator, temp_memory); destroy_transfer_buffer(render_context->allocator, transfer, transfer_memory);
vmaDestroyBuffer(render_context->allocator, temp_buffer, temp_memory);
fprintf(stderr, "%ld\n", sizeof(UILayer));
fprintf(stderr, "%ld\n", sizeof(UIRect));
while(glfwWindowShouldClose(window) == 0) { while(glfwWindowShouldClose(window) == 0) {
glfwPollEvents(); glfwPollEvents();

@ -1051,15 +1051,15 @@ VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILaye
// World subpass // World subpass
vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE); vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE);
// UI subpass // 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->char_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, 1, 1, &ui_context->font_textures, 0, NULL);
for(uint32_t i = 0; i < ui_layer_count; i++) { for(uint32_t i = 0; i < ui_layer_count; i++) {
push[1] = ui_layers[i].address; 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); 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); 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); 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); vkCmdEndRenderPass(command_buffer);
@ -1106,7 +1106,12 @@ VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILaye
return VK_SUCCESS; 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 = { VkBufferCreateInfo buffer_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
@ -1130,3 +1135,39 @@ VkResult create_transfer_buffer(VkDeviceSize size, VmaAllocator allocator, VkBuf
return VK_SUCCESS; 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);
}

@ -2,6 +2,7 @@
#include "cglm/affine.h" #include "cglm/affine.h"
#include "cglm/mat4.h" #include "cglm/mat4.h"
#include "command.h" #include "command.h"
#include "render.h"
#include "stdio.h" #include "stdio.h"
#include "stdlib.h" #include "stdlib.h"
#include "string.h" #include "string.h"
@ -338,16 +339,58 @@ VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDe
VkResult create_layer( VkResult create_layer(
uint32_t max_strings, uint32_t max_strings,
uint32_t max_characters, uint32_t max_glyphs,
uint32_t max_rects, uint32_t max_rects,
VkDevice device, VkDevice device,
VmaAllocator allocator, VmaAllocator allocator,
VkCommandPool transfer_pool, VkCommandPool transfer_pool,
Queue transfer_queue, Queue transfer_queue,
UILayerStorage* memory, UILayerStorage* memory) {
VkDeviceAddress* address) {
VkResult result; 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; return VK_SUCCESS;
} }
@ -364,7 +407,6 @@ VkResult load_font(
const char* ttf_file, const char* ttf_file,
uint32_t size, uint32_t size,
VkBool32 antialias, VkBool32 antialias,
uint32_t** charmap,
FontStorage* memory) { FontStorage* memory) {
FT_Face face; FT_Face face;
@ -419,15 +461,16 @@ VkResult load_font(
info.width = max_width; info.width = max_width;
info.height = max_height; info.height = max_height;
info.num_symbols = symbol_count; info.num_symbols = symbol_count;
memory->num_symbols = symbol_count;
uint32_t image_size = max_width*max_height*sizeof(uint32_t); uint32_t image_size = max_width*max_height*sizeof(uint32_t);
uint32_t* images = malloc(image_size*symbol_count); uint32_t* images = malloc(image_size*symbol_count);
memset(images, 0x00, image_size*symbol_count); memset(images, 0x00, image_size*symbol_count);
*charmap = malloc(sizeof(uint32_t)*symbol_count); memory->charmap = malloc(sizeof(uint32_t)*symbol_count);
memcpy(*charmap, tmp_charmap, sizeof(uint32_t)*symbol_count); memcpy(memory->charmap, tmp_charmap, sizeof(uint32_t)*symbol_count);
free(tmp_charmap); free(tmp_charmap);
for(uint32_t i = 0; i < symbol_count; i++) { 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); FT_Load_Glyph(face, glyph_index, load_flags);
for(uint32_t y = 0; y < face->glyph->bitmap.rows; y++) { for(uint32_t y = 0; y < face->glyph->bitmap.rows; y++) {
for(uint32_t x = 0; x < face->glyph->bitmap.width; x++) { 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; 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; 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); VK_RESULT(create_storage_buffer(allocator, 0, sizeof(UIContext), &memory->context, &memory->context_memory));
if(result != VK_SUCCESS) { VK_RESULT(create_storage_buffer(allocator, 0, sizeof(Font)*max_fonts, &memory->font_infos, &memory->font_infos_memory));
return result;
}
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) { VkBuffer transfer;
return result; 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; return VK_SUCCESS;
} }