Test program has been expanded to draw a RGB triangle
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user