From e851d64af665d765adb349f69cdbd1d666a3e1b1 Mon Sep 17 00:00:00 2001 From: Noah Metz Date: Mon, 21 Oct 2024 10:09:52 -0600 Subject: [PATCH] Added bindless textures --- client/include/ui.h | 9 +- client/shader_src/ui.frag | 5 + client/shader_src/ui.vert | 6 +- client/src/main.c | 4 + client/src/render.c | 2 + client/src/ui.c | 205 +++++++++++++++++++++++++++++++------- 6 files changed, 191 insertions(+), 40 deletions(-) diff --git a/client/include/ui.h b/client/include/ui.h index ab05f0e..416b006 100644 --- a/client/include/ui.h +++ b/client/include/ui.h @@ -147,11 +147,15 @@ typedef struct UIContextStorageStruct { VkBuffer font_infos; VmaAllocation font_infos_memory; + + VkDescriptorSet textures; + VkDescriptorSet samplers; VkDescriptorSet font_samplers; VkDescriptorSet font_textures; - VkDescriptorSetLayout font_samplers_layout; - VkDescriptorSetLayout font_textures_layout; + VkDescriptorSetLayout samplers_layout; + VkDescriptorSetLayout textures_layout; VkDescriptorPool fonts_pool; + VkDescriptorPool textures_pool; GraphicsPipeline pipeline; ComputePipeline string_pipeline; @@ -164,6 +168,7 @@ VkResult create_ui_context( VmaAllocator allocator, VkRenderPass render_pass, uint32_t max_fonts, + uint32_t max_textures, VkExtent2D swapchain_extent, vec2 window_scale, VkCommandPool transfer_pool, diff --git a/client/shader_src/ui.frag b/client/shader_src/ui.frag index 9105e3a..955c251 100644 --- a/client/shader_src/ui.frag +++ b/client/shader_src/ui.frag @@ -12,6 +12,9 @@ layout(std430, push_constant) uniform PushConstant { layout(set = 0, binding = 0) uniform sampler font_samplers[]; layout(set = 1, binding = 0) uniform texture2DArray font_textures[]; +layout(set = 2, binding = 0) uniform sampler samplers[]; +layout(set = 3, binding = 0) uniform texture2D textures[]; + layout(location = 0) in vec4 fragColor; layout(location = 1) in vec2 fragUV; layout(location = 2) flat in uint code; @@ -32,6 +35,8 @@ void main() { outColor = fragColor; } else if(type == 1) { outColor = fragColor * texture(sampler2DArray(font_textures[index], font_samplers[index]), vec3(fragUV, code)); + } else if (type == 2) { + outColor = fragColor * texture(sampler2D(textures[index], samplers[index]), fragUV); } } diff --git a/client/shader_src/ui.vert b/client/shader_src/ui.vert index e15d397..b9f0772 100644 --- a/client/shader_src/ui.vert +++ b/client/shader_src/ui.vert @@ -27,15 +27,15 @@ void main() { Drawable drawable = pc.layer.drawables.d[gl_InstanceIndex]; vec2 pos = square[gl_VertexIndex]; - if(drawable.type == 0) { - // Rect - } else if(drawable.type == 1){ + if(drawable.type == 1){ // Glyph Font font = pc.context.fonts.f[pc.layer.font_index]; Symbol symbol = font.symbols.s[drawable.code]; fragUV = pos * vec2(symbol.width, symbol.height); pos = pos * vec2(symbol.width, symbol.height) + vec2(symbol.left, -symbol.top); + } else { + fragUV = pos; } gl_Position = vec4((pos * drawable.size + drawable.pos + pc.layer.container.pos) * pc.context.screen * 2, 0.0, 1.0) - vec4(1.0, 1.0, 0.0, 0.0); diff --git a/client/src/main.c b/client/src/main.c index ce78614..3429a86 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -17,6 +17,7 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render) { UILayerStorage layers[2]; FontStorage font; + TextureStorage texture; VkBuffer transfer; VmaAllocation transfer_memory; @@ -29,6 +30,7 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render) { render->allocator, render->render_pass, 10, + 10, render->swapchain_extent, render->window_scale, render->transfer_pool, @@ -41,6 +43,8 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render) { VK_RESULT(load_font(render->device, render->allocator, &ui, 0, render->transfer_pool, render->transfer_queue, library, "test.ttf", 16, VK_TRUE, &font)); + VK_RESULT(load_texture(render->device, render->allocator, &ui, 0, render->transfer_pool, render->transfer_queue, "test.png", &texture)); + VK_RESULT(create_container(0, 0, 200, 200, render->device, render->allocator, render->transfer_pool, render->transfer_queue, &container)); VK_RESULT(create_layer(10, 100, 10, 0, render->device, render->allocator, render->transfer_pool, render->transfer_queue, &container, &layers[0])); diff --git a/client/src/render.c b/client/src/render.c index 33003ef..3471648 100644 --- a/client/src/render.c +++ b/client/src/render.c @@ -1097,6 +1097,8 @@ VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILaye if(i == 0) { vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 0, 1, &ui_context->font_samplers, 0, NULL); vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 1, 1, &ui_context->font_textures, 0, NULL); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 2, 1, &ui_context->samplers, 0, NULL); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.layout, 3, 1, &ui_context->textures, 0, NULL); } vkCmdDrawIndirect(command_buffer, layers[i].layer, offsetof(UILayer, draw), 1, 0); } diff --git a/client/src/ui.c b/client/src/ui.c index d1019f0..0b6e64b 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -55,8 +55,8 @@ 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, + VkDescriptorSetLayout samplers_layout, + VkDescriptorSetLayout textures_layout, GraphicsPipeline* pipeline, ComputePipeline* compute) { VkResult result; @@ -148,7 +148,7 @@ VkResult create_ui_pipeline( }, }; - VkDescriptorSetLayout set_layouts[] = {font_samplers_layout, font_textures_layout}; + VkDescriptorSetLayout set_layouts[] = {samplers_layout, textures_layout, samplers_layout, textures_layout}; VkPipelineLayoutCreateInfo layout_info = { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, @@ -405,7 +405,7 @@ VkResult load_texture( return VK_ERROR_UNKNOWN; } - size_t read = fread(png, png_size, 1, png_file); + size_t read = fread(png, 1, png_size, png_file); if(read != png_size) { return VK_ERROR_UNKNOWN; } @@ -475,24 +475,98 @@ VkResult load_texture( 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 = { .imageExtent = { - + .width = ihdr.width, + .height = ihdr.height, + .depth = 1, + }, + .imageSubresource = { + .layerCount = 1, + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, }, }; vkCmdCopyBufferToImage(command_buffer, transfer, memory->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); VkImageMemoryBarrier second_barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .image = memory->image, + .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .layerCount = 1, + .levelCount = 1, + }, + .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, }; - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, &second_barrier); + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, &second_barrier); VK_RESULT(command_end_single(device, command_buffer, transfer_pool, transfer_queue)); vkQueueWaitIdle(transfer_queue.handle); - destroy_transfer_buffer(allocator, transfer, transfer_memory); free(image_buffer); free(png); spng_ctx_free(spng); + + VkImageViewCreateInfo view_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = memory->image, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = VK_FORMAT_R8G8B8A8_SRGB, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .layerCount = 1, + .levelCount = 1, + }, + }; + + VK_RESULT(vkCreateImageView(device, &view_info, NULL, &memory->view)); + + VkSamplerCreateInfo sampler_info = { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .magFilter = VK_FILTER_LINEAR, + .minFilter = VK_FILTER_LINEAR, + .addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT, + .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT, + .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT, + }; + + VK_RESULT(vkCreateSampler(device, &sampler_info, NULL, &memory->sampler)); + + VkDescriptorImageInfo desc_sampler_info = { + .sampler = memory->sampler, + }; + + VkDescriptorImageInfo desc_image_info = { + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + .imageView = memory->view, + }; + + VkWriteDescriptorSet desc_writes[] = { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = context->textures, + .dstBinding = 0, + .dstArrayElement = index, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorCount = 1, + .pImageInfo = &desc_image_info, + }, + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = context->samplers, + .dstBinding = 0, + .dstArrayElement = index, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, + .descriptorCount = 1, + .pImageInfo = &desc_sampler_info, + }, + }; + + vkUpdateDescriptorSets(device, sizeof(desc_writes)/sizeof(VkWriteDescriptorSet), desc_writes, 0, NULL); + + return VK_SUCCESS; } VkResult load_font( @@ -737,9 +811,20 @@ VkResult load_font( return VK_SUCCESS; } -VkResult create_ui_descriptor(VkDevice device, uint32_t max_fonts, VkDescriptorSet* font_samplers, VkDescriptorSet* font_textures, VkDescriptorSetLayout* font_sampler_layout, VkDescriptorSetLayout* font_texture_layout, VkDescriptorPool* font_pool) { +VkResult create_ui_descriptor( + VkDevice device, + uint32_t max_fonts, + uint32_t max_textures, + VkDescriptorSetLayout* sampler_layout, + VkDescriptorSetLayout* texture_layout, + VkDescriptorSet* samplers, + VkDescriptorSet* textures, + VkDescriptorSet* font_samplers, + VkDescriptorSet* font_textures, + VkDescriptorPool* font_pool, + VkDescriptorPool* texture_pool) { VkResult result; - VkDescriptorSetLayoutBinding font_sampler_bindings[] = { + VkDescriptorSetLayoutBinding sampler_bindings[] = { { .binding = 0, .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, @@ -752,27 +837,23 @@ VkResult create_ui_descriptor(VkDevice device, uint32_t max_fonts, VkDescriptorS 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 = { + VkDescriptorSetLayoutBindingFlagsCreateInfo sampler_binding_info = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, - .bindingCount = sizeof(font_sampler_bindings)/sizeof(VkDescriptorSetLayoutBinding), + .bindingCount = sizeof(sampler_bindings)/sizeof(VkDescriptorSetLayoutBinding), .pBindingFlags = bindless_flags, }; - VkDescriptorSetLayoutCreateInfo font_sampler_info = { + VkDescriptorSetLayoutCreateInfo sampler_info = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .pBindings = font_sampler_bindings, - .bindingCount = sizeof(font_sampler_bindings)/sizeof(VkDescriptorSetLayoutBinding), + .pBindings = sampler_bindings, + .bindingCount = sizeof(sampler_bindings)/sizeof(VkDescriptorSetLayoutBinding), .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, - .pNext = &font_sampler_bindings_info, + .pNext = &sampler_binding_info, }; + VK_RESULT(vkCreateDescriptorSetLayout(device, &sampler_info, NULL, sampler_layout)); - result = vkCreateDescriptorSetLayout(device, &font_sampler_info, NULL, font_sampler_layout); - if(result != VK_SUCCESS) { - return result; - } - - VkDescriptorSetLayoutBinding font_texture_bindings[] = { + VkDescriptorSetLayoutBinding texture_bindings[] = { { .binding = 0, .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, @@ -781,24 +862,21 @@ VkResult create_ui_descriptor(VkDevice device, uint32_t max_fonts, VkDescriptorS }, }; - VkDescriptorSetLayoutBindingFlagsCreateInfo font_texture_bindings_info = { + VkDescriptorSetLayoutBindingFlagsCreateInfo texture_bindings_info = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, - .bindingCount = sizeof(font_texture_bindings)/sizeof(VkDescriptorSetLayoutBinding), + .bindingCount = sizeof(texture_bindings)/sizeof(VkDescriptorSetLayoutBinding), .pBindingFlags = bindless_flags, }; - VkDescriptorSetLayoutCreateInfo font_texture_info = { + VkDescriptorSetLayoutCreateInfo texture_info = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .pBindings = font_texture_bindings, - .bindingCount = sizeof(font_texture_bindings)/sizeof(VkDescriptorSetLayoutBinding), + .pBindings = texture_bindings, + .bindingCount = sizeof(texture_bindings)/sizeof(VkDescriptorSetLayoutBinding), .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, - .pNext = &font_texture_bindings_info, + .pNext = &texture_bindings_info, }; - result = vkCreateDescriptorSetLayout(device, &font_texture_info, NULL, font_texture_layout); - if(result != VK_SUCCESS) { - return result; - } + VK_RESULT(vkCreateDescriptorSetLayout(device, &texture_info, NULL, texture_layout)); VkDescriptorPoolSize font_pool_sizes[] = { { @@ -832,7 +910,7 @@ VkResult create_ui_descriptor(VkDevice device, uint32_t max_fonts, VkDescriptorS VkDescriptorSetAllocateInfo allocate_font_samplers = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .pSetLayouts = font_sampler_layout, + .pSetLayouts = sampler_layout, .descriptorSetCount = 1, .descriptorPool = *font_pool, .pNext = &count_info, @@ -840,7 +918,7 @@ VkResult create_ui_descriptor(VkDevice device, uint32_t max_fonts, VkDescriptorS VkDescriptorSetAllocateInfo allocate_font_textures = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .pSetLayouts = font_texture_layout, + .pSetLayouts = texture_layout, .descriptorSetCount = 1, .descriptorPool = *font_pool, .pNext = &count_info, @@ -856,6 +934,62 @@ VkResult create_ui_descriptor(VkDevice device, uint32_t max_fonts, VkDescriptorS return result; } + VkDescriptorPoolSize texture_pool_sizes[] = { + { + .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorCount = max_textures, + }, + { + .type = VK_DESCRIPTOR_TYPE_SAMPLER, + .descriptorCount = max_textures, + }, + }; + VkDescriptorPoolCreateInfo texture_pool_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .pPoolSizes = texture_pool_sizes, + .poolSizeCount = 2, + .maxSets = 2, + .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, + }; + + result = vkCreateDescriptorPool(device, &texture_pool_info, NULL, texture_pool); + if(result != VK_SUCCESS) { + return result; + } + + uint32_t max_texture_binding = max_textures - 1; + VkDescriptorSetVariableDescriptorCountAllocateInfo texture_count_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, + .descriptorSetCount = 1, + .pDescriptorCounts = &max_texture_binding, + }; + + VkDescriptorSetAllocateInfo allocate_samplers = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pSetLayouts = sampler_layout, + .descriptorSetCount = 1, + .descriptorPool = *texture_pool, + .pNext = &texture_count_info, + }; + + VkDescriptorSetAllocateInfo allocate_textures = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pSetLayouts = texture_layout, + .descriptorSetCount = 1, + .descriptorPool = *texture_pool, + .pNext = &texture_count_info, + }; + + result = vkAllocateDescriptorSets(device, &allocate_samplers, samplers); + if(result != VK_SUCCESS) { + return result; + } + + result = vkAllocateDescriptorSets(device, &allocate_textures, textures); + if(result != VK_SUCCESS) { + return result; + } + return VK_SUCCESS; } @@ -864,6 +998,7 @@ VkResult create_ui_context( VmaAllocator allocator, VkRenderPass render_pass, uint32_t max_fonts, + uint32_t max_textures, VkExtent2D swapchain_extent, vec2 window_scale, VkCommandPool transfer_pool, @@ -894,9 +1029,9 @@ VkResult create_ui_context( destroy_transfer_buffer(allocator, transfer, transfer_memory); memory->address = buffer_address(device, memory->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_descriptor(device, max_fonts, max_textures, &memory->samplers_layout, &memory->textures_layout, &memory->samplers, &memory->textures, &memory->font_samplers, &memory->font_textures, &memory->fonts_pool, &memory->textures_pool)); - VK_RESULT(create_ui_pipeline(device, render_pass, memory->font_samplers_layout, memory->font_textures_layout, &memory->pipeline, &memory->string_pipeline)); + VK_RESULT(create_ui_pipeline(device, render_pass, memory->samplers_layout, memory->textures_layout, &memory->pipeline, &memory->string_pipeline)); return VK_SUCCESS; }