Compare commits

...

4 Commits

Author SHA1 Message Date
abdelrahman 2cdfcde5a3 Add swapchain recreation. Needs debugging though 2026-06-21 20:51:46 +01:00
abdelrahman ef12ba03d8 Bug fixes 2026-06-21 20:09:54 +01:00
abdelrahman a425166018 Render loop 2026-06-21 17:02:09 +01:00
abdelrahman f253b6f683 Build executable with RPATH 2026-06-21 17:02:02 +01:00
3 changed files with 353 additions and 19 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ build_ktx () {
build_app () {
bear -- clang++ -g -c -Wno-nullability-completeness -DVK_NO_PROTOTYPES -I$VULKAN_SDK/include -Ivendor/include vulkan_profiles/vulkan_profiles.cpp main.cpp
bear -a -- clang -g -c -DVK_NO_PROTOTYPES -Ivulkan_profiles -I$VULKAN_SDK/include $VULKAN_SDK/include/volk/volk.c wapp/wapp.c
bear -a -- clang++ -g -DVK_NO_PROTOTYPES -L$VULKAN_SDK/lib -Lvendor/lib -lSDL3 -lglm -ltinyobjloader -lktx -lslang -o main *.o
bear -a -- clang++ -g -DVK_NO_PROTOTYPES -L$VULKAN_SDK/lib -Lvendor/lib -lSDL3 -lglm -ltinyobjloader -lktx -lslang -Wl,-rpath,./vendor/lib -Wl,-rpath,$VULKAN_SDK/lib -o main *.o
}
clean_obj () {
+352 -15
View File
@@ -5,6 +5,8 @@
#include "vulkan_profiles/vulkan_profiles.h"
#include "ktx.h"
#include "ktxvulkan.h"
#include <SDL3/SDL_timer.h>
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/quaternion.hpp>
@@ -95,6 +97,8 @@ typedef slang::CompilerOptionEntry *SlangCompOptEntryArray;
typedef VkVertexInputAttributeDescription *VkVertexInputAttributeDescriptionArray;
typedef VkPipelineShaderStageCreateInfo *VkPipelineShaderStageCreateInfoArray;
typedef VkDynamicState *VkDynamicStateArray;
typedef glm::vec3 *GlmVec3Array;
typedef VkImageMemoryBarrier2 *VkImageMemoryBarrier2Array;
// }}}
// {{{ Helper Function Declarations
@@ -104,7 +108,10 @@ wapp_intern inline void check(bool result, i32 code);
// }}}
// {{{ Global Variables
wapp_intern u32 frame_index = 0;
wapp_intern u32 image_index = 0;
wapp_intern constexpr u32 max_frames_in_flight = 2;
wapp_intern constexpr u32 instance_count = 3;
wapp_intern constexpr u32 texture_count = 3;
wapp_intern bool running = true;
wapp_intern bool update_swapchain = false;
@@ -137,7 +144,7 @@ wapp_intern VmaAllocation vert_index_buf_alloc = VK_NULL_HANDLE;
wapp_intern ShaderData shader_data = {};
wapp_intern ShaderDataBufferArray shader_data_bufs;
wapp_intern VkFenceArray fences;
wapp_intern VkSemaphoreArray image_acquired_semaphores;
wapp_intern VkSemaphoreArray image_acquired_semaphores = nullptr;
wapp_intern VkSemaphoreArray render_completed_semaphores = nullptr;
wapp_intern VkCommandPool command_pool = VK_NULL_HANDLE;
wapp_intern VkCommandBufferArray command_buffers;
@@ -150,6 +157,8 @@ wapp_intern Slang::ComPtr<slang::IGlobalSession> slang_global_session;
wapp_intern VkShaderModule shader_module = VK_NULL_HANDLE;
wapp_intern VkPipelineLayout graphics_pipeline_layout = VK_NULL_HANDLE;
wapp_intern VkPipeline graphics_pipeline = VK_NULL_HANDLE;
wapp_intern glm::vec3 camera_position = {0.0f, 0.0f, -6.0f};
wapp_intern GlmVec3Array object_rotations;
// }}}
int main() {
@@ -161,8 +170,8 @@ int main() {
check(volkInitialize());
display_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
window = SDL_CreateWindow("How To Vulkan", (i32)(display_scale * 1920),
(i32)(display_scale * 1080), SDL_WINDOW_VULKAN);
window = SDL_CreateWindow("How To Vulkan", (i32)(display_scale * 1920), (i32)(display_scale * 1080),
SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
check(window != nullptr, EXIT_CODE_WINDOW_CREATION_FAILED);
// }}}
@@ -365,7 +374,8 @@ int main() {
VmaAllocatorCreateInfo allocator_create_info = {};
allocator_create_info.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT |
VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT;
VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT |
VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT;
allocator_create_info.instance = instance;
allocator_create_info.physicalDevice = physical_device;
allocator_create_info.device = device;
@@ -520,15 +530,15 @@ int main() {
1.0 - attrib.texcoords[index.texcoord_index * 2 + 1]
};
u16 idx = (u16)wapp_array_count(indices);
wapp_array_append_alloc(Vertex, &arena, vertices, &v, ARRAY_INIT_NONE);
wapp_array_append_alloc(u16, &arena, indices, &idx, ARRAY_INIT_NONE);
u16 idx = (u16)wapp_array_count(indices);
vertices = wapp_array_append_alloc(Vertex, &arena, vertices, &v, ARRAY_INIT_NONE);
indices = wapp_array_append_alloc(u16, &arena, indices, &idx, ARRAY_INIT_NONE);
}
// }}}
// {{{ Upload to GPU
VkDeviceSize vertex_buf_size = sizeof(Vertex) * wapp_array_count(vertices);
VkDeviceSize index_buf_size = sizeof(u16) * wapp_array_count(vertices);
VkDeviceSize index_buf_size = sizeof(u16) * wapp_array_count(indices);
VkBufferCreateInfo buf_create_info = {};
buf_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@@ -556,20 +566,20 @@ int main() {
shader_data_bufs = wapp_array_with_capacity(ShaderDataBuffer, max_frames_in_flight, ARRAY_INIT_FILLED);
for (u32 i = 0; i < max_frames_in_flight; ++i) {
// {{{ Create Buffer
VkBufferUsageFlags2CreateInfo data_buf_usage_flags = {};
data_buf_usage_flags.sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO;
data_buf_usage_flags.usage = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
VkBufferUsageFlags2CreateInfo buf_usage_flags = {};
buf_usage_flags.sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO;
buf_usage_flags.usage = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
VkBufferCreateInfo data_buf_create_info = {};
data_buf_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
data_buf_create_info.size = sizeof(ShaderData);
data_buf_create_info.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
data_buf_create_info.pNext = &data_buf_usage_flags;
data_buf_create_info.pNext = &buf_usage_flags;
VmaAllocationCreateInfo data_buf_alloc_create_info = {};
data_buf_alloc_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
VMA_ALLOCATION_CREATE_MAPPED_BIT;
data_buf_create_info.usage = VMA_MEMORY_USAGE_AUTO;
data_buf_alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO;
check(vmaCreateBuffer(allocator, &data_buf_create_info, &data_buf_alloc_create_info,
&shader_data_bufs[i].buffer, &shader_data_bufs[i].allocation,
@@ -1104,8 +1114,229 @@ int main() {
// }}}
// {{{ Render Loop
SDL_Event event = {};
/**
* Render loop overview:
* - Wait on fence
* - Acquire next image
* - Update shader data
* - Record command buffer
* - Submit command buffer
* - Present image
* - Poll events
*/
object_rotations = wapp_array_with_capacity(glm::vec3, instance_count, ARRAY_INIT_FILLED);
u64 last_time = SDL_GetTicks();
SDL_Event event = {};
while (running) {
// {{{ Wait On Fence
check(vkWaitForFences(device, 1, &fences[frame_index], VK_TRUE, UINT64_MAX));
check(vkResetFences(device, 1, &fences[frame_index]));
// }}}
// {{{ Acquire Next Swapchain Image
check_swapchain(vkAcquireNextImageKHR(device, swapchain, UINT64_MAX,
image_acquired_semaphores[frame_index], VK_NULL_HANDLE,
&image_index));
// }}}
// {{{ Update Shader Data
shader_data.projection = glm::perspective(glm::radians(45.0f), (f32)window_size.x / (f32)window_size.y,
0.1f, 32.0f);
shader_data.view = glm::translate(glm::mat4(1.0f), camera_position);
for (i32 i = 0; i < instance_count; ++i) {
glm::vec3 instance_pos = glm::vec3((f32)(i - 1) * 3.0f, 0.0f, 0.0f);
shader_data.model[i] = glm::translate(glm::mat4(1.0f), instance_pos) *
glm::mat4_cast(glm::quat(object_rotations[i]));
}
memcpy(shader_data_bufs[frame_index].allocation_info.pMappedData, &shader_data, sizeof(ShaderData));
// }}}
// {{{ Record Command Buffer
VkCommandBuffer cb = command_buffers[frame_index];
check(vkResetCommandBuffer(cb, 0));
VkCommandBufferBeginInfo cmd_begin_info = {};
cmd_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmd_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
check(vkBeginCommandBuffer(cb, &cmd_begin_info));
VkImageMemoryBarrier2Array memory_barriers = wapp_array_with_capacity(VkImageMemoryBarrier2, 2, ARRAY_INIT_FILLED);
// Color Attachment
memory_barriers[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
memory_barriers[0].srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
memory_barriers[0].srcAccessMask = 0;
memory_barriers[0].dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
memory_barriers[0].dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
memory_barriers[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
memory_barriers[0].newLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
memory_barriers[0].image = swapchain_images[image_index];
memory_barriers[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
memory_barriers[0].subresourceRange.levelCount = 1;
memory_barriers[0].subresourceRange.layerCount = 1;
// Depth Attachment
memory_barriers[1].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
memory_barriers[1].srcStageMask = VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT;
memory_barriers[1].srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
memory_barriers[1].dstStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT;
memory_barriers[1].dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
memory_barriers[1].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
memory_barriers[1].newLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
memory_barriers[1].image = depth_image;
memory_barriers[1].subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
memory_barriers[1].subresourceRange.levelCount = 1;
memory_barriers[1].subresourceRange.layerCount = 1;
// {{{ Transition Layout Color And Depth Images
VkDependencyInfo barrier_dependency_info = {};
barrier_dependency_info.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
barrier_dependency_info.imageMemoryBarrierCount = wapp_array_count(memory_barriers);
barrier_dependency_info.pImageMemoryBarriers = memory_barriers;
vkCmdPipelineBarrier2(cb, &barrier_dependency_info);
// }}}
// {{{ Dynamic Rendering Commands
VkClearValue color_clear_value = {};
color_clear_value.color = { 0.0f, 0.0f, 0.0f, 0.0f };
VkClearValue depth_clear_value = {};
depth_clear_value.depthStencil = { 1.0f, 0 };
VkRenderingAttachmentInfo color_attachment = {};
color_attachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
color_attachment.imageView = swapchain_views[image_index];
color_attachment.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
color_attachment.clearValue = color_clear_value;
VkRenderingAttachmentInfo depth_attachment = {};
depth_attachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
depth_attachment.imageView = depth_view;
depth_attachment.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depth_attachment.clearValue = depth_clear_value;
VkRect2D render_area = {};
render_area.extent = { (u32)window_size.x, (u32)window_size.y };
VkRenderingInfo render_info = {};
render_info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
render_info.renderArea = render_area;
render_info.layerCount = 1;
render_info.colorAttachmentCount = 1;
render_info.pColorAttachments = &color_attachment;
render_info.pDepthAttachment = &depth_attachment;
vkCmdBeginRendering(cb, &render_info);
// {{{ Set Viewport And Scissor Dynamic States
VkViewport viewport = {};
viewport.width = window_size.x;
viewport.height = window_size.y;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vkCmdSetViewport(cb, 0, 1, &viewport);
VkRect2D scissor = {};
scissor.extent = render_area.extent;
vkCmdSetScissor(cb, 0, 1, &scissor);
// }}}
// {{{ Bind Resources
vkCmdBindPipeline(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline);
vkCmdBindDescriptorSets(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline_layout, 0, 1, &desc_set_tex, 0, NULL);
VkDeviceSize vertex_offset = {};
vkCmdBindVertexBuffers(cb, 0, 1, &vert_index_buf, &vertex_offset);
vkCmdBindIndexBuffer(cb, vert_index_buf, vertex_buf_size, VK_INDEX_TYPE_UINT16);
// }}}
// {{{ Send ShaderData Buffer Device Address To Shader
vkCmdPushConstants(cb, graphics_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0,
sizeof(VkDeviceAddress), &shader_data_bufs[frame_index].device_address);
// }}}
// {{{ Draw Commands
vkCmdDrawIndexed(cb, index_count, instance_count, 0, 0, 0);
// }}}
vkCmdEndRendering(cb);
// }}}
// {{{ Transition Color Attachment For Presentation
VkImageMemoryBarrier2 present_barrier = {};
present_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
present_barrier.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
present_barrier.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
present_barrier.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
present_barrier.dstAccessMask = 0;
present_barrier.oldLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
present_barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
present_barrier.image = swapchain_images[image_index];
present_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
present_barrier.subresourceRange.levelCount = 1;
present_barrier.subresourceRange.layerCount = 1;
VkDependencyInfo present_dependency_info = {};
present_dependency_info.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
present_dependency_info.imageMemoryBarrierCount = 1;
present_dependency_info.pImageMemoryBarriers = &present_barrier;
vkCmdPipelineBarrier2(cb, &present_dependency_info);
// }}}
check(vkEndCommandBuffer(cb));
// }}}
// {{{ Submit Command Buffer
VkPipelineStageFlags wait_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
// The wait semaphore in pWaitSemaphores ensures that execution of the command buffer does not
// begin until the swapchain image we want to render to has been acquired. This means
// presentation has finished and the image has been released by the presentation engine. This is
// required because swapchain images are owned by the presentation engine rather than by our
// application. The pipeline stage specified in pWaitDstStageMask makes that wait happen at the
// color attachment output stage, so in theory the GPU may already begin work on earlier
// pipeline stages, such as vertex fetching. The signal semaphore in pSignalSemaphores, on the
// other hand, is signaled by the GPU once command buffer execution has completed and ensures
// that presentation does not begin until the command buffer has finished execution. Together,
// these guarantees prevent read/write hazards that could cause the GPU to read from or write
// to resources that are still in use.
VkSubmitInfo submit_info = {};
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit_info.waitSemaphoreCount = 1;
submit_info.pWaitSemaphores = &image_acquired_semaphores[frame_index];
submit_info.pWaitDstStageMask = &wait_stages;
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = &cb;
submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &render_completed_semaphores[image_index];
check(vkQueueSubmit(queue, 1, &submit_info, fences[frame_index]));
// }}}
frame_index = (frame_index + 1) % max_frames_in_flight;
// {{{ Present Image
VkPresentInfoKHR present_info = {};
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = &render_completed_semaphores[image_index];
present_info.swapchainCount = 1;
present_info.pSwapchains = &swapchain;
present_info.pImageIndices = &image_index;
check_swapchain(vkQueuePresentKHR(queue, &present_info));
// }}}
// {{{ Poll Events
f32 elapsed_time = (SDL_GetTicks() - last_time) / 1000.0f;
last_time = SDL_GetTicks();
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_EVENT_QUIT:
@@ -1114,14 +1345,120 @@ int main() {
case SDL_EVENT_KEY_DOWN:
if (event.key.key == SDLK_ESCAPE) {
running = false;
break;
}
// Select active model instance
if (event.key.key == SDLK_PLUS || event.key.key == SDLK_KP_PLUS || event.key.key == SDLK_EQUALS) {
shader_data.selected = (shader_data.selected < 2) ? shader_data.selected + 1 : 0;
}
if (event.key.key == SDLK_MINUS || event.key.key == SDLK_KP_MINUS) {
shader_data.selected = (shader_data.selected > 0) ? shader_data.selected - 1 : 2;
}
break;
// Rotate the selected object with mouse drag
case SDL_EVENT_MOUSE_MOTION:
if (event.button.button == SDL_BUTTON_LEFT) {
object_rotations[shader_data.selected].x -= (float)event.motion.yrel * elapsed_time;
object_rotations[shader_data.selected].y += (float)event.motion.xrel * elapsed_time;
}
break;
// Zooming with the mouse wheel
case SDL_EVENT_MOUSE_WHEEL:
camera_position.z += (float)event.wheel.y * elapsed_time * 10.0f;
break;
// Window resize
case SDL_EVENT_WINDOW_RESIZED:
update_swapchain = true;
break;
}
}
// }}}
// {{{ Recreate Swapchain If Needed
if (update_swapchain) {
// TODO (Abdelrahman): This doesn't work well. Debug it.
update_swapchain = false;
check(vkDeviceWaitIdle(device));
check(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, &surface_caps));
// Create new swapchain
swapchain_create_info.oldSwapchain = swapchain;
swapchain_create_info.imageExtent = { (u32)window_size.x, (u32)window_size.y };
check(vkCreateSwapchainKHR(device, &swapchain_create_info, NULL, &swapchain));
// Clean old image views
for (u32 i = 0; i < swapchain_image_count; ++i) {
vkDestroyImageView(device, swapchain_views[i], NULL);
}
// Clean old render_completed semaphores
for (u32 i = 0; i < swapchain_image_count; ++i) {
vkDestroySemaphore(device, render_completed_semaphores[i], NULL);
}
// Get new swapchain images
check(vkGetSwapchainImagesKHR(device, swapchain, &swapchain_image_count, nullptr));
if (swapchain_image_count != wapp_array_count(swapchain_images)) {
swapchain_images = wapp_array_alloc_capacity(VkImage, &arena, swapchain_image_count, ARRAY_INIT_FILLED);
swapchain_views = wapp_array_alloc_capacity(VkImageView, &arena, swapchain_image_count, ARRAY_INIT_FILLED);
render_completed_semaphores = wapp_array_alloc_capacity(VkSemaphore, &arena, swapchain_image_count, ARRAY_INIT_FILLED);
}
check(swapchain_images != nullptr, EXIT_CODE_ALLOCATION_FAILURE);
check(vkGetSwapchainImagesKHR(device, swapchain, &swapchain_image_count, swapchain_images));
check(swapchain_views != nullptr, EXIT_CODE_ALLOCATION_FAILURE);
for (u32 i = 0; i < swapchain_image_count; ++i) {
VkImageViewCreateInfo view_create_info = {};
view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
view_create_info.image = swapchain_images[i];
view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_create_info.format = image_format;
view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
view_create_info.subresourceRange.levelCount = 1;
view_create_info.subresourceRange.layerCount = 1;
check(vkCreateImageView(device, &view_create_info, nullptr, &swapchain_views[i]));
}
check(render_completed_semaphores != nullptr, EXIT_CODE_SYNC_OBJ_CREATE_FAILED);
for (u32 i = 0; i < swapchain_image_count; ++i) {
check(vkCreateSemaphore(device, &semaphore_create_info, NULL, &render_completed_semaphores[i]));
}
vkDestroySwapchainKHR(device, swapchain_create_info.oldSwapchain, NULL);
vmaDestroyImage(allocator, depth_image, depth_allocation);
vkDestroyImageView(device, depth_view, NULL);
depth_image_create_info.extent = { (u32)window_size.x, (u32)window_size.y, 1 };
VmaAllocationCreateInfo alloc_create_info = {};
alloc_create_info.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO;
check(vmaCreateImage(allocator, &depth_image_create_info, &alloc_create_info, &depth_image,
&depth_allocation, nullptr));
VkImageViewCreateInfo view_create_info = {};
view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
view_create_info.image = depth_image;
view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_create_info.format = depth_format;
view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
view_create_info.subresourceRange.levelCount = 1;
view_create_info.subresourceRange.layerCount = 1;
check(vkCreateImageView(device, &view_create_info, NULL, &depth_view));
}
// }}}
}
// }}}
// {{{ Cleanup
check(vkDeviceWaitIdle(device));
vkDestroyPipeline(device, graphics_pipeline, NULL);
vkDestroyPipelineLayout(device, graphics_pipeline_layout, NULL);
vkDestroyShaderModule(device, shader_module, NULL);
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
LD_LIBRARY_PATH=$VULKAN_SDK/lib:vendor/lib/:$LD_LIBRARY_PATH ./main