|
|
|
@ -53,14 +53,33 @@ VkShaderModule load_shader_file(const char* path, VkDevice device) {
|
|
|
|
|
VkResult create_ui_pipeline(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VkRenderPass render_pass,
|
|
|
|
|
VkDescriptorSetLayout font_samplers_layout,
|
|
|
|
|
VkDescriptorSetLayout font_textures_layout,
|
|
|
|
|
VkPipelineShaderStageCreateInfo* shader_stages,
|
|
|
|
|
uint32_t shader_stage_count,
|
|
|
|
|
VkPipelineVertexInputStateCreateInfo input_info,
|
|
|
|
|
VkPipelineLayoutCreateInfo layout_info,
|
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo input_assembly_info,
|
|
|
|
|
GraphicsPipeline* pipeline) {
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
VkPushConstantRange push_constants[] = {
|
|
|
|
|
{
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
|
|
|
.size = 16,
|
|
|
|
|
.offset = 0,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetLayout set_layouts[] = {font_samplers_layout, font_textures_layout};
|
|
|
|
|
|
|
|
|
|
VkPipelineLayoutCreateInfo layout_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
|
|
|
.pushConstantRangeCount = sizeof(push_constants)/sizeof(VkPushConstantRange),
|
|
|
|
|
.pPushConstantRanges = push_constants,
|
|
|
|
|
.setLayoutCount = sizeof(set_layouts)/sizeof(VkDescriptorSetLayout),
|
|
|
|
|
.pSetLayouts = set_layouts,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreatePipelineLayout(device, &layout_info, 0, &pipeline->layout);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
@ -176,12 +195,12 @@ VkResult create_ui_pipeline(
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult create_ui_colored_rect_pipeline(VkDevice device, VkRenderPass render_pass, VkDescriptorSetLayout ui_descriptor_layout, GraphicsPipeline* pipeline) {
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file("shader_src/ui_colored_rect.vert.spv", device);
|
|
|
|
|
VkResult create_ui_rect_pipeline(VkDevice device, VkRenderPass render_pass, VkDescriptorSetLayout font_samplers_layout, VkDescriptorSetLayout font_textures_layout, GraphicsPipeline* pipeline) {
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file("shader_src/ui_rect.vert.spv", device);
|
|
|
|
|
if(vert_shader == VK_NULL_HANDLE) {
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file("shader_src/ui_colored_rect.frag.spv", device);
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file("shader_src/ui_rect.frag.spv", device);
|
|
|
|
|
if(frag_shader == VK_NULL_HANDLE) {
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
@ -210,26 +229,13 @@ VkResult create_ui_colored_rect_pipeline(VkDevice device, VkRenderPass render_pa
|
|
|
|
|
.vertexAttributeDescriptionCount = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPushConstantRange push_constant = {
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
|
|
.size = 8,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineLayoutCreateInfo layout_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
|
|
|
.setLayoutCount = 1,
|
|
|
|
|
.pSetLayouts = &ui_descriptor_layout,
|
|
|
|
|
.pPushConstantRanges = &push_constant,
|
|
|
|
|
.pushConstantRangeCount = 1,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
|
|
|
|
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
|
|
|
|
|
.primitiveRestartEnable = VK_FALSE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkResult result = create_ui_pipeline(device, render_pass, shader_stages, sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), input_info, layout_info, input_assembly_info, pipeline);
|
|
|
|
|
VkResult result = create_ui_pipeline(device, render_pass, font_samplers_layout, font_textures_layout, shader_stages, sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), input_info, input_assembly_info, pipeline);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
@ -237,7 +243,7 @@ VkResult create_ui_colored_rect_pipeline(VkDevice device, VkRenderPass render_pa
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDescriptorSetLayout ui_descriptor_layout, VkDescriptorSetLayout font_layout, GraphicsPipeline* pipeline, ComputePipeline* compute) {
|
|
|
|
|
VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDescriptorSetLayout font_samplers_layout, VkDescriptorSetLayout font_textures_layout, GraphicsPipeline* pipeline, ComputePipeline* compute) {
|
|
|
|
|
VkResult result;
|
|
|
|
|
VkShaderModule compute_shader = load_shader_file("shader_src/ui_text.comp.spv", device);
|
|
|
|
|
if(compute_shader == VK_NULL_HANDLE) {
|
|
|
|
@ -252,18 +258,14 @@ VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDe
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPushConstantRange push_constant = {
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
|
|
.size = 8,
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
|
|
|
|
.size = 16,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetLayout compute_descriptors[] = {font_layout};
|
|
|
|
|
|
|
|
|
|
VkPipelineLayoutCreateInfo compute_layout_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
|
|
|
.pushConstantRangeCount = 1,
|
|
|
|
|
.pPushConstantRanges = &push_constant,
|
|
|
|
|
.setLayoutCount = sizeof(compute_descriptors)/sizeof(VkDescriptorSetLayout),
|
|
|
|
|
.pSetLayouts = compute_descriptors,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreatePipelineLayout(device, &compute_layout_info, NULL, &compute->layout);
|
|
|
|
@ -320,23 +322,13 @@ VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDe
|
|
|
|
|
.vertexAttributeDescriptionCount = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetLayout all_layouts[] = {ui_descriptor_layout, font_layout};
|
|
|
|
|
|
|
|
|
|
VkPipelineLayoutCreateInfo layout_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
|
|
|
.setLayoutCount = sizeof(all_layouts)/sizeof(VkDescriptorSetLayout),
|
|
|
|
|
.pSetLayouts = all_layouts,
|
|
|
|
|
.pPushConstantRanges = &push_constant,
|
|
|
|
|
.pushConstantRangeCount = 1,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
|
|
|
|
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
|
|
|
|
|
.primitiveRestartEnable = VK_FALSE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = create_ui_pipeline(device, render_pass, shader_stages, sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), input_info, layout_info, input_assembly_info, pipeline);
|
|
|
|
|
result = create_ui_pipeline(device, render_pass, font_samplers_layout, font_textures_layout, shader_stages, sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), input_info, input_assembly_info, pipeline);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
@ -344,219 +336,36 @@ VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDe
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult create_font_descriptor_pools(VkDevice device, uint32_t max_sets, VkDescriptorPool* font_pool, VkDescriptorSetLayout* font_layout) {
|
|
|
|
|
VkResult result;
|
|
|
|
|
VkDescriptorPoolSize font_pool_sizes[] = {
|
|
|
|
|
{
|
|
|
|
|
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
|
|
|
.descriptorCount = 1,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
|
|
|
.descriptorCount = 1,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkDescriptorPoolCreateInfo font_pool_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
|
|
|
|
.pPoolSizes = font_pool_sizes,
|
|
|
|
|
.poolSizeCount = sizeof(font_pool_sizes)/sizeof(VkDescriptorPoolSize),
|
|
|
|
|
.maxSets = max_sets,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreateDescriptorPool(device, &font_pool_info, NULL, font_pool);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetLayoutBinding font_descriptor_bindings[] = {
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
|
|
|
.descriptorCount = 1,
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.binding = 1,
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
|
|
|
.descriptorCount = 1,
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetLayoutCreateInfo font_descriptor_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
|
|
|
|
.pBindings = font_descriptor_bindings,
|
|
|
|
|
.bindingCount = sizeof(font_descriptor_bindings)/sizeof(VkDescriptorSetLayoutBinding),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreateDescriptorSetLayout(device, &font_descriptor_info, NULL, font_layout);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult create_text_pointers(
|
|
|
|
|
VkResult create_layer(
|
|
|
|
|
uint32_t max_strings,
|
|
|
|
|
uint32_t max_characters,
|
|
|
|
|
uint32_t max_rects,
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VmaAllocator allocator,
|
|
|
|
|
VkCommandPool transfer_pool,
|
|
|
|
|
Queue transfer_queue,
|
|
|
|
|
TextPointersMemory* memory,
|
|
|
|
|
UILayerStorage* memory,
|
|
|
|
|
VkDeviceAddress* address) {
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkBufferCreateInfo strings_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
|
|
|
.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,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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(allocator, &codes_info, &memory_info, &memory->codes_buffer, &memory->codes_memory, NULL);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 = vmaCreateBuffer(allocator, &characters_info, &memory_info, &memory->characters_buffer, &memory->characters_memory, NULL);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkBufferDeviceAddressInfo pointers_address = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
|
|
|
|
|
.buffer = memory->pointers_buffer,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkBuffer temp_buffer;
|
|
|
|
|
VmaAllocation temp_memory;
|
|
|
|
|
VkBufferCreateInfo temp_buffer_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
|
|
|
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
|
|
|
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
|
|
|
|
.size = sizeof(StringPointers) +
|
|
|
|
|
sizeof(DrawCommand),
|
|
|
|
|
};
|
|
|
|
|
VmaAllocationCreateInfo temp_memory_info = {
|
|
|
|
|
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
|
|
|
|
|
};
|
|
|
|
|
result = vmaCreateBuffer(allocator, &temp_buffer_info, &temp_memory_info, &temp_buffer, &temp_memory, NULL);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* mapped;
|
|
|
|
|
result = vmaMapMemory(allocator, temp_memory, &mapped);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DrawCommand draw = {
|
|
|
|
|
.vertex_count = 6,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
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, ©_draw);
|
|
|
|
|
VkBufferCopy copy_pointers = {
|
|
|
|
|
.size = sizeof(StringPointers),
|
|
|
|
|
.srcOffset = sizeof(DrawCommand),
|
|
|
|
|
};
|
|
|
|
|
vkCmdCopyBuffer(command_buffer, temp_buffer, memory->pointers_buffer, 1, ©_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);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayout layout, VkDescriptorPool pool,VkCommandPool transfer_pool, Queue transfer_queue, FT_Library library, const char* ttf_file, uint32_t size, VkBool32 antialias, uint32_t** charmap, Font* descriptor) {
|
|
|
|
|
VkResult load_font(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VmaAllocator allocator,
|
|
|
|
|
VkBuffer font_infos,
|
|
|
|
|
VkDescriptorSet font_samplers,
|
|
|
|
|
VkDescriptorSet font_textures,
|
|
|
|
|
uint32_t index,
|
|
|
|
|
VkCommandPool transfer_pool,
|
|
|
|
|
Queue transfer_queue,
|
|
|
|
|
FT_Library library,
|
|
|
|
|
const char* ttf_file,
|
|
|
|
|
uint32_t size,
|
|
|
|
|
VkBool32 antialias,
|
|
|
|
|
uint32_t** charmap,
|
|
|
|
|
FontStorage* memory) {
|
|
|
|
|
FT_Face face;
|
|
|
|
|
|
|
|
|
|
int error;
|
|
|
|
@ -572,7 +381,7 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
|
|
|
|
|
|
|
|
|
|
uint32_t* tmp_charmap = malloc(sizeof(uint32_t)*face->num_glyphs);
|
|
|
|
|
SymbolInfo* symbols = malloc(sizeof(SymbolInfo)*face->num_glyphs);
|
|
|
|
|
FontUniform uniform;
|
|
|
|
|
Font info;
|
|
|
|
|
|
|
|
|
|
uint32_t glyph_index;
|
|
|
|
|
uint32_t max_height = 0;
|
|
|
|
@ -607,9 +416,9 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
|
|
|
|
|
c = FT_Get_Next_Char(face, c, &glyph_index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uniform.width = max_width;
|
|
|
|
|
uniform.height = max_height;
|
|
|
|
|
uniform.num_symbols = symbol_count;
|
|
|
|
|
info.width = max_width;
|
|
|
|
|
info.height = max_height;
|
|
|
|
|
info.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);
|
|
|
|
@ -636,53 +445,29 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
VkDescriptorSetAllocateInfo set_allocate_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
|
|
|
|
.pSetLayouts = &layout,
|
|
|
|
|
.descriptorSetCount = 1,
|
|
|
|
|
.descriptorPool = pool,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkAllocateDescriptorSets(device, &set_allocate_info, &descriptor->set);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return 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)*uniform.num_symbols,
|
|
|
|
|
.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, &descriptor->symbols, &descriptor->symbol_memory, NULL);
|
|
|
|
|
result = vmaCreateBuffer(allocator, &symbol_buffer_info, &symbol_memory_info, &memory->symbols, &memory->symbol_memory, NULL);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkBufferCreateInfo uniform_buffer_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
|
|
|
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
|
|
|
|
.size = sizeof(FontUniform),
|
|
|
|
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VmaAllocationCreateInfo uniform_memory_info = {
|
|
|
|
|
.usage = VMA_MEMORY_USAGE_GPU_ONLY,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vmaCreateBuffer(allocator, &uniform_buffer_info, &uniform_memory_info, &descriptor->uniform, &descriptor->uniform_memory, NULL);
|
|
|
|
|
VkImageCreateInfo image_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
|
|
|
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
|
|
|
|
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
|
|
|
|
.extent.depth = 1,
|
|
|
|
|
.extent.width = uniform.width,
|
|
|
|
|
.extent.height = uniform.height,
|
|
|
|
|
.extent.width = info.width,
|
|
|
|
|
.extent.height = info.height,
|
|
|
|
|
.mipLevels = 1,
|
|
|
|
|
.arrayLayers = uniform.num_symbols,
|
|
|
|
|
.arrayLayers = info.num_symbols,
|
|
|
|
|
.format = VK_FORMAT_R8G8B8A8_SRGB,
|
|
|
|
|
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
|
|
|
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
|
|
@ -694,7 +479,7 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
|
|
|
|
|
.usage = VMA_MEMORY_USAGE_GPU_ONLY,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vmaCreateImage(allocator, &image_info, &image_memory_info, &descriptor->image, &descriptor->image_memory, NULL);
|
|
|
|
|
result = vmaCreateImage(allocator, &image_info, &image_memory_info, &memory->image, &memory->image_memory, NULL);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
@ -703,7 +488,7 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
|
|
|
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
|
|
|
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
|
|
|
|
.size = sizeof(FontUniform) + image_size*uniform.num_symbols + sizeof(SymbolInfo)*uniform.num_symbols,
|
|
|
|
|
.size = sizeof(Font) + image_size*info.num_symbols + sizeof(SymbolInfo)*info.num_symbols,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VmaAllocationCreateInfo staging_memory_info = {
|
|
|
|
@ -722,66 +507,66 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
memcpy(mapped_staging + image_size*uniform.num_symbols + sizeof(FontUniform), symbols, sizeof(SymbolInfo)*uniform.num_symbols);
|
|
|
|
|
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 = descriptor->symbols,
|
|
|
|
|
.buffer = memory->symbols,
|
|
|
|
|
};
|
|
|
|
|
uniform.symbol_list = vkGetBufferDeviceAddress(device, &address_info);
|
|
|
|
|
memcpy(mapped_staging + image_size*uniform.num_symbols, &uniform, sizeof(FontUniform));
|
|
|
|
|
memcpy(mapped_staging, images, image_size*uniform.num_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 uniform_copy_info = {
|
|
|
|
|
.size = sizeof(FontUniform),
|
|
|
|
|
.srcOffset = image_size*uniform.num_symbols,
|
|
|
|
|
.dstOffset = 0,
|
|
|
|
|
VkBufferCopy info_copy = {
|
|
|
|
|
.size = sizeof(Font),
|
|
|
|
|
.srcOffset = image_size*info.num_symbols,
|
|
|
|
|
.dstOffset = index*sizeof(Font),
|
|
|
|
|
};
|
|
|
|
|
vkCmdCopyBuffer(command_buffer, staging_buffer, descriptor->uniform, 1, &uniform_copy_info);
|
|
|
|
|
vkCmdCopyBuffer(command_buffer, staging_buffer, font_infos, 1, &info_copy);
|
|
|
|
|
|
|
|
|
|
VkBufferCopy symbol_copy_info = {
|
|
|
|
|
.size = sizeof(SymbolInfo)*uniform.num_symbols,
|
|
|
|
|
.srcOffset = image_size*uniform.num_symbols + sizeof(FontUniform),
|
|
|
|
|
VkBufferCopy symbol_copy = {
|
|
|
|
|
.size = sizeof(SymbolInfo)*info.num_symbols,
|
|
|
|
|
.srcOffset = image_size*info.num_symbols + sizeof(Font),
|
|
|
|
|
.dstOffset = 0,
|
|
|
|
|
};
|
|
|
|
|
vkCmdCopyBuffer(command_buffer, staging_buffer, descriptor->symbols, 1, &symbol_copy_info);
|
|
|
|
|
vkCmdCopyBuffer(command_buffer, staging_buffer, memory->symbols, 1, &symbol_copy);
|
|
|
|
|
|
|
|
|
|
VkImageMemoryBarrier first_barrier = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
|
.image = descriptor->image,
|
|
|
|
|
.image = memory->image,
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
|
|
|
.subresourceRange.levelCount = 1,
|
|
|
|
|
.subresourceRange.layerCount = uniform.num_symbols,
|
|
|
|
|
.subresourceRange.layerCount = info.num_symbols,
|
|
|
|
|
.srcAccessMask = 0,
|
|
|
|
|
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
|
};
|
|
|
|
|
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, &first_barrier);
|
|
|
|
|
|
|
|
|
|
VkBufferImageCopy image_copy = {
|
|
|
|
|
.imageSubresource.layerCount = uniform.num_symbols,
|
|
|
|
|
.imageSubresource.layerCount = info.num_symbols,
|
|
|
|
|
.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
|
|
|
.imageExtent = image_info.extent,
|
|
|
|
|
};
|
|
|
|
|
vkCmdCopyBufferToImage(command_buffer, staging_buffer, descriptor->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy);
|
|
|
|
|
vkCmdCopyBufferToImage(command_buffer, staging_buffer, memory->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy);
|
|
|
|
|
|
|
|
|
|
VkImageMemoryBarrier second_barrier = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
|
.image = descriptor->image,
|
|
|
|
|
.image = memory->image,
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
|
|
|
.subresourceRange.levelCount = 1,
|
|
|
|
|
.subresourceRange.layerCount = uniform.num_symbols,
|
|
|
|
|
.subresourceRange.layerCount = info.num_symbols,
|
|
|
|
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
|
|
|
|
};
|
|
|
|
@ -795,18 +580,18 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
|
|
|
|
|
|
|
|
|
|
VkImageViewCreateInfo view_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
|
|
|
|
.image = descriptor->image,
|
|
|
|
|
.image = memory->image,
|
|
|
|
|
.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
|
|
|
|
.format = VK_FORMAT_R8G8B8A8_SRGB,
|
|
|
|
|
.subresourceRange = {
|
|
|
|
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
|
|
|
.layerCount = uniform.num_symbols,
|
|
|
|
|
.layerCount = info.num_symbols,
|
|
|
|
|
.baseMipLevel = 0,
|
|
|
|
|
.levelCount = 1,
|
|
|
|
|
.baseArrayLayer = 0,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
result = vkCreateImageView(device, &view_info, NULL, &descriptor->view);
|
|
|
|
|
result = vkCreateImageView(device, &view_info, NULL, &memory->view);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
@ -819,171 +604,199 @@ VkResult load_font(VkDevice device, VmaAllocator allocator, VkDescriptorSetLayou
|
|
|
|
|
.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
|
|
|
|
.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
|
|
|
|
};
|
|
|
|
|
result = vkCreateSampler(device, &sampler_info, NULL, &descriptor->sampler);
|
|
|
|
|
result = vkCreateSampler(device, &sampler_info, NULL, &memory->sampler);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkDescriptorBufferInfo desc_uniform_info = {
|
|
|
|
|
.offset = 0,
|
|
|
|
|
.range = sizeof(FontUniform),
|
|
|
|
|
.buffer = descriptor->uniform,
|
|
|
|
|
VkDescriptorImageInfo desc_sampler_info = {
|
|
|
|
|
.sampler = memory->sampler,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkDescriptorImageInfo desc_image_info = {
|
|
|
|
|
.sampler = descriptor->sampler,
|
|
|
|
|
VkDescriptorImageInfo desc_texture_info = {
|
|
|
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
|
|
|
.imageView = descriptor->view,
|
|
|
|
|
.imageView = memory->view,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkWriteDescriptorSet descriptor_writes[] = {
|
|
|
|
|
{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
|
|
|
.dstSet = descriptor->set,
|
|
|
|
|
.dstSet = font_textures,
|
|
|
|
|
.dstBinding = 0,
|
|
|
|
|
.dstArrayElement = 0,
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
|
|
|
.dstArrayElement = index,
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
|
|
|
.descriptorCount = 1,
|
|
|
|
|
.pBufferInfo = &desc_uniform_info,
|
|
|
|
|
.pImageInfo = &desc_texture_info,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
|
|
|
.dstSet = descriptor->set,
|
|
|
|
|
.dstBinding = 1,
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
|
|
|
.dstSet = font_samplers,
|
|
|
|
|
.dstBinding = 0,
|
|
|
|
|
.dstArrayElement = index,
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
|
|
|
.descriptorCount = 1,
|
|
|
|
|
.pImageInfo = &desc_image_info,
|
|
|
|
|
}
|
|
|
|
|
.pImageInfo = &desc_sampler_info,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
vkUpdateDescriptorSets(device, 2, descriptor_writes, 0, NULL);
|
|
|
|
|
vkUpdateDescriptorSets(device, sizeof(descriptor_writes)/sizeof(VkWriteDescriptorSet), descriptor_writes, 0, NULL);
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult create_ui_descriptor_set(VkDevice device, VmaAllocator allocator, VkExtent2D swapchain_extent, vec2 window_scale, VkDescriptorSetLayout* ui_descriptor_layout, VkDescriptorPool* ui_descriptor_pool, VkDescriptorSet* ui_descriptor_set, VmaAllocation* ui_descriptor_memory, VkBuffer* ui_descriptor_buffer) {
|
|
|
|
|
VkDescriptorSetLayoutBinding ui_descriptor_bindings[] = {
|
|
|
|
|
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 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,
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
|
|
|
.descriptorCount = 1,
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
|
|
}
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
|
|
|
.descriptorCount = max_fonts,
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkDescriptorBindingFlags bindless_flags[] = {
|
|
|
|
|
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetLayoutBindingFlagsCreateInfo font_sampler_bindings_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
|
|
|
|
.bindingCount = sizeof(font_sampler_bindings)/sizeof(VkDescriptorSetLayoutBinding),
|
|
|
|
|
.pBindingFlags = bindless_flags,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetLayoutCreateInfo ui_descriptor_info = {
|
|
|
|
|
VkDescriptorSetLayoutCreateInfo font_sampler_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
|
|
|
|
.pBindings = ui_descriptor_bindings,
|
|
|
|
|
.bindingCount = sizeof(ui_descriptor_bindings)/sizeof(VkDescriptorSetLayoutBinding),
|
|
|
|
|
.pBindings = font_sampler_bindings,
|
|
|
|
|
.bindingCount = sizeof(font_sampler_bindings)/sizeof(VkDescriptorSetLayoutBinding),
|
|
|
|
|
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
|
|
|
|
|
.pNext = &font_sampler_bindings_info,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
result = vkCreateDescriptorSetLayout(device, &ui_descriptor_info, NULL, ui_descriptor_layout);
|
|
|
|
|
|
|
|
|
|
result = vkCreateDescriptorSetLayout(device, &font_sampler_info, NULL, font_sampler_layout);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkDescriptorPoolSize pool_size = {
|
|
|
|
|
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
|
|
|
.descriptorCount = 1,
|
|
|
|
|
VkDescriptorSetLayoutBinding font_texture_bindings[] = {
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
|
|
|
.descriptorCount = max_fonts,
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkDescriptorPoolCreateInfo ui_pool_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
|
|
|
|
.pPoolSizes = &pool_size,
|
|
|
|
|
.poolSizeCount = 1,
|
|
|
|
|
.maxSets = 1,
|
|
|
|
|
VkDescriptorSetLayoutBindingFlagsCreateInfo font_texture_bindings_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
|
|
|
|
.bindingCount = sizeof(font_texture_bindings)/sizeof(VkDescriptorSetLayoutBinding),
|
|
|
|
|
.pBindingFlags = bindless_flags,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreateDescriptorPool(device, &ui_pool_info, NULL, ui_descriptor_pool);
|
|
|
|
|
VkDescriptorSetLayoutCreateInfo font_texture_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
|
|
|
|
.pBindings = font_texture_bindings,
|
|
|
|
|
.bindingCount = sizeof(font_texture_bindings)/sizeof(VkDescriptorSetLayoutBinding),
|
|
|
|
|
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
|
|
|
|
|
.pNext = &font_texture_bindings_info,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreateDescriptorSetLayout(device, &font_texture_info, NULL, font_texture_layout);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetAllocateInfo ui_descriptor_allocate_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
|
|
|
|
.pSetLayouts = ui_descriptor_layout,
|
|
|
|
|
.descriptorSetCount = 1,
|
|
|
|
|
.descriptorPool = *ui_descriptor_pool,
|
|
|
|
|
VkDescriptorPoolSize font_pool_sizes[] = {
|
|
|
|
|
{
|
|
|
|
|
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
|
|
|
.descriptorCount = max_fonts,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
|
|
|
.descriptorCount = max_fonts,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
VkDescriptorPoolCreateInfo font_pool_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
|
|
|
|
.pPoolSizes = font_pool_sizes,
|
|
|
|
|
.poolSizeCount = 2,
|
|
|
|
|
.maxSets = 2,
|
|
|
|
|
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkAllocateDescriptorSets(device, &ui_descriptor_allocate_info, ui_descriptor_set);
|
|
|
|
|
result = vkCreateDescriptorPool(device, &font_pool_info, NULL, font_pool);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkBufferCreateInfo ui_uniform_buffer_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
|
|
|
.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
|
|
|
|
.size = sizeof(UIUniform),
|
|
|
|
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
|
|
|
|
uint32_t max_font_binding = max_fonts - 1;
|
|
|
|
|
VkDescriptorSetVariableDescriptorCountAllocateInfo count_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
|
|
|
|
|
.descriptorSetCount = 1,
|
|
|
|
|
.pDescriptorCounts = &max_font_binding,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VmaAllocationCreateInfo ui_uniform_memory_info = {
|
|
|
|
|
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
|
|
|
|
|
VkDescriptorSetAllocateInfo allocate_font_samplers = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
|
|
|
|
.pSetLayouts = font_sampler_layout,
|
|
|
|
|
.descriptorSetCount = 1,
|
|
|
|
|
.descriptorPool = *font_pool,
|
|
|
|
|
.pNext = &count_info,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vmaCreateBuffer(allocator, &ui_uniform_buffer_info, &ui_uniform_memory_info, ui_descriptor_buffer, ui_descriptor_memory, NULL);
|
|
|
|
|
VkDescriptorSetAllocateInfo allocate_font_textures = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
|
|
|
|
.pSetLayouts = font_texture_layout,
|
|
|
|
|
.descriptorSetCount = 1,
|
|
|
|
|
.descriptorPool = *font_pool,
|
|
|
|
|
.pNext = &count_info,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkAllocateDescriptorSets(device, &allocate_font_samplers, font_samplers);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* mapped;
|
|
|
|
|
result = vmaMapMemory(allocator, *ui_descriptor_memory, &mapped);
|
|
|
|
|
result = vkAllocateDescriptorSets(device, &allocate_font_textures, font_textures);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
UIUniform ui_uniform;
|
|
|
|
|
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(ui_uniform.screen);
|
|
|
|
|
glm_translate(ui_uniform.screen, screen_offset);
|
|
|
|
|
glm_scale(ui_uniform.screen, screen_scale);
|
|
|
|
|
memcpy(mapped, &ui_uniform, sizeof(ui_uniform));
|
|
|
|
|
vmaUnmapMemory(allocator, *ui_descriptor_memory);
|
|
|
|
|
|
|
|
|
|
VkDescriptorBufferInfo ui_uniform_info = {
|
|
|
|
|
.offset = 0,
|
|
|
|
|
.range = sizeof(ui_uniform),
|
|
|
|
|
.buffer = *ui_descriptor_buffer,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkWriteDescriptorSet ui_uniform_write = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
|
|
|
.dstSet = *ui_descriptor_set,
|
|
|
|
|
.dstBinding = 0,
|
|
|
|
|
.dstArrayElement = 0,
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
|
|
|
.descriptorCount = 1,
|
|
|
|
|
.pBufferInfo = &ui_uniform_info,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
vkUpdateDescriptorSets(device, 1, &ui_uniform_write, 0, NULL);
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult init_pipelines(VkDevice device, VmaAllocator allocator, VkExtent2D swapchain_extent, vec2 window_scale, VkRenderPass render_pass, UIContext* context) {
|
|
|
|
|
VkResult create_ui_context(VkDevice device, VmaAllocator allocator, VkRenderPass render_pass, UIContextStorage* memory) {
|
|
|
|
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
result = create_ui_descriptor_set(device, allocator, swapchain_extent, window_scale, &context->ui_descriptor_layout, &context->ui_descriptor_pool, &context->ui_descriptor_set, &context->ui_descriptor_memory, &context->ui_descriptor_buffer);
|
|
|
|
|
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_colored_rect_pipeline(device, render_pass, context->ui_descriptor_layout, &context->ui_pipeline_rect);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = create_font_descriptor_pools(device, 10, &context->font_pool, &context->font_layout);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = create_ui_text_pipeline(device, render_pass, context->ui_descriptor_layout, context->font_layout, &context->ui_pipeline_text, &context->ui_compute_text);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|