Changed multiple render passes to subpasses

main
noah metz 2024-10-15 00:06:46 -06:00
parent 6988abcd86
commit 28cd4efbaf
8 changed files with 198 additions and 49 deletions

@ -10,11 +10,13 @@ SOURCES = src/main.c src/render.c src/vma.cpp src/pipeline.c src/command.c src/s
OBJECTS = $(addsuffix .o, $(basename $(SOURCES))) OBJECTS = $(addsuffix .o, $(basename $(SOURCES)))
VERT_SPV = $(addsuffix .vert.spv, $(basename $(wildcard shader_src/*.vert))) VERT_SPV = $(addsuffix .vert.spv, $(basename $(wildcard shader_src/*.vert)))
FRAG_SPV = $(addsuffix .frag.spv, $(basename $(wildcard shader_src/*.frag))) FRAG_SPV = $(addsuffix .frag.spv, $(basename $(wildcard shader_src/*.frag)))
COMP_SPV = $(addsuffix .comp.spv, $(basename $(wildcard shader_src/*.comp)))
SPV_FILES = $(VERT_SPV) $(FRAG_SPV) $(COMP_SPV)
export MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=1 export MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=1
.PHONY: all .PHONY: all
all: roleplay $(VERT_SPV) $(FRAG_SPV) all: roleplay $(SPV_FILES)
roleplay: $(OBJECTS) roleplay: $(OBJECTS)
$(CPP) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(CPP) $(CFLAGS) $(LDFLAGS) -o $@ $^
@ -28,8 +30,7 @@ roleplay: $(OBJECTS)
.PHONY: clean clean_compdb .PHONY: clean clean_compdb
clean: clean:
rm -f $(FRAG_SPV) rm -f $(SPV_FILES)
rm -f $(VERT_SPV)
rm -f $(OBJECTS) rm -f $(OBJECTS)
rm -f roleplay rm -f roleplay
rm -rf roleplay.dSYM rm -rf roleplay.dSYM
@ -38,18 +39,20 @@ clean_compdb:
rm -rf .compdb rm -rf .compdb
rm compile_commands.json rm compile_commands.json
run: roleplay $(VERT_SPV) $(FRAG_SPV) run: roleplay $(SPV_FILES)
./roleplay ./roleplay
roleplay.dSYM: roleplay roleplay.dSYM: roleplay
$(DSYM) roleplay $(DSYM) roleplay
debug: roleplay roleplay.dSYM $(VERT_SPV) $(FRAG_SPV) debug: roleplay roleplay.dSYM $(SPV_FILES)
$(GDB) roleplay $(GDB) roleplay
%.vert.spv: %.vert %.vert.spv: %.vert
glslangValidator -V -o $@ $< glslangValidator -V -o $@ $<
%.frag.spv: %.frag %.frag.spv: %.frag
glslangValidator -V -o $@ $< glslangValidator -V -o $@ $<
%.comp.spv: %.comp
glslangValidator -V -o $@ $<

@ -34,6 +34,12 @@ typedef struct TextStruct {
uint32_t offset; uint32_t offset;
} Text; } Text;
typedef struct TextPointersStruct {
VkDeviceAddress strings;
VkDeviceAddress codes;
VkDeviceAddress characters;
} TextPointers;
typedef struct CharStruct { typedef struct CharStruct {
vec3 pos; vec3 pos;
vec4 color; vec4 color;

@ -71,8 +71,7 @@ typedef struct RenderContextStruct {
VkCommandPool graphics_pool; VkCommandPool graphics_pool;
VkCommandPool transfer_pool; VkCommandPool transfer_pool;
VkRenderPass world_render_pass; VkRenderPass render_pass;
VkRenderPass ui_render_pass;
VkCommandBuffer* swapchain_command_buffers; VkCommandBuffer* swapchain_command_buffers;

@ -0,0 +1,64 @@
#version 450
#extension GL_EXT_buffer_reference : require
struct Symbol {
uint x;
uint top;
uint width;
};
struct Character {
vec3 pos;
vec4 color;
float size;
uint code;
};
struct String {
vec3 pos;
vec4 color;
float size;
uint offset;
uint length;
};
layout(buffer_reference, std430) readonly buffer SymbolList{
Symbol symbols[];
};
layout(buffer_reference, std430) writeonly buffer CharacterList{
Character characters[];
};
layout(buffer_reference, std430) readonly buffer Characters{
uint codes[];
};
layout(buffer_reference, std430) readonly buffer Strings{
String strings[];
};
layout(set = 0, binding = 0) uniform UIUniform {
mat4 screen;
} ubo;
layout(set = 1, binding = 0) uniform Font {
uint num_symbols;
uint width;
uint height;
uint space_width;
SymbolList symbol_list;
} font;
layout(buffer_reference, std430) readonly buffer Pointers {
Strings strings;
Characters codes;
CharacterList characters;
};
layout(std430, push_constant) uniform Push {
Pointers pointers;
} push;
void main() {
}

@ -26,7 +26,7 @@ layout(set = 0, binding = 0) uniform UIUniform {
mat4 screen; mat4 screen;
} ubo; } ubo;
layout(set = 1, binding = 0) uniform FontUniform { layout(set = 1, binding = 0) uniform Font {
uint num_symbols; uint num_symbols;
uint width; uint width;
uint height; uint height;
@ -34,8 +34,13 @@ layout(set = 1, binding = 0) uniform FontUniform {
SymbolList symbol_list; SymbolList symbol_list;
} font; } font;
layout(std430, push_constant) uniform Push { layout(buffer_reference, std430) readonly buffer Pointers {
uint padding[4];
CharacterList characters; CharacterList characters;
};
layout(std430, push_constant) uniform Push {
Pointers pointers;
} push; } push;
layout(location = 0) in vec2 inVertexPosition; layout(location = 0) in vec2 inVertexPosition;
@ -44,7 +49,7 @@ layout(location = 0) out vec4 fragColor;
layout(location = 1) out vec2 fragUV; layout(location = 1) out vec2 fragUV;
void main() { void main() {
Character character = push.characters.characters[gl_InstanceIndex]; Character character = push.pointers.characters.characters[gl_InstanceIndex];
Symbol symbol = font.symbol_list.symbols[character.code]; Symbol symbol = font.symbol_list.symbols[character.code];
float fragU = (inVertexPosition.x*symbol.width + symbol.x) / font.width; float fragU = (inVertexPosition.x*symbol.width + symbol.x) / font.width;

@ -106,7 +106,7 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render_context) {
VmaAllocation colored_rect_memory; VmaAllocation colored_rect_memory;
VmaAllocation text_memory; VmaAllocation text_memory;
result = init_pipelines(render_context->device, render_context->allocator, render_context->swapchain_extent, render_context->world_render_pass, render_context->transfer_queue, render_context->transfer_pool, &ui_context); result = init_pipelines(render_context->device, render_context->allocator, render_context->swapchain_extent, render_context->render_pass, render_context->transfer_queue, render_context->transfer_pool, &ui_context);
if(result != VK_SUCCESS) { if(result != VK_SUCCESS) {
return result; return result;
} }
@ -197,10 +197,42 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render_context) {
vmaUnmapMemory(render_context->allocator, text_memory); vmaUnmapMemory(render_context->allocator, text_memory);
VkBuffer text_pointer_buffer;
VmaAllocation text_pointer_memory;
VkBufferCreateInfo text_pointer_buffer_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.size = sizeof(TextPointers),
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo text_pointer_memory_info = {
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
};
result = vmaCreateBuffer(render_context->allocator, &text_pointer_buffer_info, &text_pointer_memory_info, &text_pointer_buffer, &text_pointer_memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
TextPointers* pointers;
result = vmaMapMemory(render_context->allocator, text_pointer_memory, (void**)&pointers);
if(result != VK_SUCCESS) {
return result;
}
VkBufferDeviceAddressInfo test_address_info = { VkBufferDeviceAddressInfo test_address_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = text_buffer, .buffer = text_buffer,
}; };
pointers->characters = vkGetBufferDeviceAddress(render_context->device, &test_address_info);
vmaUnmapMemory(render_context->allocator, text_pointer_memory);
VkBufferDeviceAddressInfo pointers_address_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = text_pointer_buffer,
};
UILayer test_layer = { UILayer test_layer = {
.colored_rects = colored_rect_buffer, .colored_rects = colored_rect_buffer,
@ -209,7 +241,7 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render_context) {
.font = test_font_descriptor, .font = test_font_descriptor,
.text_count = 2, .text_count = 2,
.texts = text_buffer, .texts = text_buffer,
.texts_address = vkGetBufferDeviceAddress(render_context->device, &test_address_info), .texts_address = vkGetBufferDeviceAddress(render_context->device, &pointers_address_info),
}; };
while(glfwWindowShouldClose(window) == 0) { while(glfwWindowShouldClose(window) == 0) {

@ -286,6 +286,46 @@ VkPipelineVertexInputStateCreateInfo input_info = {
} }
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 ui_descriptor_layout, VkDescriptorSetLayout font_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 | VK_SHADER_STAGE_VERTEX_BIT,
.size = 8,
};
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); VkShaderModule vert_shader = load_shader_file("shader_src/ui_text.vert.spv", device);
if(vert_shader == VK_NULL_HANDLE) { if(vert_shader == VK_NULL_HANDLE) {
return VK_ERROR_UNKNOWN; return VK_ERROR_UNKNOWN;
@ -339,11 +379,6 @@ VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDe
VkDescriptorSetLayout all_layouts[] = {ui_descriptor_layout, font_layout}; VkDescriptorSetLayout all_layouts[] = {ui_descriptor_layout, font_layout};
VkPushConstantRange push_constant = {
.size = 8,
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
};
VkPipelineLayoutCreateInfo layout_info = { VkPipelineLayoutCreateInfo layout_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = sizeof(all_layouts)/sizeof(VkDescriptorSetLayout), .setLayoutCount = sizeof(all_layouts)/sizeof(VkDescriptorSetLayout),
@ -358,7 +393,7 @@ VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDe
.primitiveRestartEnable = VK_FALSE, .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); result = create_ui_pipeline(device, render_pass, shader_stages, sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), input_info, layout_info, input_assembly_info, pipeline);
if(result != VK_SUCCESS) { if(result != VK_SUCCESS) {
return result; return result;
} }

@ -27,6 +27,10 @@ const char * instance_extensions[] = {
uint32_t instance_extension_count = sizeof(instance_extensions) / sizeof(const char *); uint32_t instance_extension_count = sizeof(instance_extensions) / sizeof(const char *);
const char * device_extensions[] = { const char * device_extensions[] = {
#ifdef __APPLE__
"VK_KHR_portability_subset",
#endif
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME,
}; };
@ -125,8 +129,6 @@ VkResult create_instance(VkInstance* instance) {
.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR, .flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR,
}; };
VkResult result = vkCreateInstance(&instance_info, 0, instance); VkResult result = vkCreateInstance(&instance_info, 0, instance);
if(result != VK_SUCCESS) { if(result != VK_SUCCESS) {
return result; return result;
@ -575,17 +577,17 @@ VkResult find_depth_format(VkPhysicalDevice physical_device, VkImageTiling tilin
return VK_ERROR_UNKNOWN; return VK_ERROR_UNKNOWN;
} }
VkResult create_render_pass(VkDevice device, VkSurfaceFormatKHR format, VkFormat depth_format, VkRenderPass* render_pass, VkImageLayout initial_layout, VkImageLayout final_layout, VkAttachmentLoadOp color_load_op) { VkResult create_render_pass(VkDevice device, VkSurfaceFormatKHR format, VkFormat depth_format, VkRenderPass* render_pass) {
VkAttachmentDescription attachments[] = { VkAttachmentDescription attachments[] = {
{ {
.format = format.format, .format = format.format,
.samples = VK_SAMPLE_COUNT_1_BIT, .samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = color_load_op, .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE, .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
.initialLayout = initial_layout, .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.finalLayout = final_layout, .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
}, },
{ {
.format = depth_format, .format = depth_format,
@ -619,6 +621,12 @@ VkResult create_render_pass(VkDevice device, VkSurfaceFormatKHR format, VkFormat
.pColorAttachments = color_attachment_refs, .pColorAttachments = color_attachment_refs,
.pDepthStencilAttachment = &depth_attachment_ref, .pDepthStencilAttachment = &depth_attachment_ref,
}, },
{
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
.colorAttachmentCount = sizeof(color_attachment_refs)/sizeof(VkAttachmentReference),
.pColorAttachments = color_attachment_refs,
.pDepthStencilAttachment = &depth_attachment_ref,
},
}; };
// This basically says "make sure nothing else is writing to the depth_stencil or the color attachment during the pipeline // This basically says "make sure nothing else is writing to the depth_stencil or the color attachment during the pipeline
@ -631,6 +639,15 @@ VkResult create_render_pass(VkDevice device, VkSurfaceFormatKHR format, VkFormat
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT, .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT,
},
{
.srcSubpass = 0,
.dstSubpass = 1,
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT,
} }
}; };
@ -931,12 +948,7 @@ VkResult init_vulkan(GLFWwindow* window, RenderContext* context) {
return result; return result;
} }
result = create_render_pass(context->device, context->swapchain_format, context->depth_format, &context->world_render_pass, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_ATTACHMENT_LOAD_OP_CLEAR); result = create_render_pass(context->device, context->swapchain_format, context->depth_format, &context->render_pass);
if(result != VK_SUCCESS) {
return result;
}
result = create_render_pass(context->device, context->swapchain_format, context->depth_format, &context->ui_render_pass, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_ATTACHMENT_LOAD_OP_LOAD);
if(result != VK_SUCCESS) { if(result != VK_SUCCESS) {
return result; return result;
} }
@ -946,7 +958,7 @@ VkResult init_vulkan(GLFWwindow* window, RenderContext* context) {
return result; return result;
} }
result = create_swapchain_framebuffers(context->device, context->swapchain_image_count, context->swapchain_image_views, context->depth_image_view, context->world_render_pass, context->swapchain_extent, &context->swapchain_framebuffers); result = create_swapchain_framebuffers(context->device, context->swapchain_image_count, context->swapchain_image_views, context->depth_image_view, context->render_pass, context->swapchain_extent, &context->swapchain_framebuffers);
if(result != VK_SUCCESS) { if(result != VK_SUCCESS) {
return result; return result;
} }
@ -1005,30 +1017,20 @@ VkResult draw_frame(RenderContext* context, UIContext* ui_context, UILayer* ui_l
VkClearValue clear_values[2] = {{.color={{0.0f, 0.0f, 0.0f, 1.0f}}}, {.depthStencil={1.0f, 0.0f}}}; VkClearValue clear_values[2] = {{.color={{0.0f, 0.0f, 0.0f, 1.0f}}}, {.depthStencil={1.0f, 0.0f}}};
VkDeviceSize offset = 0; VkDeviceSize offset = 0;
// World Render Pass VkRenderPassBeginInfo render_pass_begin = {
VkRenderPassBeginInfo world_render_pass_begin = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = context->world_render_pass, .renderPass = context->render_pass,
.framebuffer = context->swapchain_framebuffers[image_index], .framebuffer = context->swapchain_framebuffers[image_index],
.renderArea.offset = {0, 0}, .renderArea.offset = {0, 0},
.renderArea.extent = context->swapchain_extent, .renderArea.extent = context->swapchain_extent,
.clearValueCount = 2, .clearValueCount = 2,
.pClearValues = clear_values, .pClearValues = clear_values,
}; };
vkCmdBeginRenderPass(command_buffer, &world_render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
vkCmdEndRenderPass(command_buffer); // World subpass
// UI Render Pass vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE);
VkRenderPassBeginInfo ui_render_pass_begin = { // UI subpass
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = context->ui_render_pass,
.framebuffer = context->swapchain_framebuffers[image_index],
.renderArea.offset = {0, 0},
.renderArea.extent = context->swapchain_extent,
.clearValueCount = 2,
.pClearValues = clear_values,
};
vkCmdBeginRenderPass(command_buffer, &ui_render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
// Draw UI colored rects //////////////////////////////// // Draw UI colored rects ////////////////////////////////
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->ui_pipeline_rect.pipeline); vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->ui_pipeline_rect.pipeline);
@ -1044,12 +1046,15 @@ VkResult draw_frame(RenderContext* context, UIContext* ui_context, UILayer* ui_l
} }
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
// Draw UI text ///////////////////////////////////////// // Draw UI text /////////////////////////////////////////
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, ui_context->ui_compute_text.pipeline);
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].text_count > 0) {
// Bind Font Descriptor
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->ui_pipeline_text.layout, 1, 1, &ui_layers[i].font.set, 0, NULL); vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->ui_pipeline_text.layout, 1, 1, &ui_layers[i].font.set, 0, NULL);
vkCmdPushConstants(command_buffer, ui_context->ui_pipeline_text.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 8, &ui_layers[i].texts_address); // Push pointers
vkCmdPushConstants(command_buffer, ui_context->ui_pipeline_text.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0, 8, &ui_layers[i].texts_address);
vkCmdDrawIndexed(command_buffer, 6, ui_layers[i].text_count, 0, 0, 0); vkCmdDrawIndexed(command_buffer, 6, ui_layers[i].text_count, 0, 0, 0);
} }
} }