summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhunter@kvog.sh <hunter@kvog.sh>2026-03-15 17:00:37 -0500
committerhunter@kvog.sh <hunter@kvog.sh>2026-03-15 17:00:37 -0500
commitf409e568ef60940d5dfb2c3479d43dd19882f780 (patch)
tree0a339675115c57727ba72551edd4c53cd5a4e6d3
parent62b66395da15266c6ec41d7384f237d0e16fbc90 (diff)
-rw-r--r--common/c_cpp/CMakeLists.txt5
-rw-r--r--common/c_cpp/vkutil.h44
-rwxr-xr-xvk-asylum/build-shaders.sh6
-rw-r--r--vk-asylum/main.c370
-rw-r--r--vk-asylum/shaders.h2
-rw-r--r--vk-asylum/triangle_fs.glsl11
-rw-r--r--vk-asylum/triangle_vs.glsl13
7 files changed, 435 insertions, 16 deletions
diff --git a/common/c_cpp/CMakeLists.txt b/common/c_cpp/CMakeLists.txt
index d629db3..a6f09eb 100644
--- a/common/c_cpp/CMakeLists.txt
+++ b/common/c_cpp/CMakeLists.txt
@@ -37,6 +37,11 @@ if(NOT MINGW)
endif()
# -----------------------------------------------------------------------------
+# Include helper files
+# -----------------------------------------------------------------------------
+target_include_directories(common INTERFACE "${CMAKE_CURRENT_LIST_DIR}")
+
+# -----------------------------------------------------------------------------
# Dependency: Dear ImGui
# -----------------------------------------------------------------------------
if(DEMO_NEEDS_DEAR_IMGUI)
diff --git a/common/c_cpp/vkutil.h b/common/c_cpp/vkutil.h
index 89c7940..2530831 100644
--- a/common/c_cpp/vkutil.h
+++ b/common/c_cpp/vkutil.h
@@ -1,5 +1,49 @@
#ifndef _DEMOS_VKUTIL_H_
#define _DEMOS_VKUTIL_H_
+static inline const char* VkResultToString(VkResult result)
+{
+ // ref: https://docs.vulkan.org/refpages/latest/refpages/source/VkResult.html
+ switch (result) {
+#define X(_E) case _E: return #_E;
+ X(VK_SUCCESS);
+ X(VK_NOT_READY);
+ X(VK_TIMEOUT);
+ X(VK_EVENT_SET);
+ X(VK_EVENT_RESET);
+ X(VK_INCOMPLETE);
+ X(VK_ERROR_OUT_OF_HOST_MEMORY);
+ X(VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ X(VK_ERROR_INITIALIZATION_FAILED);
+ X(VK_ERROR_DEVICE_LOST);
+ X(VK_ERROR_MEMORY_MAP_FAILED);
+ X(VK_ERROR_LAYER_NOT_PRESENT);
+ X(VK_ERROR_EXTENSION_NOT_PRESENT);
+ X(VK_ERROR_FEATURE_NOT_PRESENT);
+ X(VK_ERROR_INCOMPATIBLE_DRIVER);
+ X(VK_ERROR_TOO_MANY_OBJECTS);
+ X(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ X(VK_ERROR_FRAGMENTED_POOL);
+ X(VK_ERROR_UNKNOWN);
+ X(VK_ERROR_VALIDATION_FAILED);
+ X(VK_ERROR_OUT_OF_POOL_MEMORY);
+ X(VK_ERROR_INVALID_EXTERNAL_HANDLE);
+ X(VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS);
+ X(VK_ERROR_FRAGMENTATION);
+ X(VK_PIPELINE_COMPILE_REQUIRED);
+ X(VK_ERROR_NOT_PERMITTED);
+ X(VK_ERROR_SURFACE_LOST_KHR);
+ X(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR);
+ X(VK_SUBOPTIMAL_KHR);
+ X(VK_ERROR_OUT_OF_DATE_KHR);
+#undef X
+ default: {
+ static char buf[64]; // @@ should be thread-local
+ snprintf(buf, sizeof(buf), "VkResult(%d)", result);
+ return buf;
+ } break;
+ }
+}
+
#endif // _DEMOS_VKUTIL_H_
diff --git a/vk-asylum/build-shaders.sh b/vk-asylum/build-shaders.sh
new file mode 100755
index 0000000..51d4475
--- /dev/null
+++ b/vk-asylum/build-shaders.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+mkdir -p build
+glslc -fshader-stage=vert ./triangle_vs.glsl -o build/triangle_vs.spv
+glslc -fshader-stage=frag ./triangle_fs.glsl -o build/triangle_fs.spv
+echo "const uint32_t triangle_vert_spv[] = { "$(hexdump -v -e '1/4 "0x%08x, "' build/triangle_vs.spv)" };" > shaders.h
+echo "const uint32_t triangle_frag_spv[] = { "$(hexdump -v -e '1/4 "0x%08x, "' build/triangle_vs.spv)" };" >> shaders.h
diff --git a/vk-asylum/main.c b/vk-asylum/main.c
index 2e0e0b2..74e86e2 100644
--- a/vk-asylum/main.c
+++ b/vk-asylum/main.c
@@ -6,37 +6,375 @@
#include <SDL3/SDL.h>
#include <SDL3/SDL_vulkan.h>
#include <stdlib.h>
+#include <stdio.h>
#include <vulkan/vulkan.h>
+#include "vkutil.h"
#define COUNTOF(_Arr) (sizeof(_Arr) / sizeof((_Arr)[0]))
#define DIE(...) do { printf(__VA_ARGS__); printf("\n"); exit(1); } while (0);
#define ASSERT(_Expr) do { if (!(_Expr)) { DIE("%s:%d: " #_Expr, __FILE__, __LINE__); } } while (0);
+#define WND_W 1024
+#define WND_H 768
+
int main(int argc, char* argv[])
{
(void)argc; (void)argv;
SDL_Init(SDL_INIT_VIDEO);
- SDL_Window* wnd = SDL_CreateWindow("vk-asylum", 1024, 768, SDL_WINDOW_VULKAN);
+ SDL_Window* wnd = SDL_CreateWindow("vk-asylum", WND_W, WND_H, SDL_WINDOW_VULKAN);
ASSERT(wnd);
- VkApplicationInfo vkai = (VkApplicationInfo){
- .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
- .apiVersion = VK_API_VERSION_1_4,
- };
- VkInstanceCreateInfo vkici = (VkInstanceCreateInfo){
- .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
- .pApplicationInfo = &vkai,
- };
+ VkResult r = VK_SUCCESS;
- vkici.ppEnabledExtensionNames = SDL_Vulkan_GetInstanceExtensions(&vkici.enabledExtensionCount);
- printf("Instance extensions requested by SDL:\n");
- for (uint32_t i = 0; i < vkici.enabledExtensionCount; ++i) {
- printf(" %s\n", vkici.ppEnabledExtensionNames[i]);
- }
+ VkInstance vk = 0;
+ {
+ VkApplicationInfo vkai = (VkApplicationInfo){
+ .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
+ .apiVersion = VK_API_VERSION_1_4,
+ };
+ VkInstanceCreateInfo vkici = (VkInstanceCreateInfo){
+ .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+ .pApplicationInfo = &vkai,
+ };
+
+ vkici.ppEnabledExtensionNames = SDL_Vulkan_GetInstanceExtensions(&vkici.enabledExtensionCount);
+ printf("Instance extensions requested by SDL:\n");
+ for (uint32_t i = 0; i < vkici.enabledExtensionCount; ++i) {
+ printf(" %s\n", vkici.ppEnabledExtensionNames[i]);
+ }
#ifdef __APPLE__
- // Required for instance extension VK_KHR_portability_enumeration (MoltenVK)
- vkici.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
+ // Required for instance extension VK_KHR_portability_enumeration (MoltenVK)
+ vkici.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
#endif
+
+ if ((r = vkCreateInstance(&vkici, 0, &vk)) != VK_SUCCESS) {
+ DIE("Failed to create Vulkan instance: %s", VkResultToString(r));
+ }
+ }
+
+ VkSurfaceKHR vk_surf = 0;
+ if (!SDL_Vulkan_CreateSurface(wnd, vk, 0, &vk_surf)) {
+ DIE("Failed to create Vulkan surface: %s", SDL_GetError());
+ }
+
+ VkPhysicalDevice vk_pdev = 0;
+ {
+ uint32_t vk_pdev_count = 0;
+ vkEnumeratePhysicalDevices(vk, &vk_pdev_count, 0);
+ if (vk_pdev_count < 1) {
+ DIE("No Vulkan-capable devices available");
+ }
+
+ VkPhysicalDevice* vk_pdevs = calloc(vk_pdev_count, sizeof(VkPhysicalDevice));
+ vkEnumeratePhysicalDevices(vk, &vk_pdev_count, vk_pdevs);
+
+ // Just pick the first available physical device
+ vk_pdev = vk_pdevs[0];
+
+ printf("Vulkan devices:\n");
+ for (uint32_t i = 0; i < vk_pdev_count; ++i) {
+ VkPhysicalDeviceProperties vk_pdev_props = { 0 };
+ vkGetPhysicalDeviceProperties(vk_pdev, &vk_pdev_props);
+ printf(" %s\n", vk_pdev_props.deviceName);
+ }
+
+ free(vk_pdevs);
+ }
+
+ uint32_t vk_qf_index = (uint32_t)-1;
+ {
+ uint32_t vk_qf_count = 0;
+ vkGetPhysicalDeviceQueueFamilyProperties(vk_pdev, &vk_qf_count, 0);
+ ASSERT(vk_qf_count > 0);
+
+ VkQueueFamilyProperties* vk_qfs = calloc(vk_qf_count, sizeof(VkQueueFamilyProperties));
+ vkGetPhysicalDeviceQueueFamilyProperties(vk_pdev, &vk_qf_count, vk_qfs);
+
+ // Select queue family with graphics capabilities
+ for (uint32_t i = 0; i < vk_qf_count; ++i) {
+ if (vk_qfs[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
+ vk_qf_index = i;
+ break;
+ }
+ }
+
+ free(vk_qfs);
+ }
+ ASSERT(vk_qf_index != (uint32_t)-1);
+
+ VkDevice vk_dev = 0;
+ {
+ float priority = 1.0f;
+ VkDeviceQueueCreateInfo queue_create = (VkDeviceQueueCreateInfo){
+ .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
+ .queueFamilyIndex = vk_qf_index,
+ .queueCount = 1,
+ .pQueuePriorities = &priority,
+ };
+
+ const char* device_extensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, };
+ VkDeviceCreateInfo device_create = (VkDeviceCreateInfo){
+ .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+ .queueCreateInfoCount = 1,
+ .pQueueCreateInfos = &queue_create,
+ .enabledExtensionCount = COUNTOF(device_extensions),
+ .ppEnabledExtensionNames = device_extensions,
+ };
+
+ if ((r = vkCreateDevice(vk_pdev, &device_create, 0, &vk_dev)) != VK_SUCCESS) {
+ DIE("Failed to create logical device: %s", VkResultToString(r));
+ }
+ }
+
+ VkQueue vk_graphics_queue = 0;
+ vkGetDeviceQueue(vk_dev, vk_qf_index, 0, &vk_graphics_queue);
+
+ VkSwapchainKHR vk_swp = 0;
+ VkExtent2D vk_extent;
+ {
+ VkSurfaceCapabilitiesKHR surf_caps = { 0 };
+ if ((r = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk_pdev, vk_surf, &surf_caps)) != VK_SUCCESS) {
+ DIE("Failed to get device surface capabilities: %s", VkResultToString(r));
+ }
+
+ vk_extent = surf_caps.currentExtent;
+ if (vk_extent.width == UINT32_MAX || vk_extent.height == UINT32_MAX) {
+ vk_extent.width = WND_W;
+ vk_extent.height = WND_H;
+ }
+
+ VkSwapchainCreateInfoKHR swapchain_create = (VkSwapchainCreateInfoKHR){
+ .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
+ .surface = vk_surf,
+ .minImageCount = 3,
+ .imageFormat = VK_FORMAT_B8G8R8A8_SRGB,
+ .imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
+ .imageExtent = vk_extent,
+ .imageArrayLayers = 1,
+ .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+ .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
+ .preTransform = surf_caps.currentTransform,
+ .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
+ .presentMode = VK_PRESENT_MODE_FIFO_KHR,
+ .clipped = VK_TRUE,
+ .oldSwapchain = VK_NULL_HANDLE,
+ };
+ if ((r = vkCreateSwapchainKHR(vk_dev, &swapchain_create, 0, &vk_swp)) != VK_SUCCESS) {
+ DIE("Failed to create swapchain: %s", VkResultToString(r));
+ }
+ }
+
+ uint32_t vk_swap_image_count = 0;
+ VkImage* vk_swap_images = 0;
+ VkImageView* vk_swap_image_views = 0;
+ {
+ vkGetSwapchainImagesKHR(vk_dev, vk_swp, &vk_swap_image_count, 0);
+ ASSERT(vk_swap_image_count > 0);
+ vk_swap_images = calloc(vk_swap_image_count, sizeof(VkImage));
+ vkGetSwapchainImagesKHR(vk_dev, vk_swp, &vk_swap_image_count, vk_swap_images);
+
+ vk_swap_image_views = calloc(vk_swap_image_count, sizeof(VkImageView));
+ for (uint32_t i = 0; i < vk_swap_image_count; ++i) {
+ VkImageViewCreateInfo image_view_create = (VkImageViewCreateInfo){
+ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+ .image = vk_swap_images[i],
+ .viewType = VK_IMAGE_VIEW_TYPE_2D,
+ .format = VK_FORMAT_B8G8R8A8_SRGB,
+ .components.r = VK_COMPONENT_SWIZZLE_IDENTITY,
+ .components.g = VK_COMPONENT_SWIZZLE_IDENTITY,
+ .components.b = VK_COMPONENT_SWIZZLE_IDENTITY,
+ .components.a = VK_COMPONENT_SWIZZLE_IDENTITY,
+ .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .subresourceRange.baseMipLevel = 0,
+ .subresourceRange.levelCount = 1,
+ .subresourceRange.baseArrayLayer = 0,
+ .subresourceRange.layerCount = 1,
+ };
+ if ((r = vkCreateImageView(vk_dev, &image_view_create, 0, &vk_swap_image_views[i])) != VK_SUCCESS) {
+ DIE("Failed to create image view #%u: %s", i, VkResultToString(r));
+ }
+ }
+ }
+
+ VkRenderPass vk_pass = 0;
+ {
+ VkAttachmentDescription attachment = (VkAttachmentDescription){
+ .format = VK_FORMAT_B8G8R8A8_SRGB,
+ .samples = VK_SAMPLE_COUNT_1_BIT,
+ .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
+ .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+ .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+ .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
+ .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
+ .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+ };
+ VkAttachmentReference color_ref = (VkAttachmentReference){
+ .attachment = 0,
+ .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ };
+ VkSubpassDescription subpass = (VkSubpassDescription){
+ .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
+ .colorAttachmentCount = 1,
+ .pColorAttachments = &color_ref,
+ };
+ VkSubpassDependency dep = (VkSubpassDependency){
+ .srcSubpass = VK_SUBPASS_EXTERNAL,
+ .dstSubpass = 0,
+ .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ };
+ VkRenderPassCreateInfo render_pass_create = (VkRenderPassCreateInfo){
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+ .attachmentCount = 1,
+ .pAttachments = &attachment,
+ .subpassCount = 1,
+ .pSubpasses = &subpass,
+ .dependencyCount = 1,
+ .pDependencies = &dep,
+ };
+ if ((r = vkCreateRenderPass(vk_dev, &render_pass_create, 0, &vk_pass)) != VK_SUCCESS) {
+ DIE("Failed to create render pass: %s", VkResultToString(r));
+ }
+ }
+
+ VkFramebuffer* vk_framebuffers = calloc(vk_swap_image_count, sizeof(VkFramebuffer));
+ {
+ for (uint32_t i = 0; i < vk_swap_image_count; ++i) {
+ VkImageView attachments[] = { vk_swap_image_views[i] };
+ VkFramebufferCreateInfo framebuffer_create = (VkFramebufferCreateInfo){
+ .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+ .renderPass = vk_pass,
+ .attachmentCount = 1,
+ .pAttachments = attachments,
+ .width = vk_extent.width,
+ .height = vk_extent.height,
+ .layers = 1,
+ };
+ if ((r = vkCreateFramebuffer(vk_dev, &framebuffer_create, 0, &vk_framebuffers[i])) != VK_SUCCESS) {
+ DIE("Failed to create render pass #%u: %s", i, VkResultToString(r));
+ }
+ }
+ }
+
+ VkPipeline vk_pipeline = 0;
+ {
+ VkPipelineLayoutCreateInfo pipeline_layout_create = (VkPipelineLayoutCreateInfo){
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+ };
+ VkPipelineLayout pipeline_layout = 0;
+ if ((r = vkCreatePipelineLayout(vk_dev, &pipeline_layout_create, 0, &pipeline_layout)) != VK_SUCCESS) {
+ DIE("Failed to create pipeline layout: %s", VkResultToString(r));
+ }
+ }
+
+ VkCommandPool vk_cmd_pool = 0;
+ {
+ VkCommandPoolCreateInfo cmd_pool_create = (VkCommandPoolCreateInfo){
+ .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+ .queueFamilyIndex = vk_qf_index,
+ .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
+ };
+ if ((r = vkCreateCommandPool(vk_dev, &cmd_pool_create, 0, &vk_cmd_pool)) != VK_SUCCESS) {
+ DIE("Failed to create command pool: %s", VkResultToString(r));
+ }
+ }
+
+ VkCommandBuffer* vk_cmd_buffers = calloc(vk_swap_image_count, sizeof(VkCommandBuffer));
+ {
+ VkCommandBufferAllocateInfo cmd_buffer_info = (VkCommandBufferAllocateInfo){
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+ .commandPool = vk_cmd_pool,
+ .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+ .commandBufferCount = vk_swap_image_count,
+ };
+ if ((r = vkAllocateCommandBuffers(vk_dev, &cmd_buffer_info, vk_cmd_buffers)) != VK_SUCCESS) {
+ DIE("Failed to allocate command buffers: %s", VkResultToString(r));
+ }
+ }
+
+ for (uint32_t i = 0; i < vk_swap_image_count; ++i) {
+ VkCommandBufferBeginInfo cmd_buffer_begin_info = (VkCommandBufferBeginInfo){
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+ };
+ if ((r = vkBeginCommandBuffer(vk_cmd_buffers[i], &cmd_buffer_begin_info)) != VK_SUCCESS) {
+ DIE("Failed to begin command buffer for swapchain image #%u: %s", i, VkResultToString(r));
+ }
+
+ VkClearValue clear_val = (VkClearValue){
+ .color.float32[0] = 1.0f,
+ .color.float32[1] = 0.0f,
+ .color.float32[2] = 1.0f,
+ .color.float32[3] = 1.0f,
+ };
+ VkRenderPassBeginInfo render_pass_begin_info = (VkRenderPassBeginInfo){
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+ .renderPass = vk_pass,
+ .framebuffer = vk_framebuffers[i],
+ .renderArea.extent = vk_extent,
+ .clearValueCount = 1,
+ .pClearValues = &clear_val
+ };
+ vkCmdBeginRenderPass(vk_cmd_buffers[i], &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
+
+ //
+
+ vkCmdEndRenderPass(vk_cmd_buffers[i]);
+ vkEndCommandBuffer(vk_cmd_buffers[i]);
+ }
+
+ VkSemaphore vk_image_available = 0;
+ VkSemaphore vk_render_finished = 0;
+ {
+ VkSemaphoreCreateInfo semaphore_create = (VkSemaphoreCreateInfo){
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+ };
+ vkCreateSemaphore(vk_dev, &semaphore_create, 0, &vk_image_available);
+ vkCreateSemaphore(vk_dev, &semaphore_create, 0, &vk_render_finished);
+ }
+
+ bool running = true;
+ while (running) {
+ SDL_Event evt;
+ while (SDL_PollEvent(&evt)) {
+ switch (evt.type) {
+ case SDL_EVENT_QUIT: {
+ running = false;
+ } break;
+ }
+ }
+
+ uint32_t next_image_idx = 0;
+ vkAcquireNextImageKHR(vk_dev, vk_swp, UINT64_MAX, vk_image_available, VK_NULL_HANDLE, &next_image_idx);
+
+ VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
+ VkSubmitInfo submit_info = (VkSubmitInfo){
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+ .waitSemaphoreCount = 1,
+ .pWaitSemaphores = &vk_image_available,
+ .pWaitDstStageMask = wait_stages,
+ .commandBufferCount = 1,
+ .pCommandBuffers = &vk_cmd_buffers[next_image_idx],
+ .signalSemaphoreCount = 1,
+ .pSignalSemaphores = &vk_render_finished,
+ };
+ if ((r = vkQueueSubmit(vk_graphics_queue, 1, &submit_info, VK_NULL_HANDLE)) != VK_SUCCESS) {
+ DIE("Failed to submit graphics queue: %s", VkResultToString(r));
+ }
+
+ VkPresentInfoKHR present_info = (VkPresentInfoKHR){
+ .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+ .waitSemaphoreCount = 1,
+ .pWaitSemaphores = &vk_render_finished,
+ .swapchainCount = 1,
+ .pSwapchains = &vk_swp,
+ .pImageIndices = &next_image_idx,
+ };
+ if ((r = vkQueuePresentKHR(vk_graphics_queue, &present_info)) != VK_SUCCESS) {
+ DIE("Failed to submit present queue: %s", VkResultToString(r));
+ }
+ }
}
+
diff --git a/vk-asylum/shaders.h b/vk-asylum/shaders.h
new file mode 100644
index 0000000..3ceda9c
--- /dev/null
+++ b/vk-asylum/shaders.h
@@ -0,0 +1,2 @@
+const uint32_t triangle_vert_spv[] = { 0x07230203, 0x00010000, 0x000d000b, 0x0000001f, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0009000f, 0x00000000, 0x00000004, 0x6e69616d, 0x00000000, 0x0000000d, 0x00000012, 0x0000001c, 0x0000001d, 0x00030003, 0x00000002, 0x000001c2, 0x000a0004, 0x475f4c47, 0x4c474f4f, 0x70635f45, 0x74735f70, 0x5f656c79, 0x656e696c, 0x7269645f, 0x69746365, 0x00006576, 0x00080004, 0x475f4c47, 0x4c474f4f, 0x6e695f45, 0x64756c63, 0x69645f65, 0x74636572, 0x00657669, 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00060005, 0x0000000b, 0x505f6c67, 0x65567265, 0x78657472, 0x00000000, 0x00060006, 0x0000000b, 0x00000000, 0x505f6c67, 0x7469736f, 0x006e6f69, 0x00070006, 0x0000000b, 0x00000001, 0x505f6c67, 0x746e696f, 0x657a6953, 0x00000000, 0x00070006, 0x0000000b, 0x00000002, 0x435f6c67, 0x4470696c, 0x61747369, 0x0065636e, 0x00070006, 0x0000000b, 0x00000003, 0x435f6c67, 0x446c6c75, 0x61747369, 0x0065636e, 0x00030005, 0x0000000d, 0x00000000, 0x00030005, 0x00000012, 0x00705f76, 0x00030005, 0x0000001c, 0x00635f66, 0x00030005, 0x0000001d, 0x00635f76, 0x00030047, 0x0000000b, 0x00000002, 0x00050048, 0x0000000b, 0x00000000, 0x0000000b, 0x00000000, 0x00050048, 0x0000000b, 0x00000001, 0x0000000b, 0x00000001, 0x00050048, 0x0000000b, 0x00000002, 0x0000000b, 0x00000003, 0x00050048, 0x0000000b, 0x00000003, 0x0000000b, 0x00000004, 0x00040047, 0x00000012, 0x0000001e, 0x00000000, 0x00040047, 0x0000001c, 0x0000001e, 0x00000000, 0x00040047, 0x0000001d, 0x0000001e, 0x00000001, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, 0x00000006, 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000004, 0x00040015, 0x00000008, 0x00000020, 0x00000000, 0x0004002b, 0x00000008, 0x00000009, 0x00000001, 0x0004001c, 0x0000000a, 0x00000006, 0x00000009, 0x0006001e, 0x0000000b, 0x00000007, 0x00000006, 0x0000000a, 0x0000000a, 0x00040020, 0x0000000c, 0x00000003, 0x0000000b, 0x0004003b, 0x0000000c, 0x0000000d, 0x00000003, 0x00040015, 0x0000000e, 0x00000020, 0x00000001, 0x0004002b, 0x0000000e, 0x0000000f, 0x00000000, 0x00040017, 0x00000010, 0x00000006, 0x00000003, 0x00040020, 0x00000011, 0x00000001, 0x00000010, 0x0004003b, 0x00000011, 0x00000012, 0x00000001, 0x0004002b, 0x00000006, 0x00000014, 0x3f800000, 0x00040020, 0x00000019, 0x00000003, 0x00000007, 0x00040020, 0x0000001b, 0x00000003, 0x00000010, 0x0004003b, 0x0000001b, 0x0000001c, 0x00000003, 0x0004003b, 0x00000011, 0x0000001d, 0x00000001, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0004003d, 0x00000010, 0x00000013, 0x00000012, 0x00050051, 0x00000006, 0x00000015, 0x00000013, 0x00000000, 0x00050051, 0x00000006, 0x00000016, 0x00000013, 0x00000001, 0x00050051, 0x00000006, 0x00000017, 0x00000013, 0x00000002, 0x00070050, 0x00000007, 0x00000018, 0x00000015, 0x00000016, 0x00000017, 0x00000014, 0x00050041, 0x00000019, 0x0000001a, 0x0000000d, 0x0000000f, 0x0003003e, 0x0000001a, 0x00000018, 0x0004003d, 0x00000010, 0x0000001e, 0x0000001d, 0x0003003e, 0x0000001c, 0x0000001e, 0x000100fd, 0x00010038, };
+const uint32_t triangle_frag_spv[] = { 0x07230203, 0x00010000, 0x000d000b, 0x0000001f, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0009000f, 0x00000000, 0x00000004, 0x6e69616d, 0x00000000, 0x0000000d, 0x00000012, 0x0000001c, 0x0000001d, 0x00030003, 0x00000002, 0x000001c2, 0x000a0004, 0x475f4c47, 0x4c474f4f, 0x70635f45, 0x74735f70, 0x5f656c79, 0x656e696c, 0x7269645f, 0x69746365, 0x00006576, 0x00080004, 0x475f4c47, 0x4c474f4f, 0x6e695f45, 0x64756c63, 0x69645f65, 0x74636572, 0x00657669, 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00060005, 0x0000000b, 0x505f6c67, 0x65567265, 0x78657472, 0x00000000, 0x00060006, 0x0000000b, 0x00000000, 0x505f6c67, 0x7469736f, 0x006e6f69, 0x00070006, 0x0000000b, 0x00000001, 0x505f6c67, 0x746e696f, 0x657a6953, 0x00000000, 0x00070006, 0x0000000b, 0x00000002, 0x435f6c67, 0x4470696c, 0x61747369, 0x0065636e, 0x00070006, 0x0000000b, 0x00000003, 0x435f6c67, 0x446c6c75, 0x61747369, 0x0065636e, 0x00030005, 0x0000000d, 0x00000000, 0x00030005, 0x00000012, 0x00705f76, 0x00030005, 0x0000001c, 0x00635f66, 0x00030005, 0x0000001d, 0x00635f76, 0x00030047, 0x0000000b, 0x00000002, 0x00050048, 0x0000000b, 0x00000000, 0x0000000b, 0x00000000, 0x00050048, 0x0000000b, 0x00000001, 0x0000000b, 0x00000001, 0x00050048, 0x0000000b, 0x00000002, 0x0000000b, 0x00000003, 0x00050048, 0x0000000b, 0x00000003, 0x0000000b, 0x00000004, 0x00040047, 0x00000012, 0x0000001e, 0x00000000, 0x00040047, 0x0000001c, 0x0000001e, 0x00000000, 0x00040047, 0x0000001d, 0x0000001e, 0x00000001, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, 0x00000006, 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000004, 0x00040015, 0x00000008, 0x00000020, 0x00000000, 0x0004002b, 0x00000008, 0x00000009, 0x00000001, 0x0004001c, 0x0000000a, 0x00000006, 0x00000009, 0x0006001e, 0x0000000b, 0x00000007, 0x00000006, 0x0000000a, 0x0000000a, 0x00040020, 0x0000000c, 0x00000003, 0x0000000b, 0x0004003b, 0x0000000c, 0x0000000d, 0x00000003, 0x00040015, 0x0000000e, 0x00000020, 0x00000001, 0x0004002b, 0x0000000e, 0x0000000f, 0x00000000, 0x00040017, 0x00000010, 0x00000006, 0x00000003, 0x00040020, 0x00000011, 0x00000001, 0x00000010, 0x0004003b, 0x00000011, 0x00000012, 0x00000001, 0x0004002b, 0x00000006, 0x00000014, 0x3f800000, 0x00040020, 0x00000019, 0x00000003, 0x00000007, 0x00040020, 0x0000001b, 0x00000003, 0x00000010, 0x0004003b, 0x0000001b, 0x0000001c, 0x00000003, 0x0004003b, 0x00000011, 0x0000001d, 0x00000001, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0004003d, 0x00000010, 0x00000013, 0x00000012, 0x00050051, 0x00000006, 0x00000015, 0x00000013, 0x00000000, 0x00050051, 0x00000006, 0x00000016, 0x00000013, 0x00000001, 0x00050051, 0x00000006, 0x00000017, 0x00000013, 0x00000002, 0x00070050, 0x00000007, 0x00000018, 0x00000015, 0x00000016, 0x00000017, 0x00000014, 0x00050041, 0x00000019, 0x0000001a, 0x0000000d, 0x0000000f, 0x0003003e, 0x0000001a, 0x00000018, 0x0004003d, 0x00000010, 0x0000001e, 0x0000001d, 0x0003003e, 0x0000001c, 0x0000001e, 0x000100fd, 0x00010038, };
diff --git a/vk-asylum/triangle_fs.glsl b/vk-asylum/triangle_fs.glsl
new file mode 100644
index 0000000..543fd79
--- /dev/null
+++ b/vk-asylum/triangle_fs.glsl
@@ -0,0 +1,11 @@
+#version 450
+
+layout (location = 0) in vec3 f_c;
+
+layout (location = 0) out vec4 f_out_color;
+
+void main()
+{
+ f_out_color = vec4(f_c, 1.0f);
+}
+
diff --git a/vk-asylum/triangle_vs.glsl b/vk-asylum/triangle_vs.glsl
new file mode 100644
index 0000000..3d87f3e
--- /dev/null
+++ b/vk-asylum/triangle_vs.glsl
@@ -0,0 +1,13 @@
+#version 450
+
+layout (location = 0) in vec3 v_p;
+layout (location = 1) in vec3 v_c;
+
+layout (location = 0) out vec3 f_c;
+
+void main()
+{
+ gl_Position = vec4(v_p, 1.0f);
+ f_c = v_c;
+}
+