Renamed pipeline->ui, moved square vertices to shaders

main
noah metz 2024-10-17 15:56:35 -06:00
parent e9192e42fe
commit 04e15db065
8 changed files with 67 additions and 180 deletions

@ -2,7 +2,7 @@ ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
CFLAGS = -I $(ROOT_DIR)/include -I/usr/local/include -O0 -g -Wall -Wextra
LDFLAGS = -lfreetype -lz -lglfw -lvulkan -ldl -Xlinker -rpath -Xlinker /opt/homebrew/lib
SOURCES = src/main.c src/render.c src/pipeline.c src/command.c lib/spng.c lib/vma.cpp
SOURCES = src/main.c src/render.c src/ui.c src/command.c lib/spng.c lib/vma.cpp
OBJECTS = $(addsuffix .o, $(basename $(SOURCES)))
VERT_SPV = $(addsuffix .vert.spv, $(basename $(wildcard shader_src/*.vert)))
FRAG_SPV = $(addsuffix .frag.spv, $(basename $(wildcard shader_src/*.frag)))

@ -24,7 +24,7 @@
#include <cglm/quat.h>
#include <cglm/cam.h>
#include "pipeline.h"
#include "ui.h"
#include "command.h"
extern const uint32_t MAX_FRAMES_IN_FLIGHT;

@ -38,10 +38,9 @@ typedef struct StringStruct {
} String;
typedef struct DrawCommandStruct {
uint32_t index_count;
uint32_t vertex_count;
uint32_t instance_count;
uint32_t first_index;
int32_t vertex_offset;
uint32_t first_vertex;
uint32_t first_instance;
} DrawCommand;
@ -116,14 +115,6 @@ typedef struct UILayerStruct {
FontDescriptor font;
} UILayer;
struct RectBuffer {
VkBuffer vertex;
VkBuffer index;
VmaAllocation vertex_memory;
VmaAllocation index_memory;
};
typedef struct UIContextStruct {
VkBuffer ui_descriptor_buffer;
VmaAllocation ui_descriptor_memory;
@ -134,20 +125,39 @@ typedef struct UIContextStruct {
VkDescriptorPool font_pool;
VkDescriptorSetLayout font_layout;
struct RectBuffer ui_rect;
GraphicsPipeline ui_pipeline_rect;
GraphicsPipeline ui_pipeline_text;
ComputePipeline ui_compute_text;
} UIContext;
typedef struct UIFontStruct {
} UIFont;
typedef struct UITextStruct {
} UIText;
typedef struct UICharacterStruct {
} UICharacter;
typedef struct UIElementStruct {
uint32_t type;
uint32_t offset;
} UIElement;
typedef struct UIContainerStruct {
VkDeviceAddress elements;
} UIContainer;
typedef struct UIStruct {
} UI;
VkResult init_pipelines(
VkDevice device,
VmaAllocator allocator,
VkExtent2D swapchain_extent,
vec2 window_scale,
VkRenderPass render_pass,
Queue transfer_queue,
VkCommandPool transfer_pool,
UIContext* context);
VkResult load_font(

@ -5,15 +5,23 @@ layout(set = 0, binding = 0) uniform UIUniform {
mat4 screen;
} ubo;
layout(location = 0) in vec2 inVertexPosition;
layout(location = 1) in vec3 inPolygonPosition;
layout(location = 2) in vec2 inPolygonSize;
layout(location = 3) in vec4 inColor;
layout(location = 0) in vec3 inPolygonPosition;
layout(location = 1) in vec2 inPolygonSize;
layout(location = 2) in vec4 inColor;
layout(location = 0) out vec4 fragColor;
const vec2 square[6] = {
vec2(0.0, 0.0),
vec2(1.0, 0.0),
vec2(0.0, 1.0),
vec2(1.0, 0.0),
vec2(1.0, 1.0),
vec2(0.0, 1.0),
};
void main() {
gl_Position = ubo.screen * vec4(vec3(inVertexPosition * inPolygonSize, 0.0) + inPolygonPosition, 1.0);
gl_Position = ubo.screen * vec4(vec3(square[gl_VertexIndex] * inPolygonSize, 0.0) + inPolygonPosition, 1.0);
fragColor = inColor;
}

@ -44,20 +44,27 @@ layout(std430, push_constant) uniform Push {
Pointers pointers;
} push;
layout(location = 0) in vec2 inVertexPosition;
layout(location = 0) out vec4 fragColor;
layout(location = 1) out vec2 fragUV;
layout(location = 2) out uint code;
const vec2 square[6] = {
vec2(0.0, 0.0),
vec2(1.0, 0.0),
vec2(0.0, 1.0),
vec2(1.0, 0.0),
vec2(1.0, 1.0),
vec2(0.0, 1.0),
};
void main() {
Character character = push.pointers.characters.characters[gl_InstanceIndex];
Symbol symbol = font.symbol_list.symbols[character.code];
float fragU = inVertexPosition.x * symbol.width/font.width;
float fragV = inVertexPosition.y * symbol.height/font.height;
float x = (inVertexPosition.x * symbol.width + symbol.left) * character.size / font.width;
float y = (inVertexPosition.y * symbol.height - symbol.top) * character.size / font.height;
float fragU = square[gl_VertexIndex].x * symbol.width/font.width;
float fragV = square[gl_VertexIndex].y * symbol.height/font.height;
float x = (square[gl_VertexIndex].x * symbol.width + symbol.left) * character.size / font.width;
float y = (square[gl_VertexIndex].y * symbol.height - symbol.top) * character.size / font.height;
fragUV = vec2(fragU, fragV);
fragColor = character.color;

@ -1,6 +1,6 @@
#include "render.h"
#include "arpa/inet.h"
#include "pipeline.h"
#include "ui.h"
#include "vk_mem_alloc.h"
#include "vulkan/vk_enum_string_helper.h"
#include "vulkan/vulkan_core.h"
@ -23,7 +23,7 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render_context) {
VkBuffer colored_rect_buffer;
VmaAllocation colored_rect_memory;
result = init_pipelines(render_context->device, render_context->allocator, render_context->swapchain_extent, render_context->window_scale, render_context->render_pass, render_context->transfer_queue, render_context->transfer_pool, &ui_context);
result = init_pipelines(render_context->device, render_context->allocator, render_context->swapchain_extent, render_context->window_scale, render_context->render_pass, &ui_context);
if(result != VK_SUCCESS) {
return result;
}

@ -2,7 +2,6 @@
#include "GLFW/glfw3.h"
#include "stdio.h"
#include "string.h"
#include "pipeline.h"
#include "vk_mem_alloc.h"
#include "vulkan/vulkan_core.h"
@ -1092,18 +1091,15 @@ VkResult draw_frame(RenderContext* context, UIContext* ui_context, UILayer* ui_l
// Draw UI colored rects ////////////////////////////////
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->ui_pipeline_rect.pipeline);
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->ui_pipeline_rect.layout, 0, 1, &ui_context->ui_descriptor_set, 0, NULL);
vkCmdBindVertexBuffers(command_buffer, 0, 1, &ui_context->ui_rect.vertex, &offset);
vkCmdBindIndexBuffer(command_buffer, ui_context->ui_rect.index, 0, VK_INDEX_TYPE_UINT32);
for(uint32_t i = 0; i < ui_layer_count; i++) {
if(ui_layers[i].colored_rect_count > 0) {
vkCmdBindVertexBuffers(command_buffer, 1, 1, &ui_layers[i].colored_rects, &offset);
vkCmdDrawIndexed(command_buffer, 6, ui_layers[i].colored_rect_count, 0, 0, 0);
vkCmdBindVertexBuffers(command_buffer, 0, 1, &ui_layers[i].colored_rects, &offset);
vkCmdDraw(command_buffer, 6, ui_layers[i].colored_rect_count, 0, 0);
}
}
/////////////////////////////////////////////////////////
// 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);
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++) {
@ -1112,7 +1108,7 @@ VkResult draw_frame(RenderContext* context, UIContext* ui_context, UILayer* ui_l
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->ui_pipeline_text.layout, 1, 1, &ui_layers[i].font.set, 0, NULL);
// Push pointers
vkCmdPushConstants(command_buffer, ui_context->ui_pipeline_text.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0, 8, &ui_layers[i].string_pointers);
vkCmdDrawIndexedIndirect(command_buffer, ui_layers[i].string_draw, 0, 1, sizeof(DrawCommand));
vkCmdDrawIndirect(command_buffer, ui_layers[i].string_draw, 0, 1, sizeof(DrawCommand));
}
}
/////////////////////////////////////////////////////////

@ -1,4 +1,4 @@
#include "pipeline.h"
#include "ui.h"
#include "cglm/affine.h"
#include "cglm/mat4.h"
#include "command.h"
@ -203,11 +203,6 @@ VkResult create_ui_colored_rect_pipeline(VkDevice device, VkRenderPass render_pa
VkVertexInputBindingDescription bindings[] = {
{
.binding = 0,
.stride = sizeof(vec2),
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
},
{
.binding = 1,
.stride = sizeof(ColoredRect),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE,
},
@ -217,24 +212,18 @@ VkResult create_ui_colored_rect_pipeline(VkDevice device, VkRenderPass render_pa
{
.binding = 0,
.location = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = 0,
},
{
.binding = 1,
.location = 1,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(ColoredRect, pos),
},
{
.binding = 1,
.location = 2,
.binding = 0,
.location = 1,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = offsetof(ColoredRect, size),
},
{
.binding = 1,
.location = 3,
.binding = 0,
.location = 2,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(ColoredRect, color),
},
@ -340,21 +329,8 @@ VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDe
},
};
VkVertexInputBindingDescription bindings[] = {
{
.binding = 0,
.stride = sizeof(vec2),
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
},
};
VkVertexInputAttributeDescription attributes[] = {
{
.binding = 0,
.location = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = 0,
},
};
VkVertexInputBindingDescription bindings[] = {};
VkVertexInputAttributeDescription attributes[] = {};
VkPipelineVertexInputStateCreateInfo input_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
@ -566,7 +542,7 @@ VkResult create_text_pointers(
}
DrawCommand draw = {
.index_count = 6,
.vertex_count = 6,
};
memcpy(mapped + 0, &draw, sizeof(DrawCommand));
@ -1005,113 +981,7 @@ VkResult create_ui_descriptor_set(VkDevice device, VmaAllocator allocator, VkExt
return VK_SUCCESS;
}
VkResult create_ui_rect_buffer(VkDevice device, Queue transfer_queue, VkCommandPool transfer_pool, VmaAllocator allocator, struct RectBuffer* rect) {
uint32_t vertex_buffer_size = 4 * sizeof(vec2);
uint32_t index_buffer_size = 6 * sizeof(uint32_t);
// Create temp buffer
VkBufferCreateInfo temp_buffer_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.size = vertex_buffer_size + index_buffer_size,
};
VmaAllocationCreateInfo temp_allocation_info = {
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
};
VkBuffer temp_buffer;
VmaAllocation temp_buffer_memory;
VkResult result;
result = vmaCreateBuffer(allocator, &temp_buffer_info, &temp_allocation_info, &temp_buffer, &temp_buffer_memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
// Create buffers
VmaAllocationCreateInfo allocation_info = {
.usage = VMA_MEMORY_USAGE_GPU_ONLY,
};
VkBufferCreateInfo vertex_buffer_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.size = vertex_buffer_size,
};
result = vmaCreateBuffer(allocator, &vertex_buffer_info, &allocation_info, &rect->vertex, &rect->vertex_memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
VkBufferCreateInfo index_buffer_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.size = index_buffer_size,
};
result = vmaCreateBuffer(allocator, &index_buffer_info, &allocation_info, &rect->index, &rect->index_memory, NULL);
if(result != VK_SUCCESS) {
return result;
}
void* mapped;
result = vmaMapMemory(allocator, temp_buffer_memory, &mapped);
if(result != VK_SUCCESS) {
return result;
}
vec2* mapped_vertex = (vec2*)mapped;
mapped_vertex[0][0] = 0.0f;
mapped_vertex[0][1] = 0.0f;
mapped_vertex[1][0] = 1.0f;
mapped_vertex[1][1] = 0.0f;
mapped_vertex[2][0] = 0.0f;
mapped_vertex[2][1] = 1.0f;
mapped_vertex[3][0] = 1.0f;
mapped_vertex[3][1] = 1.0f;
uint32_t* mapped_index = (uint32_t*)(mapped + vertex_buffer_size);
mapped_index[0] = 0;
mapped_index[1] = 1;
mapped_index[2] = 2;
mapped_index[3] = 1;
mapped_index[4] = 3;
mapped_index[5] = 2;
vmaUnmapMemory(allocator, temp_buffer_memory);
VkCommandBuffer copy_buffer = command_begin_single(device, transfer_pool);
VkBufferCopy vertex_copy_region = {
.size = vertex_buffer_size,
.dstOffset = 0,
.srcOffset = 0,
};
vkCmdCopyBuffer(copy_buffer, temp_buffer, rect->vertex, 1, &vertex_copy_region);
VkBufferCopy index_copy_region = {
.size = index_buffer_size,
.dstOffset = 0,
.srcOffset = vertex_buffer_size,
};
vkCmdCopyBuffer(copy_buffer, temp_buffer, rect->index, 1, &index_copy_region);
result = command_end_single(device, copy_buffer, transfer_pool, transfer_queue);
if(result != VK_SUCCESS) {
return result;
}
vmaDestroyBuffer(allocator, temp_buffer, temp_buffer_memory);
return VK_SUCCESS;
}
VkResult init_pipelines(VkDevice device, VmaAllocator allocator, VkExtent2D swapchain_extent, vec2 window_scale, VkRenderPass render_pass, Queue transfer_queue, VkCommandPool transfer_pool, UIContext* context) {
VkResult init_pipelines(VkDevice device, VmaAllocator allocator, VkExtent2D swapchain_extent, vec2 window_scale, VkRenderPass render_pass, UIContext* context) {
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);
@ -1119,11 +989,6 @@ VkResult init_pipelines(VkDevice device, VmaAllocator allocator, VkExtent2D swap
return result;
}
result = create_ui_rect_buffer(device, transfer_queue, transfer_pool, allocator, &context->ui_rect);
if(result != VK_SUCCESS) {
return result;
}
result = create_ui_colored_rect_pipeline(device, render_pass, context->ui_descriptor_layout, &context->ui_pipeline_rect);
if(result != VK_SUCCESS) {
return result;
@ -1139,5 +1004,6 @@ VkResult init_pipelines(VkDevice device, VmaAllocator allocator, VkExtent2D swap
return result;
}
return VK_SUCCESS;
}