Changed draw to use containers instead of layers, added draw/string/code storage to layer on host side

main
noah metz 2024-10-21 13:52:40 -06:00
parent 130c6538b2
commit 688fccf251
5 changed files with 91 additions and 81 deletions

@ -7,7 +7,7 @@
VkResult draw_frame(
RenderContext* context,
UIContextStorage* ui_context,
UILayerStorage* ui_layers,
uint32_t ui_layer_count);
UIContainerStorage* containers,
uint32_t container_count);
#endif

@ -213,14 +213,17 @@ typedef struct UILayerInputStruct {
uint32_t font;
} UILayerInput;
typedef struct UIContainerInputStruct {
uint32_t id;
vec2 pos;
vec2 size;
uint32_t layer_count;
UILayerInput* layers;
} UIContainerInput;
VkResult create_container(
uint32_t id,
float x,
float y,
float width,
float height,
uint32_t layer_count,
UILayerInput* layers,
UIContainerInput* container,
RenderContext* gpu,
UIContainerStorage* memory);

@ -1,6 +1,10 @@
#include "draw.h"
VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILayerStorage* layers, uint32_t layer_count) {
VkResult draw_frame(
RenderContext* context,
UIContextStorage* ui_context,
UIContainerStorage* containers,
uint32_t container_count) {
VkResult result;
result = vkWaitForFences(context->device, 1, &context->in_flight_fences[context->current_frame], VK_TRUE, UINT64_MAX);
@ -62,48 +66,50 @@ VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILaye
// Compute Pass
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, ui_context->string_pipeline.pipeline);
for(uint32_t i = 0; i < layer_count; i++) {
push[1] = layers[i].address;
VkBufferMemoryBarrier draw_command_barrier_1 = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.buffer = layers[i].layer,
.offset = offsetof(UILayer, draw),
.size = sizeof(DrawCommand),
.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1, &draw_command_barrier_1, 0, NULL);
command_copy_buffer(command_buffer, layers[i].layer, layers[i].layer, offsetof(UILayer, num_drawables), offsetof(UILayer, draw) + offsetof(DrawCommand, instance_count), sizeof(uint32_t));
VkBufferMemoryBarrier draw_command_barrier_2 = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.buffer = layers[i].layer,
.offset = offsetof(UILayer, draw),
.size = sizeof(DrawCommand),
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, NULL, 1, &draw_command_barrier_2, 0, NULL);
vkCmdPushConstants(command_buffer, ui_context->string_pipeline.layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 16, push);
vkCmdDispatchIndirect(command_buffer, layers[i].layer, offsetof(UILayer, dispatch_strings));
VkBufferMemoryBarrier draw_command_barrier_3 = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.buffer = layers[i].layer,
.offset = offsetof(UILayer, draw),
.size = sizeof(DrawCommand),
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0, 0, NULL, 1, &draw_command_barrier_3, 0, NULL);
VkBufferMemoryBarrier drawables_barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.buffer = layers[i].drawables,
.offset = 0,
.size = sizeof(UIDrawable)*layers[i].data.max_drawables,
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, NULL, 1, &drawables_barrier, 0, NULL);
for(uint32_t i = 0; i < container_count; i++) {
for(uint32_t j = 0; j < containers[i].layer_count; j++) {
push[1] = containers[i].layers[j].address;
VkBufferMemoryBarrier draw_command_barrier_1 = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.buffer = containers[i].layers[j].layer,
.offset = offsetof(UILayer, draw),
.size = sizeof(DrawCommand),
.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1, &draw_command_barrier_1, 0, NULL);
command_copy_buffer(command_buffer, containers[i].layers[j].layer, containers[i].layers[j].layer, offsetof(UILayer, num_drawables), offsetof(UILayer, draw) + offsetof(DrawCommand, instance_count), sizeof(uint32_t));
VkBufferMemoryBarrier draw_command_barrier_2 = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.buffer = containers[i].layers[j].layer,
.offset = offsetof(UILayer, draw),
.size = sizeof(DrawCommand),
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, NULL, 1, &draw_command_barrier_2, 0, NULL);
vkCmdPushConstants(command_buffer, ui_context->string_pipeline.layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 16, push);
vkCmdDispatchIndirect(command_buffer, containers[i].layers[j].layer, offsetof(UILayer, dispatch_strings));
VkBufferMemoryBarrier draw_command_barrier_3 = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.buffer = containers[i].layers[j].layer,
.offset = offsetof(UILayer, draw),
.size = sizeof(DrawCommand),
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0, 0, NULL, 1, &draw_command_barrier_3, 0, NULL);
VkBufferMemoryBarrier drawables_barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.buffer = containers[i].layers[j].drawables,
.offset = 0,
.size = sizeof(UIDrawable)*containers[i].layers[j].data.max_drawables,
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, NULL, 1, &drawables_barrier, 0, NULL);
}
}
@ -112,17 +118,17 @@ VkResult draw_frame(RenderContext* context, UIContextStorage* ui_context, UILaye
// World subpass
vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE);
// UI subpass
for(uint32_t i = 0; i < layer_count; i++) {
push[1] = layers[i].address;
vkCmdPushConstants(command_buffer, ui_context->pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, push);
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.pipeline);
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);
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_context->pipeline.pipeline);
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);
for(uint32_t i = 0; i < container_count; i++) {
for(uint32_t j = 0; j < containers[i].layer_count; j++) {
push[1] = containers[i].layers[j].address;
vkCmdPushConstants(command_buffer, ui_context->pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, push);
vkCmdDrawIndirect(command_buffer, containers[i].layers[j].layer, offsetof(UILayer, draw), 1, 0);
}
vkCmdDrawIndirect(command_buffer, layers[i].layer, offsetof(UILayer, draw), 1, 0);
}
vkCmdEndRenderPass(command_buffer);

@ -82,12 +82,20 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render) {
map_string("Hello, World!", layers[1].codes, 0, font.charmap, font.num_symbols);
VK_RESULT(create_container(0xDEADBEEF, 0.0, 0.0, 200.0, 200.0, sizeof(layers)/sizeof(UILayerInput), layers, render, &container));
UIContainerInput container_info = {
.id = 0xDEADBEEF,
.pos = {0.0, 0.0},
.size = {200.0, 200.0},
.layer_count = sizeof(layers)/sizeof(UILayerInput),
.layers = layers,
};
VK_RESULT(create_container(&container_info, render, &container));
while(glfwWindowShouldClose(window) == 0) {
glfwPollEvents();
result = draw_frame(render, &ui, container.layers, container.layer_count);
result = draw_frame(render, &ui, &container, 1);
if(result != VK_SUCCESS) {
fprintf(stderr, "draw_frame error: %s\n", string_VkResult(result));
return result;

@ -275,13 +275,7 @@ VkResult create_ui_pipeline(
}
VkResult create_container(
uint32_t id,
float x,
float y,
float width,
float height,
uint32_t layer_count,
UILayerInput* layers,
UIContainerInput* container,
RenderContext* gpu,
UIContainerStorage* memory) {
VkResult result;
@ -293,10 +287,10 @@ VkResult create_container(
void* mapped;
VK_RESULT(create_transfer_buffer(gpu->allocator, sizeof(UIContainer), &transfer, &transfer_memory, &mapped));
memory->data.pos[0] = x;
memory->data.pos[1] = y;
memory->data.size[0] = width;
memory->data.size[1] = height;
memory->data.pos[0] = container->pos[0];
memory->data.pos[1] = container->pos[1];
memory->data.size[0] = container->size[0];
memory->data.size[1] = container->size[1];
memcpy(mapped, &memory->data, sizeof(UIContainer));
VkCommandBuffer command_buffer = command_begin_single(gpu->device, gpu->transfer_pool);
@ -305,11 +299,11 @@ VkResult create_container(
destroy_transfer_buffer(gpu->allocator, transfer, transfer_memory);
memory->address = buffer_address(gpu->device, memory->container);
memory->id = id;
memory->layer_count = layer_count;
memory->layers = malloc(sizeof(UILayerStorage)*layer_count);
for(uint32_t i = 0; i < layer_count; i++) {
VK_RESULT(create_layer(i, &layers[i], gpu, memory));
memory->id = container->id;
memory->layer_count = container->layer_count;
memory->layers = malloc(sizeof(UILayerStorage)*container->layer_count);
for(uint32_t i = 0; i < container->layer_count; i++) {
VK_RESULT(create_layer(i, &container->layers[i], gpu, memory));
}
return VK_SUCCESS;
@ -402,7 +396,6 @@ VkResult create_layer(
codes[i] = input->codes[i];
container->layers[index].codes_buffer[i] = input->codes[i];
}
vkCmdFillBuffer(command_buffer, container->layers[index].codes, sizeof(UIDrawable)*input->num_drawables, sizeof(UIDrawable)*input->num_codes, 0x00000000);
command_copy_buffer(command_buffer, transfer, container->layers[index].codes, sizeof(UILayer) + sizeof(UIString)*input->num_strings + sizeof(UIDrawable)*input->num_drawables, 0, sizeof(uint32_t)*input->num_codes);
}
VK_RESULT(command_end_single(gpu->device, command_buffer, gpu->transfer_pool, gpu->transfer_queue));