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

@ -71,5 +71,11 @@ void main() {
String string = push.pointers.strings.strings[gID]; String string = push.pointers.strings.strings[gID];
uint buffer_pos = atomicAdd(push.pointers.draw.instance_count, string.len); 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) // 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; 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; 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) { if(result != VK_SUCCESS) {
return result; return result;
} }
FontData test_font = {}; VkBufferCreateInfo draw_info = {
uint32_t* test_atlas; .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
SymbolInfo* test_symbols; .size = sizeof(DrawCommand),
result = load_font("tools/test.png", "tools/test.meta", &test_font, &test_symbols, &test_atlas); .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) { if(result != VK_SUCCESS) {
return result; return result;
} }
FontDescriptor test_font_descriptor; VkBufferCreateInfo draw_clear_info = {
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); .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) { if(result != VK_SUCCESS) {
return result; return result;
} }
VkBufferCreateInfo colored_rect_buffer_info = { VkBufferCreateInfo strings_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, .size = max_strings*sizeof(String),
.size = 3*sizeof(ColoredRect), .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, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
}; };
VmaAllocationCreateInfo colored_rect_memory_info = { result = vmaCreateBuffer(allocator, &strings_info, &memory_info, &memory->strings_buffer, &memory->strings_memory, NULL);
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU, 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) { if(result != VK_SUCCESS) {
return result; 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) { if(result != VK_SUCCESS) {
return result; 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); VkBufferDeviceAddressInfo pointers_address = {
colored_rects[1] = colored_rect(100.0, 100.0, 0.0, 1.0, 0.0, 1.0, 0.0, 100.0, 0.5); .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
colored_rects[2] = colored_rect(100.0, 100.0, 0.0, 0.0, 1.0, 1.0, 100.0, 0.0, 0.5); .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, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.size = 2*sizeof(Char),
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.size = sizeof(StringPointers) +
sizeof(DrawCommand),
}; };
VmaAllocationCreateInfo temp_memory_info = {
VmaAllocationCreateInfo text_memory_info = {
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU, .usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
}; };
result = vmaCreateBuffer(allocator, &temp_buffer_info, &temp_memory_info, &temp_buffer, &temp_memory, NULL);
result = vmaCreateBuffer(render_context->allocator, &text_buffer_info, &text_memory_info, &text_buffer, &text_memory, NULL);
if(result != VK_SUCCESS) { if(result != VK_SUCCESS) {
return result; return result;
} }
Char* text; void* mapped;
result = vmaMapMemory(allocator, temp_memory, &mapped);
result = vmaMapMemory(render_context->allocator, text_memory, (void**)&text);
if(result != VK_SUCCESS) { if(result != VK_SUCCESS) {
return result; return result;
} }
text[0].color[0] = 1.0f; DrawCommand draw = {
text[0].color[1] = 1.0f; .index_count = 6,
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;
text[1].color[0] = 1.0f; memcpy(mapped + 0, &draw, sizeof(DrawCommand));
text[1].color[1] = 1.0f; StringPointers pointers = {
text[1].color[2] = 1.0f; .strings = vkGetBufferDeviceAddress(device, &strings_address),
text[1].color[3] = 1.0f; .codes = vkGetBufferDeviceAddress(device, &codes_address),
text[1].pos[0] = 400.0f; .characters = vkGetBufferDeviceAddress(device, &characters_address),
text[1].pos[1] = 200.0f; .draw = vkGetBufferDeviceAddress(device, &draw_address),
text[1].size = 200.0f; };
text[1].code = 14; 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; return VK_SUCCESS;
VmaAllocation draw_memory; }
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, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.size = sizeof(DrawCommand),
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.size = size,
}; };
VmaAllocationCreateInfo memory_info = {
VmaAllocationCreateInfo draw_memory_info = { .usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
.usage = VMA_MEMORY_USAGE_GPU_ONLY,
}; };
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) { if(result != VK_SUCCESS) {
return result; return result;
} }
VkBuffer text_pointer_buffer; FontDescriptor test_font_descriptor;
VmaAllocation text_pointer_memory; 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, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
.size = sizeof(TextPointers), .size = 3*sizeof(ColoredRect),
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
}; };
VmaAllocationCreateInfo text_pointer_memory_info = { VmaAllocationCreateInfo colored_rect_memory_info = {
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU, .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) { if(result != VK_SUCCESS) {
return result; 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) { if(result != VK_SUCCESS) {
return result; return result;
} }
VkBufferDeviceAddressInfo test_address_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, colored_rects[0] = colored_rect(100.0, 100.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5);
.buffer = text_buffer, 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); vkCmdCopyBuffer(command_buffer, temp_buffer, text_pointers.strings_buffer, 1, &copy_string);
VkBufferDeviceAddressInfo draw_address_info = { VkBufferCopy copy_codes = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, .size = 2*sizeof(uint32_t),
.buffer = draw_buffer, .srcOffset = sizeof(String),
}; };
pointers->draw = vkGetBufferDeviceAddress(render_context->device, &draw_address_info); vkCmdCopyBuffer(command_buffer, temp_buffer, text_pointers.codes_buffer, 1, &copy_codes);
vmaUnmapMemory(render_context->allocator, text_pointer_memory); 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 = { vkQueueWaitIdle(render_context->transfer_queue.handle);
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, vmaUnmapMemory(render_context->allocator, temp_memory);
.buffer = text_pointer_buffer, vmaDestroyBuffer(render_context->allocator, temp_buffer, temp_memory);
};
UILayer test_layer = { UILayer test_layer = {
.colored_rects = colored_rect_buffer, .colored_rects = colored_rect_buffer,
.colored_rect_count = 3, .colored_rect_count = 3,
.font = test_font_descriptor, .font = test_font_descriptor,
.text_count = 2, .chars_size = 10*sizeof(Character),
.texts = text_buffer, .chars = text_pointers.characters_buffer,
.texts_address = vkGetBufferDeviceAddress(render_context->device, &pointers_address_info), .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) { while(glfwWindowShouldClose(window) == 0) {
glfwPollEvents(); glfwPollEvents();

@ -1035,10 +1035,44 @@ VkResult draw_frame(RenderContext* context, UIContext* ui_context, UILayer* ui_l
// UI strings compute pass // UI strings compute pass
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, ui_context->ui_compute_text.pipeline); vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, ui_context->ui_compute_text.pipeline);
for(uint32_t i = 0; i < ui_layer_count; i ++) { 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); 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); 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, 1, 1, 1); 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); 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); 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++) { 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 // 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); 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 // 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); 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);
vkCmdDrawIndexed(command_buffer, 6, ui_layers[i].text_count, 0, 0, 0); vkCmdDrawIndexedIndirect(command_buffer, ui_layers[i].string_draw, 0, 1, sizeof(DrawCommand));
} }
} }
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////