|
|
|
@ -56,12 +56,88 @@ VkResult create_ui_pipeline(
|
|
|
|
|
VkRenderPass render_pass,
|
|
|
|
|
VkDescriptorSetLayout font_samplers_layout,
|
|
|
|
|
VkDescriptorSetLayout font_textures_layout,
|
|
|
|
|
VkPipelineShaderStageCreateInfo* shader_stages,
|
|
|
|
|
uint32_t shader_stage_count,
|
|
|
|
|
VkPipelineVertexInputStateCreateInfo input_info,
|
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo input_assembly_info,
|
|
|
|
|
GraphicsPipeline* pipeline) {
|
|
|
|
|
GraphicsPipeline* pipeline,
|
|
|
|
|
ComputePipeline* compute) {
|
|
|
|
|
VkResult result;
|
|
|
|
|
VkShaderModule compute_shader = load_shader_file("shader_src/string.comp.spv", device);
|
|
|
|
|
if(compute_shader == VK_NULL_HANDLE) {
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPipelineShaderStageCreateInfo compute_shader_stage = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
|
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
|
|
|
|
|
.pName = "main",
|
|
|
|
|
.module = compute_shader,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPushConstantRange push_constant = {
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
|
|
|
|
.size = 16,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineLayoutCreateInfo compute_layout_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
|
|
|
.pushConstantRangeCount = 1,
|
|
|
|
|
.pPushConstantRanges = &push_constant,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreatePipelineLayout(device, &compute_layout_info, NULL, &compute->layout);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkComputePipelineCreateInfo compute_pipeline_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
|
|
|
|
.layout = compute->layout,
|
|
|
|
|
.stage = compute_shader_stage,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &compute_pipeline_info, NULL, &compute->pipeline);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file("shader_src/ui.vert.spv", device);
|
|
|
|
|
if(vert_shader == VK_NULL_HANDLE) {
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file("shader_src/ui.frag.spv", device);
|
|
|
|
|
if(frag_shader == VK_NULL_HANDLE) {
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPipelineShaderStageCreateInfo shader_stages[] = {
|
|
|
|
|
{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
|
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
|
|
.module = vert_shader,
|
|
|
|
|
.pName = "main",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
|
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
|
|
|
.module = frag_shader,
|
|
|
|
|
.pName = "main",
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkVertexInputBindingDescription bindings[] = {};
|
|
|
|
|
VkVertexInputAttributeDescription attributes[] = {};
|
|
|
|
|
|
|
|
|
|
VkPipelineVertexInputStateCreateInfo input_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
|
|
|
|
.pVertexBindingDescriptions = bindings,
|
|
|
|
|
.vertexBindingDescriptionCount = sizeof(bindings)/sizeof(VkVertexInputBindingDescription),
|
|
|
|
|
.pVertexAttributeDescriptions = attributes,
|
|
|
|
|
.vertexAttributeDescriptionCount = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
|
|
|
|
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
|
|
|
|
|
.primitiveRestartEnable = VK_FALSE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPushConstantRange push_constants[] = {
|
|
|
|
|
{
|
|
|
|
@ -173,7 +249,7 @@ VkResult create_ui_pipeline(
|
|
|
|
|
|
|
|
|
|
VkGraphicsPipelineCreateInfo draw_pipeline_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
|
|
|
|
.stageCount = shader_stage_count,
|
|
|
|
|
.stageCount = sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo),
|
|
|
|
|
.pStages = shader_stages,
|
|
|
|
|
.pVertexInputState = &input_info,
|
|
|
|
|
.pInputAssemblyState = &input_assembly_info,
|
|
|
|
@ -193,154 +269,14 @@ VkResult create_ui_pipeline(
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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_rect.frag.spv", device);
|
|
|
|
|
if(frag_shader == VK_NULL_HANDLE) {
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
VkPipelineShaderStageCreateInfo shader_stages[] = {
|
|
|
|
|
{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
|
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
|
|
.module = vert_shader,
|
|
|
|
|
.pName = "main",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
|
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
|
|
|
.module = frag_shader,
|
|
|
|
|
.pName = "main",
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkVertexInputBindingDescription bindings[] = {};
|
|
|
|
|
VkVertexInputAttributeDescription attributes[] = {};
|
|
|
|
|
VkPipelineVertexInputStateCreateInfo input_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
|
|
|
|
.pVertexBindingDescriptions = bindings,
|
|
|
|
|
.vertexBindingDescriptionCount = sizeof(bindings)/sizeof(VkVertexInputBindingDescription),
|
|
|
|
|
.pVertexAttributeDescriptions = attributes,
|
|
|
|
|
.vertexAttributeDescriptionCount = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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, 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPipelineShaderStageCreateInfo compute_shader_stage = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
|
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
|
|
|
|
|
.pName = "main",
|
|
|
|
|
.module = compute_shader,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPushConstantRange push_constant = {
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
|
|
|
|
.size = 16,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineLayoutCreateInfo compute_layout_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
|
|
|
.pushConstantRangeCount = 1,
|
|
|
|
|
.pPushConstantRanges = &push_constant,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreatePipelineLayout(device, &compute_layout_info, NULL, &compute->layout);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkComputePipelineCreateInfo compute_pipeline_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
|
|
|
|
.layout = compute->layout,
|
|
|
|
|
.stage = compute_shader_stage,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &compute_pipeline_info, NULL, &compute->pipeline);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file("shader_src/ui_text.vert.spv", device);
|
|
|
|
|
if(vert_shader == VK_NULL_HANDLE) {
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file("shader_src/ui_text.frag.spv", device);
|
|
|
|
|
if(frag_shader == VK_NULL_HANDLE) {
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: add a compute stage before the shader stages that sets up the draw buffer and commands for the characters based off of strings + positions
|
|
|
|
|
// 1. Reserve a buffer for array of draw command params + Char on the GPU
|
|
|
|
|
// 2. Reserve a buffer for Text on the GPU
|
|
|
|
|
VkPipelineShaderStageCreateInfo shader_stages[] = {
|
|
|
|
|
{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
|
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
|
|
.module = vert_shader,
|
|
|
|
|
.pName = "main",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
|
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
|
|
|
.module = frag_shader,
|
|
|
|
|
.pName = "main",
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkVertexInputBindingDescription bindings[] = {};
|
|
|
|
|
VkVertexInputAttributeDescription attributes[] = {};
|
|
|
|
|
|
|
|
|
|
VkPipelineVertexInputStateCreateInfo input_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
|
|
|
|
.pVertexBindingDescriptions = bindings,
|
|
|
|
|
.vertexBindingDescriptionCount = sizeof(bindings)/sizeof(VkVertexInputBindingDescription),
|
|
|
|
|
.pVertexAttributeDescriptions = attributes,
|
|
|
|
|
.vertexAttributeDescriptionCount = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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, 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult create_layer(
|
|
|
|
|
uint32_t max_strings,
|
|
|
|
|
uint32_t max_glyphs,
|
|
|
|
|
uint32_t max_rects,
|
|
|
|
|
uint32_t max_codes,
|
|
|
|
|
uint32_t max_drawables,
|
|
|
|
|
uint32_t font_index,
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VmaAllocator allocator,
|
|
|
|
@ -349,15 +285,14 @@ VkResult create_layer(
|
|
|
|
|
UILayerStorage* memory) {
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
memory->max_string = max_strings;
|
|
|
|
|
memory->max_glyphs = max_glyphs;
|
|
|
|
|
memory->max_rects = max_rects;
|
|
|
|
|
memory->max_strings = max_strings;
|
|
|
|
|
memory->max_codes = max_codes;
|
|
|
|
|
memory->max_drawables = max_drawables;
|
|
|
|
|
|
|
|
|
|
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, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, sizeof(UILayer), &memory->layer, &memory->layer_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));
|
|
|
|
|
VK_RESULT(create_storage_buffer(allocator, 0, sizeof(UIDrawable)*max_drawables, &memory->drawables, &memory->drawables_memory));
|
|
|
|
|
VK_RESULT(create_storage_buffer(allocator, 0, sizeof(uint32_t)*max_codes, &memory->codes, &memory->codes_memory));
|
|
|
|
|
|
|
|
|
|
VkBuffer transfer;
|
|
|
|
|
VmaAllocation transfer_memory;
|
|
|
|
@ -367,31 +302,25 @@ VkResult create_layer(
|
|
|
|
|
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->drawables = buffer_address(device, memory->drawables);
|
|
|
|
|
|
|
|
|
|
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->draw.first_vertex = 0;
|
|
|
|
|
mapped->draw.vertex_count = 6;
|
|
|
|
|
mapped->draw.first_instance = 0;
|
|
|
|
|
mapped->draw.instance_count = 0;
|
|
|
|
|
|
|
|
|
|
mapped->dispatch_strings.x = 0;
|
|
|
|
|
mapped->dispatch_strings.y = 1;
|
|
|
|
|
mapped->dispatch_strings.z = 1;
|
|
|
|
|
|
|
|
|
|
mapped->font_index = font_index;
|
|
|
|
|
mapped->drawable_count = 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);
|
|
|
|
|
vkCmdFillBuffer(command_buffer, memory->drawables, 0, sizeof(UIDrawable)*max_drawables, 0x00000000);
|
|
|
|
|
vkCmdFillBuffer(command_buffer, memory->codes, 0, sizeof(uint32_t)*max_codes, 0x00000000);
|
|
|
|
|
VK_RESULT(command_end_single(device, command_buffer, transfer_pool, transfer_queue));
|
|
|
|
|
vkQueueWaitIdle(transfer_queue.handle);
|
|
|
|
|
destroy_transfer_buffer(allocator, transfer, transfer_memory);
|
|
|
|
@ -805,9 +734,7 @@ VkResult create_ui_context(
|
|
|
|
|
|
|
|
|
|
VK_RESULT(create_ui_descriptor(device, max_fonts, &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));
|
|
|
|
|
VK_RESULT(create_ui_pipeline(device, render_pass, memory->font_samplers_layout, memory->font_textures_layout, &memory->pipeline, &memory->string_pipeline));
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|