Test program has been expanded to draw a RGB triangle

This commit is contained in:
2025-07-07 22:57:13 +10:00
parent c65d7fd4e3
commit 86851edf50

View File

@@ -1,13 +1,168 @@
#include "basalt_context.h" #include "vulkan/basalt_command_buffer.h"
#include "basalt_window.h" #include "vulkan/basalt_swapchain.h"
int main() void application()
{ {
basalt::Window window(640, 480, "Hello Vulkan!"); basalt::Context ctx("Basic",
basalt::darray<const char*>({
"VK_LAYER_KHRONOS_validation"
}, MEMORY_TAG_CLASS_ARRAY | MEMORY_TAG_ZONE_APPLICATION | MEMORY_TAG_ALIGN_ANY),
basalt::darray<const char*>({
VK_EXT_DEBUG_UTILS_EXTENSION_NAME
}, MEMORY_TAG_CLASS_ARRAY | MEMORY_TAG_ZONE_APPLICATION | MEMORY_TAG_ALIGN_ANY)
);
basalt::Window window(ctx, 640, 480, "Hello Vulkan!");;
basalt::PhysicalDevice phy_dev = basalt::PhysicalDeviceSelector(ctx, window)
.prefer_types(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, 2.0f, 0.0f)
.prefer_types(VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, 1.0f, 0.0f)
.ensure_queues(VK_QUEUE_GRAPHICS_BIT, true)
.ensure_swapchain()
.prefer_surface_format({ VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR })
.prefer_present_mode(VK_PRESENT_MODE_MAILBOX_KHR)
.pick();
basalt::Device dev = basalt::DeviceDesigner(ctx, phy_dev)
.request_layer("VK_LAYER_KHRONOS_validation")
.request_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)
.request_queue(phy_dev.indicies.graphics, 1.0f)
.request_queue(phy_dev.indicies.present, 1.0f)
.design();
basalt::Swapchain swapchain(dev, window,
{ {VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR} },
{ VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR }
);
basalt::RenderPass pass = basalt::RenderPassBuilder(dev)
.add_attachment({
.format = swapchain.details.cached_format.format,
.samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
})
.add_subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, {
{
.attachment = 0,
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
}
})
.add_subpass_dependency({
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
})
.build();
basalt::Pipeline pipeline = basalt::PipelineBuilder(dev, swapchain.swapchain_extent, VK_NULL_HANDLE)
.add_dynamic_state(VK_DYNAMIC_STATE_SCISSOR)
.add_dynamic_state(VK_DYNAMIC_STATE_VIEWPORT)
.set_render_pass(pass.render_pass)
.add_colour_attachment({
.blendEnable = VK_FALSE,
.srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
.colorBlendOp = VK_BLEND_OP_ADD,
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
.alphaBlendOp = VK_BLEND_OP_ADD,
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
})
.add_shader("shaders/out/simple.vert.spv", VK_SHADER_STAGE_VERTEX_BIT)
.add_shader("shaders/out/simple.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT)
.build();
swapchain.create_framebuffers(pass.render_pass);
basalt::CommandPool cmdpool(dev, phy_dev.indicies.graphics);
basalt::darray<basalt::CommandBuffer> cmdbufs(swapchain.max_frames_in_flight, MEMORY_TAG_CLASS_DYNARRAY | MEMORY_TAG_ZONE_APPLICATION | MEMORY_TAG_ALIGN_32);
for (u32 i = 0; i < swapchain.max_frames_in_flight; ++i)
new (cmdbufs.m_pdata+i) basalt::CommandBuffer(std::move(cmdpool.get_buffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY)));
cmdbufs.m_nelements = swapchain.max_frames_in_flight;
u32 mem_str_len = 0;
char* mem_str = nullptr;
basalt::mem::get_memory_usage_string(&mem_str_len, &mem_str);
BINFO("%s\n", mem_str);
basalt::mem::dealloc(mem_str, mem_str_len, MEMORY_TAG_CLASS_STRING | MEMORY_TAG_ZONE_DEBUG | MEMORY_TAG_ALIGN_ANY);
VkResult err = VK_SUCCESS;
VkRect2D render_area = { .offset = {0,0}, .extent = swapchain.swapchain_extent };
VkViewport viewport = {
.x = (float)render_area.offset.x,
.y = (float)render_area.offset.y,
.width = (float)render_area.extent.width,
.height = (float)render_area.extent.height,
.minDepth = 0.0f,
.maxDepth = 1.0f
};
while (!window.should_close()) while (!window.should_close())
{ {
glfwPollEvents(); glfwPollEvents();
swapchain.wait_and_reset();
u32 image_index = swapchain.acquire_next_image();
cmdbufs[swapchain.current_frame].reset();
cmdbufs[swapchain.current_frame].start(pass, swapchain.framebuffers[image_index], render_area);
cmdbufs[swapchain.current_frame].bind_pipeline(pipeline, VK_PIPELINE_BIND_POINT_GRAPHICS);
cmdbufs[swapchain.current_frame].set_scissor(render_area);
cmdbufs[swapchain.current_frame].set_viewport(viewport);
vkCmdDraw(cmdbufs[swapchain.current_frame].vk, 3, 1, 0, 0);
cmdbufs[swapchain.current_frame].stop();
VkSubmitInfo submit_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO};
VkSemaphore wait_semaphores[] = {swapchain.semaphores_image_available[swapchain.current_frame]};
VkSemaphore signal_semaphores[] = {swapchain.semaphores_render_finished[image_index]};
VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = &cmdbufs[swapchain.current_frame].vk;
submit_info.waitSemaphoreCount = 1;
submit_info.pWaitSemaphores = wait_semaphores;
submit_info.pWaitDstStageMask = wait_stages;
submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = signal_semaphores;
VK_ASSERT(vkQueueSubmit(dev.queues[0].queue, 1, &submit_info, swapchain.fences_in_flight[swapchain.current_frame]), "Failed to submit command buffer(s) to queue\n\tAt %s:%d\n\tError %s\n");
VkPresentInfoKHR present_info = {VK_STRUCTURE_TYPE_PRESENT_INFO_KHR};
present_info.pNext = VK_NULL_HANDLE;
present_info.pResults = VK_NULL_HANDLE;
present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = signal_semaphores;
present_info.swapchainCount = 1;
present_info.pSwapchains = &swapchain.swapchain;
present_info.pImageIndices = &image_index;
VK_ASSERT(vkQueuePresentKHR(dev.queues[1].queue, &present_info), "Failed to queue presentation of rendered frame\n\tAt %s:%d\n\tError %s\n");
swapchain.current_frame = (swapchain.current_frame + 1) % swapchain.max_frames_in_flight;
} }
cmdbufs.resize(0);
}
int main()
{
initialize_logger();
basalt::mem::initialize_memory();
glfwInit();
logger_set_global_mask(LOG_MASK_ALL);
logger_set_mask(logger_find_stream(stdout), LOG_DEBUG | LOG_MASK_INFO | LOG_TRACE);
application();
u32 mem_str_len = 0;
char* mem_str = nullptr;
basalt::mem::get_memory_usage_string(&mem_str_len, &mem_str);
BINFO("%s\n", mem_str);
basalt::mem::dealloc(mem_str, mem_str_len, MEMORY_TAG_CLASS_STRING | MEMORY_TAG_ZONE_DEBUG | MEMORY_TAG_ALIGN_ANY);
glfwTerminate();
basalt::mem::terminate_memory();
terminate_logger();
return 0; return 0;
} }