First pass of compute string to gpu characters

main
noah metz 2024-10-15 16:14:34 -06:00
parent 3c059e4333
commit 405cf139ef
4 changed files with 312 additions and 107 deletions

@ -26,34 +26,35 @@ typedef struct UIUniformStruct {
mat4 screen;
} UIUniform;
typedef struct TextStruct {
typedef struct StringStruct {
vec3 pos;
vec2 size;
vec4 color;
uint32_t length;
float size;
uint32_t offset;
} Text;
uint32_t length;
} String;
typedef struct DrawCommandStruct {
uint32_t vertex_count;
uint32_t index_count;
uint32_t instance_count;
uint32_t first_vertex;
uint32_t first_index;
int32_t vertex_offset;
uint32_t first_instance;
} DrawCommand;
typedef struct TextPointersStruct {
typedef struct StringPointersStruct {
VkDeviceAddress strings;
VkDeviceAddress codes;
VkDeviceAddress characters;
VkDeviceAddress draw;
} TextPointers;
} StringPointers;
typedef struct CharStruct {
typedef struct CharacterStruct {
vec3 pos;
vec4 color;
float size;
uint32_t code;
} Char;
} Character;
typedef struct FontUniformStruct {
uint32_t num_symbols;
@ -94,9 +95,12 @@ typedef struct UILayerStruct {
uint32_t textured_rect_count;
VkDescriptorSet textured_rect_descriptor;
VkDeviceAddress texts_address;
VkBuffer texts;
uint32_t text_count;
VkBuffer string_draw;
VkBuffer string_draw_clear;
uint32_t chars_size;
VkBuffer chars;
VkDeviceAddress string_pointers;
uint32_t string_count;
FontDescriptor font;
} UILayer;

@ -71,5 +71,11 @@ void main() {
String string = push.pointers.strings.strings[gID];
uint buffer_pos = atomicAdd(push.pointers.draw.instance_count, string.len);
for(uint i = 0; i < string.len; i++) {
push.pointers.characters.characters[buffer_pos + i].pos = string.pos;
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[buffer_pos + i];
}
// Write the characters to push.pointers.characters.characters[buffer_pos:buffer_pos+string.len)
}

@ -98,175 +98,336 @@ VkResult load_font(const char* atlas_file, const char* metadata_file, FontData*
return VK_SUCCESS;
}
VkResult render_thread(GLFWwindow* window, RenderContext* render_context) {
typedef struct TextPointersMemoryStruct {
VmaAllocation pointers_memory;
VmaAllocation draw_memory;
VmaAllocation strings_memory;
VmaAllocation codes_memory;
VmaAllocation characters_memory;
VmaAllocation draw_clear_memory;
VkBuffer pointers_buffer;
VkBuffer draw_buffer;
VkBuffer draw_clear_buffer;
VkBuffer strings_buffer;
VkBuffer codes_buffer;
VkBuffer characters_buffer;
} TextPointersMemory;
VkResult create_text_pointers(
uint32_t max_strings,
uint32_t max_characters,
VkDevice device,
VmaAllocator allocator,
VkCommandPool transfer_pool,
Queue transfer_queue,
TextPointersMemory* memory,
VkDeviceAddress* address) {
VkResult result;
UIContext ui_context;
VkBuffer colored_rect_buffer;
VkBuffer text_buffer;
VmaAllocation colored_rect_memory;
VmaAllocation text_memory;
result = init_pipelines(render_context->device, render_context->allocator, render_context->swapchain_extent, render_context->window_scale, render_context->render_pass, render_context->transfer_queue, render_context->transfer_pool, &ui_context);
VmaAllocationCreateInfo memory_info = {
.usage = VMA_MEMORY_USAGE_GPU_ONLY,
};
VkBufferCreateInfo pointers_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = sizeof(StringPointers),
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
result = vmaCreateBuffer(allocator, &pointers_info, &memory_info, &memory->pointers_buffer, &memory->pointers_memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
FontData test_font = {};
uint32_t* test_atlas;
SymbolInfo* test_symbols;
result = load_font("tools/test.png", "tools/test.meta", &test_font, &test_symbols, &test_atlas);
VkBufferCreateInfo draw_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = sizeof(DrawCommand),
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
result = vmaCreateBuffer(allocator, &draw_info, &memory_info, &memory->draw_buffer, &memory->draw_memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
FontDescriptor test_font_descriptor;
result = create_text_descriptor(render_context->device, render_context->allocator, ui_context.font_layout, ui_context.font_pool, &test_font, test_symbols, test_atlas, render_context->transfer_pool, render_context->transfer_queue, &test_font_descriptor);
VkBufferCreateInfo draw_clear_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = sizeof(DrawCommand),
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
result = vmaCreateBuffer(allocator, &draw_clear_info, &memory_info, &memory->draw_clear_buffer, &memory->draw_clear_memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
VkBufferCreateInfo colored_rect_buffer_info = {
VkBufferCreateInfo strings_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
.size = 3*sizeof(ColoredRect),
.size = max_strings*sizeof(String),
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo colored_rect_memory_info = {
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
result = vmaCreateBuffer(allocator, &strings_info, &memory_info, &memory->strings_buffer, &memory->strings_memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
VkBufferCreateInfo codes_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = max_characters*sizeof(DrawCommand),
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
result = vmaCreateBuffer(render_context->allocator, &colored_rect_buffer_info, &colored_rect_memory_info, &colored_rect_buffer, &colored_rect_memory, NULL);
result = vmaCreateBuffer(allocator, &codes_info, &memory_info, &memory->codes_buffer, &memory->codes_memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
ColoredRect* colored_rects;
VkBufferCreateInfo characters_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = max_characters*sizeof(DrawCommand),
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
result = vmaMapMemory(render_context->allocator, colored_rect_memory, (void**)&colored_rects);
result = vmaCreateBuffer(allocator, &characters_info, &memory_info, &memory->characters_buffer, &memory->characters_memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
colored_rects[0] = colored_rect(100.0, 100.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5);
colored_rects[1] = colored_rect(100.0, 100.0, 0.0, 1.0, 0.0, 1.0, 0.0, 100.0, 0.5);
colored_rects[2] = colored_rect(100.0, 100.0, 0.0, 0.0, 1.0, 1.0, 100.0, 0.0, 0.5);
VkBufferDeviceAddressInfo pointers_address = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = memory->pointers_buffer,
};
vmaUnmapMemory(render_context->allocator, colored_rect_memory);
VkBufferDeviceAddressInfo strings_address = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = memory->strings_buffer,
};
VkBufferDeviceAddressInfo codes_address = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = memory->codes_buffer,
};
VkBufferDeviceAddressInfo characters_address = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = memory->characters_buffer,
};
VkBufferDeviceAddressInfo draw_address = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = memory->draw_buffer,
};
VkBufferCreateInfo text_buffer_info = {
VkBuffer temp_buffer;
VmaAllocation temp_memory;
VkBufferCreateInfo temp_buffer_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.size = 2*sizeof(Char),
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.size = sizeof(StringPointers) +
sizeof(DrawCommand),
};
VmaAllocationCreateInfo text_memory_info = {
VmaAllocationCreateInfo temp_memory_info = {
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
};
result = vmaCreateBuffer(render_context->allocator, &text_buffer_info, &text_memory_info, &text_buffer, &text_memory, NULL);
result = vmaCreateBuffer(allocator, &temp_buffer_info, &temp_memory_info, &temp_buffer, &temp_memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
Char* text;
result = vmaMapMemory(render_context->allocator, text_memory, (void**)&text);
void* mapped;
result = vmaMapMemory(allocator, temp_memory, &mapped);
if(result != VK_SUCCESS) {
return result;
}
text[0].color[0] = 1.0f;
text[0].color[1] = 1.0f;
text[0].color[2] = 1.0f;
text[0].color[3] = 1.0f;
text[0].pos[0] = 200.0f;
text[0].pos[1] = 200.0f;
text[0].size = 200.0f;
text[0].code = 1;
DrawCommand draw = {
.index_count = 6,
};
text[1].color[0] = 1.0f;
text[1].color[1] = 1.0f;
text[1].color[2] = 1.0f;
text[1].color[3] = 1.0f;
text[1].pos[0] = 400.0f;
text[1].pos[1] = 200.0f;
text[1].size = 200.0f;
text[1].code = 14;
memcpy(mapped + 0, &draw, sizeof(DrawCommand));
StringPointers pointers = {
.strings = vkGetBufferDeviceAddress(device, &strings_address),
.codes = vkGetBufferDeviceAddress(device, &codes_address),
.characters = vkGetBufferDeviceAddress(device, &characters_address),
.draw = vkGetBufferDeviceAddress(device, &draw_address),
};
memcpy(mapped + sizeof(DrawCommand), &pointers, sizeof(StringPointers));
vmaUnmapMemory(allocator, temp_memory);
vmaUnmapMemory(render_context->allocator, text_memory);
VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool);
VkBufferCopy copy_draw = {
.size = sizeof(DrawCommand),
.srcOffset = 0,
};
vkCmdCopyBuffer(command_buffer, temp_buffer, memory->draw_buffer, 1, &copy_draw);
vkCmdCopyBuffer(command_buffer, temp_buffer, memory->draw_clear_buffer, 1, &copy_draw);
VkBufferCopy copy_pointers = {
.size = sizeof(StringPointers),
.srcOffset = sizeof(DrawCommand),
};
vkCmdCopyBuffer(command_buffer, temp_buffer, memory->pointers_buffer, 1, &copy_pointers);
result = command_end_single(device, command_buffer, transfer_pool, transfer_queue);
if(result != VK_SUCCESS) {
return result;
}
vmaDestroyBuffer(allocator, temp_buffer, temp_memory);
*address = vkGetBufferDeviceAddress(device, &pointers_address);
VkBuffer draw_buffer;
VmaAllocation draw_memory;
return VK_SUCCESS;
}
VkBufferCreateInfo draw_buffer_info = {
VkResult create_transfer_buffer(VkDeviceSize size, VmaAllocator allocator, VkBuffer* buffer, VmaAllocation* memory, void** mapped) {
VkBufferCreateInfo buffer_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.size = sizeof(DrawCommand),
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.size = size,
};
VmaAllocationCreateInfo draw_memory_info = {
.usage = VMA_MEMORY_USAGE_GPU_ONLY,
VmaAllocationCreateInfo memory_info = {
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
};
result = vmaCreateBuffer(render_context->allocator, &draw_buffer_info, &draw_memory_info, &draw_buffer, &draw_memory, NULL);
VkResult result = vmaCreateBuffer(allocator, &buffer_info, &memory_info, buffer, memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
result = vmaMapMemory(allocator, *memory, mapped);
if(result != VK_SUCCESS) {
vmaDestroyBuffer(allocator, *buffer, *memory);
return result;
}
return VK_SUCCESS;
}
VkResult render_thread(GLFWwindow* window, RenderContext* render_context) {
VkResult result;
UIContext ui_context;
VkBuffer colored_rect_buffer;
VmaAllocation colored_rect_memory;
result = init_pipelines(render_context->device, render_context->allocator, render_context->swapchain_extent, render_context->window_scale, render_context->render_pass, render_context->transfer_queue, render_context->transfer_pool, &ui_context);
if(result != VK_SUCCESS) {
return result;
}
FontData test_font = {};
uint32_t* test_atlas;
SymbolInfo* test_symbols;
result = load_font("tools/test.png", "tools/test.meta", &test_font, &test_symbols, &test_atlas);
if(result != VK_SUCCESS) {
return result;
}
VkBuffer text_pointer_buffer;
VmaAllocation text_pointer_memory;
FontDescriptor test_font_descriptor;
result = create_text_descriptor(render_context->device, render_context->allocator, ui_context.font_layout, ui_context.font_pool, &test_font, test_symbols, test_atlas, render_context->transfer_pool, render_context->transfer_queue, &test_font_descriptor);
if(result != VK_SUCCESS) {
return result;
}
VkBufferCreateInfo text_pointer_buffer_info = {
VkBufferCreateInfo colored_rect_buffer_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.size = sizeof(TextPointers),
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
.size = 3*sizeof(ColoredRect),
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo text_pointer_memory_info = {
VmaAllocationCreateInfo colored_rect_memory_info = {
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
};
result = vmaCreateBuffer(render_context->allocator, &text_pointer_buffer_info, &text_pointer_memory_info, &text_pointer_buffer, &text_pointer_memory, NULL);
result = vmaCreateBuffer(render_context->allocator, &colored_rect_buffer_info, &colored_rect_memory_info, &colored_rect_buffer, &colored_rect_memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
TextPointers* pointers;
ColoredRect* colored_rects;
result = vmaMapMemory(render_context->allocator, text_pointer_memory, (void**)&pointers);
result = vmaMapMemory(render_context->allocator, colored_rect_memory, (void**)&colored_rects);
if(result != VK_SUCCESS) {
return result;
}
VkBufferDeviceAddressInfo test_address_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = text_buffer,
colored_rects[0] = colored_rect(100.0, 100.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5);
colored_rects[1] = colored_rect(100.0, 100.0, 0.0, 1.0, 0.0, 1.0, 0.0, 100.0, 0.5);
colored_rects[2] = colored_rect(100.0, 100.0, 0.0, 0.0, 1.0, 1.0, 100.0, 0.0, 0.5);
vmaUnmapMemory(render_context->allocator, colored_rect_memory);
TextPointersMemory text_pointers;
VkDeviceAddress text_pointers_address;
result = create_text_pointers(10, 100, render_context->device, render_context->allocator, render_context->transfer_pool, render_context->transfer_queue, &text_pointers, &text_pointers_address);
if(result != VK_SUCCESS) {
return result;
}
VkBuffer temp_buffer;
VmaAllocation temp_memory;
void* mapped;
result = create_transfer_buffer(sizeof(String) + 2*sizeof(uint32_t), render_context->allocator, &temp_buffer, &temp_memory, (void**)&mapped);
if(result != VK_SUCCESS) {
return result;
}
String* mapped_string = (String*)mapped;
mapped_string->pos[0] = 200.0;
mapped_string->pos[1] = 200.0;
mapped_string->pos[1] = 0.5;
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->size = 200.0;
mapped_string->length = 2;
mapped_string->offset = 0;
uint32* mapped_codes = (uint32_t*)(mapped + sizeof(String));
mapped_codes[0] = 4;
mapped_codes[1] = 5;
VkCommandBuffer command_buffer = command_begin_single(render_context->device, render_context->transfer_pool);
VkBufferCopy copy_string = {
.size = sizeof(String),
.srcOffset = 0,
};
pointers->characters = vkGetBufferDeviceAddress(render_context->device, &test_address_info);
VkBufferDeviceAddressInfo draw_address_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = draw_buffer,
vkCmdCopyBuffer(command_buffer, temp_buffer, text_pointers.strings_buffer, 1, &copy_string);
VkBufferCopy copy_codes = {
.size = 2*sizeof(uint32_t),
.srcOffset = sizeof(String),
};
pointers->draw = vkGetBufferDeviceAddress(render_context->device, &draw_address_info);
vmaUnmapMemory(render_context->allocator, text_pointer_memory);
vkCmdCopyBuffer(command_buffer, temp_buffer, text_pointers.codes_buffer, 1, &copy_codes);
result = command_end_single(render_context->device, command_buffer, render_context->transfer_pool, render_context->transfer_queue);
if(result != VK_SUCCESS) {
return result;
}
VkBufferDeviceAddressInfo pointers_address_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = text_pointer_buffer,
};
vkQueueWaitIdle(render_context->transfer_queue.handle);
vmaUnmapMemory(render_context->allocator, temp_memory);
vmaDestroyBuffer(render_context->allocator, temp_buffer, temp_memory);
UILayer test_layer = {
.colored_rects = colored_rect_buffer,
.colored_rect_count = 3,
.font = test_font_descriptor,
.text_count = 2,
.texts = text_buffer,
.texts_address = vkGetBufferDeviceAddress(render_context->device, &pointers_address_info),
.chars_size = 10*sizeof(Character),
.chars = text_pointers.characters_buffer,
.string_count = 2,
.string_pointers = text_pointers_address,
.string_draw = text_pointers.draw_buffer,
.string_draw_clear = text_pointers.draw_clear_buffer,
};
fprintf(stderr, "GPU Buffer: 0x%llX\n", text_pointers_address);
while(glfwWindowShouldClose(window) == 0) {
glfwPollEvents();

@ -1035,10 +1035,44 @@ VkResult draw_frame(RenderContext* context, UIContext* ui_context, UILayer* ui_l
// UI strings compute pass
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, ui_context->ui_compute_text.pipeline);
for(uint32_t i = 0; i < ui_layer_count; i ++) {
if(ui_layers[i].text_count > 0) {
if(ui_layers[i].string_count > 0) {
VkBufferMemoryBarrier draw_barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.size = sizeof(DrawCommand),
.buffer = ui_layers[i].string_draw,
.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_2_ALL_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 1, &draw_barrier, 0, NULL);
vkCmdFillBuffer(command_buffer, ui_layers[i].string_draw, offsetof(DrawCommand, instance_count), sizeof(uint32_t), 0);
VkBufferMemoryBarrier clear_barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.size = sizeof(DrawCommand),
.buffer = ui_layers[i].string_draw,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 1, &clear_barrier, 0, NULL);
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, ui_context->ui_compute_text.layout, 0, 1, &ui_layers[i].font.set, 0, NULL);
vkCmdPushConstants(command_buffer, ui_context->ui_pipeline_text.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0, 8, &ui_layers[i].texts_address);
vkCmdDispatch(command_buffer, 1, 1, 1);
vkCmdPushConstants(command_buffer, ui_context->ui_pipeline_text.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0, 8, &ui_layers[i].string_pointers);
vkCmdDispatch(command_buffer, ui_layers[i].string_count, 1, 1);
VkBufferMemoryBarrier character_compute_barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.size = ui_layers[i].chars_size,
.buffer = ui_layers[i].chars,
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
};
VkBufferMemoryBarrier draw_compute_barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.size = sizeof(DrawCommand),
.buffer = ui_layers[i].string_draw,
.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_VERTEX_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 1, &character_compute_barrier, 0, NULL);
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 1, &draw_compute_barrier, 0, NULL);
}
}
@ -1067,12 +1101,12 @@ VkResult draw_frame(RenderContext* context, UIContext* ui_context, UILayer* ui_l
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->ui_pipeline_text.pipeline);
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->ui_pipeline_text.layout, 0, 1, &ui_context->ui_descriptor_set, 0, NULL);
for(uint32_t i = 0; i < ui_layer_count; i++) {
if(ui_layers[i].text_count > 0) {
if(ui_layers[i].string_count > 0) {
// Bind Font Descriptor
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->ui_pipeline_text.layout, 1, 1, &ui_layers[i].font.set, 0, NULL);
// Push pointers
vkCmdPushConstants(command_buffer, ui_context->ui_pipeline_text.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0, 8, &ui_layers[i].texts_address);
vkCmdDrawIndexed(command_buffer, 6, ui_layers[i].text_count, 0, 0, 0);
vkCmdPushConstants(command_buffer, ui_context->ui_pipeline_text.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0, 8, &ui_layers[i].string_pointers);
vkCmdDrawIndexedIndirect(command_buffer, ui_layers[i].string_draw, 0, 1, sizeof(DrawCommand));
}
}
/////////////////////////////////////////////////////////