Skip to content

Instantly share code, notes, and snippets.

@nihalkenkre
Last active April 28, 2023 04:37
Show Gist options
  • Save nihalkenkre/f89539b6e582cce009531e3a73e247bd to your computer and use it in GitHub Desktop.
Save nihalkenkre/f89539b6e582cce009531e3a73e247bd to your computer and use it in GitHub Desktop.
Looking to copy an image into a swapchain image
#include <Windows.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
// #include "cpu.h"
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_win32.h>
#define ID_GAME_TICK 1237
LRESULT CALLBACK WindowProc(HWND h_wnd, UINT msg, WPARAM w_param, LPARAM l_param)
{
// OutputDebugString(L"WindowProc\n");
switch (msg)
{
case WM_QUIT:
OutputDebugString(L"WM_QUIT\n");
PostQuitMessage(0);
break;
case WM_DESTROY:
PostQuitMessage(0);
OutputDebugString(L"WM_DESTROY\n");
break;
case WM_CLOSE:
PostQuitMessage(0);
OutputDebugString(L"WM_CLOSE\n");
break;
case WM_KEYDOWN:
OutputDebugString(L"key down\n");
break;
case WM_KEYUP:
OutputDebugString(L"key up\n");
break;
default:
break;
}
return DefWindowProc(h_wnd, msg, w_param, l_param);
}
VkInstance instance = VK_NULL_HANDLE;
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkDevice device = VK_NULL_HANDLE;
VkImage image = VK_NULL_HANDLE;
VkDeviceMemory memory = VK_NULL_HANDLE;
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
VkImage *sc_imgs = NULL;
VkImageView *sc_ivs = NULL;
VkQueue q = VK_NULL_HANDLE;
VkCommandPool cmd_pool = VK_NULL_HANDLE;
VkCommandBuffer cmd_buf = VK_NULL_HANDLE;
VkSemaphore img_acquire_sem = VK_NULL_HANDLE;
VkSemaphore signal_present_sem = VK_NULL_HANDLE;
VkMemoryRequirements mem_req;
VkSurfaceCapabilitiesKHR caps;
VkImageSubresourceRange isr = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseArrayLayer = 0,
.baseMipLevel = 0,
.layerCount = 1,
.levelCount = 1,
};
VkCommandBufferBeginInfo cbbi = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.pNext = NULL,
.flags = 0,
.pInheritanceInfo = NULL,
};
VkImageMemoryBarrier img_to_gen = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = NULL,
.srcAccessMask = VK_ACCESS_NONE,
.dstAccessMask = VK_ACCESS_NONE,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
};
unsigned char *mapped_data = NULL;
void init_vulkan(HINSTANCE h_instance, HWND h_wnd)
{
VkApplicationInfo app_info = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pNext = NULL,
.pApplicationName = "Chip8",
.applicationVersion = VK_MAKE_VERSION(1, 0, 0),
.pEngineName = "Chip8",
.engineVersion = VK_MAKE_VERSION(1, 0, 0),
.apiVersion = VK_API_VERSION_1_3,
};
char *enabled_extensions[] = {
VK_KHR_SURFACE_EXTENSION_NAME,
VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
};
VkInstanceCreateInfo instance_ci = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = NULL,
.pApplicationInfo = &app_info,
.ppEnabledExtensionNames = enabled_extensions,
.enabledExtensionCount = 2,
.enabledLayerCount = 0,
.ppEnabledLayerNames = NULL,
};
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(&instance_ci, NULL, &instance);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Instance creation failed with result %d\n", result);
OutputDebugString(buff);
return;
}
uint32_t phy_dev_count = 2;
VkPhysicalDevice phy_dev;
result = vkEnumeratePhysicalDevices(instance, &phy_dev_count, &phy_dev);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Enumerating physical devices failed with result: %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
VkWin32SurfaceCreateInfoKHR surface_ci = {
.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
.pNext = NULL,
.flags = 0,
.hinstance = h_instance,
.hwnd = h_wnd,
};
VkSurfaceKHR surface = VK_NULL_HANDLE;
result = vkCreateWin32SurfaceKHR(instance, &surface_ci, NULL, &surface);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Surface creationg failed with result: %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
VkPhysicalDeviceProperties dev_props;
vkGetPhysicalDeviceProperties(phy_dev, &dev_props);
VkPhysicalDeviceMemoryProperties mem_props;
vkGetPhysicalDeviceMemoryProperties(phy_dev, &mem_props);
VkPhysicalDeviceFeatures pdf;
vkGetPhysicalDeviceFeatures(phy_dev, &pdf);
uint32_t pm_count = 1;
VkPresentModeKHR pm;
vkGetPhysicalDeviceSurfacePresentModesKHR(phy_dev, surface, &pm_count, &pm);
uint32_t fmt_count = 1;
VkSurfaceFormatKHR fmt;
vkGetPhysicalDeviceSurfaceFormatsKHR(phy_dev, surface, &fmt_count, &fmt);
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(phy_dev, surface, &caps);
float priorities = 1.f;
VkDeviceQueueCreateInfo dev_q_ci = {
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.pNext = NULL,
.queueFamilyIndex = 0,
.queueCount = 1,
.pQueuePriorities = &priorities,
};
char *enabled_device_extensions[] = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
};
VkDeviceCreateInfo dev_ci = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &dev_q_ci,
.enabledExtensionCount = 1,
.ppEnabledExtensionNames = enabled_device_extensions,
.enabledLayerCount = 0,
};
result = vkCreateDevice(phy_dev, &dev_ci, NULL, &device);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Device creation failed with result: %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
VkSwapchainCreateInfoKHR swapchain_ci = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.pNext = NULL,
.flags = 0,
.surface = surface,
.minImageCount = caps.minImageCount,
.imageFormat = fmt.format,
.imageColorSpace = fmt.colorSpace,
.imageExtent = caps.currentExtent,
.imageArrayLayers = 1,
.imageUsage = caps.supportedUsageFlags,
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.preTransform = caps.currentTransform,
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
.presentMode = pm,
.clipped = VK_TRUE,
.oldSwapchain = VK_NULL_HANDLE,
};
result = vkCreateSwapchainKHR(device, &swapchain_ci, NULL, &swapchain);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Creating swapchain failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
sc_imgs = (VkImage *)malloc(sizeof(VkImage) * caps.minImageCount);
result = vkGetSwapchainImagesKHR(device, swapchain, &caps.minImageCount, sc_imgs);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Getting swapchain images failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
VkImageViewCreateInfo icci = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = fmt.format,
.components.r = VK_COMPONENT_SWIZZLE_R,
.components.g = VK_COMPONENT_SWIZZLE_G,
.components.b = VK_COMPONENT_SWIZZLE_B,
.components.a = VK_COMPONENT_SWIZZLE_A,
.subresourceRange = isr,
};
sc_ivs = (VkImageView *)malloc(sizeof(VkImageView) * caps.minImageCount);
for (uint32_t sc_img_idx = 0; sc_img_idx < caps.minImageCount; ++sc_img_idx)
{
icci.image = sc_imgs[sc_img_idx];
result = vkCreateImageView(device, &icci, NULL, sc_ivs + sc_img_idx);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Creating image view failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
}
vkGetDeviceQueue(device, 0, 0, &q);
VkCommandPoolCreateInfo cpci = {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.pNext = NULL,
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
.queueFamilyIndex = 0,
};
result = vkCreateCommandPool(device, &cpci, NULL, &cmd_pool);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Creating command pool failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
VkCommandBufferAllocateInfo cbai = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.pNext = NULL,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandPool = cmd_pool,
.commandBufferCount = 1,
};
result = vkAllocateCommandBuffers(device, &cbai, &cmd_buf);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Allocating command buffers failed with %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
VkSemaphoreCreateInfo sem_ci = {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
.pNext = NULL,
.flags = 0};
result = vkCreateSemaphore(device, &sem_ci, NULL, &img_acquire_sem);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Creating semaphore failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
result = vkCreateSemaphore(device, &sem_ci, NULL, &signal_present_sem);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Creating semaphore failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
VkImageCreateInfo image_ci = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.format = fmt.format,
.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
.extent = {caps.currentExtent.width, caps.currentExtent.height, 1},
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.imageType = VK_IMAGE_TYPE_2D,
.mipLevels = 1,
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
};
result = vkCreateImage(device, &image_ci, NULL, &image);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Creating image failed with result: %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
vkGetImageMemoryRequirements(device, image, &mem_req);
uint32_t mem_type_idx = 0;
uint32_t req_types = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
for (uint32_t i = 0; i < mem_props.memoryTypeCount; ++i)
{
if (mem_req.memoryTypeBits * (1 << i) && req_types & mem_props.memoryTypes[i].propertyFlags)
{
mem_type_idx = i;
break;
}
}
VkMemoryAllocateInfo mai = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = NULL,
.allocationSize = mem_req.size,
.memoryTypeIndex = mem_type_idx,
};
result = vkAllocateMemory(device, &mai, NULL, &memory);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Memory allocation failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
result = vkBindImageMemory(device, image, memory, 0);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Binding Image Memory failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
img_to_gen.image = image;
img_to_gen.subresourceRange = isr;
result = vkBeginCommandBuffer(cmd_buf, &cbbi);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Beginning commmand buffer failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, NULL, 0, NULL, 1, &img_to_gen);
result = vkEndCommandBuffer(cmd_buf);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"End commmand buffer failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
VkFenceCreateInfo fence_ci = {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.pNext = NULL,
.flags = 0,
};
VkFence fence;
result = vkCreateFence(device, &fence_ci, NULL, &fence);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Creating fence failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
VkSubmitInfo si = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = NULL,
.commandBufferCount = 1,
.pCommandBuffers = &cmd_buf,
};
result = vkQueueSubmit(q, 1, &si, fence);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"End commmand buffer failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
result = vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Wait for fence failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
result = vkMapMemory(device, memory, 0, mem_req.size, 0, &mapped_data);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Mapping memory failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
return;
}
memset(mapped_data, 128, mem_req.size);
vkDestroyFence(device, fence, NULL);
}
void shutdown_vulkan()
{
OutputDebugString(L"shutdown_vulkan\n");
if (img_acquire_sem != VK_NULL_HANDLE)
{
vkDestroySemaphore(device, img_acquire_sem, NULL);
}
if (signal_present_sem != VK_NULL_HANDLE)
{
vkDestroySemaphore(device, signal_present_sem, NULL);
}
if (cmd_buf != VK_NULL_HANDLE)
{
vkFreeCommandBuffers(device, cmd_pool, 1, &cmd_buf);
}
if (cmd_pool != VK_NULL_HANDLE)
{
vkDestroyCommandPool(device, cmd_pool, NULL);
}
if (sc_ivs != NULL)
{
for (uint32_t sc_img_idx = 0; sc_img_idx < caps.minImageCount; ++sc_img_idx)
{
if (sc_ivs[sc_img_idx] != VK_NULL_HANDLE)
{
vkDestroyImageView(device, sc_ivs[sc_img_idx], NULL);
}
}
free(sc_ivs);
}
if (sc_imgs != NULL)
{
free(sc_imgs);
}
if (swapchain != VK_NULL_HANDLE)
{
vkDestroySwapchainKHR(device, swapchain, NULL);
}
if (mapped_data != NULL)
{
vkUnmapMemory(device, memory);
}
if (memory != VK_NULL_HANDLE)
{
vkFreeMemory(device, memory, NULL);
}
if (image != VK_NULL_HANDLE)
{
vkDestroyImage(device, image, NULL);
}
if (device != VK_NULL_HANDLE)
{
vkDestroyDevice(device, NULL);
}
if (surface != VK_NULL_HANDLE)
{
vkDestroySurfaceKHR(instance, surface, NULL);
}
if (instance != VK_NULL_HANDLE)
{
vkDestroyInstance(instance, NULL);
}
}
int WINAPI wWinMain(_In_ HINSTANCE h_instance, _In_opt_ HINSTANCE previous_instance, _In_ PWSTR cmd_line, _In_ int cmd_show)
{
OutputDebugString(L"Hello Chip8\n");
WNDCLASS wc = {0};
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WindowProc;
wc.hInstance = h_instance;
wc.lpszClassName = L"Chip8";
wc.hCursor = LoadCursor(h_instance, IDC_ARROW);
if (!RegisterClass(&wc))
{
return EXIT_FAILURE;
}
HWND h_wnd = CreateWindow(
L"Chip8",
L"Chip8",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT,
CW_USEDEFAULT,
1040,
551,
NULL,
NULL,
h_instance,
NULL);
if (!h_wnd)
{
return EXIT_FAILURE;
}
ShowWindow(h_wnd, cmd_show);
UpdateWindow(h_wnd);
char *path = "./build32/vscode/debug/IBM_Logo.ch8";
// cpu *c = cpu_create(h_instance, h_wnd);
init_vulkan(h_instance, h_wnd);
SetTimer(h_wnd, ID_GAME_TICK, 1000, NULL);
MSG msg;
ZeroMemory(&msg, sizeof(msg));
RECT client_rect;
GetClientRect(h_wnd, &client_rect);
BOOL gm;
while ((gm = GetMessage(&msg, h_wnd, 0, 0)) != 0)
{
if (gm == -1)
{
break;
}
else
{
if (msg.message == WM_PAINT)
{
OutputDebugString(L"Paint\n");
uint32_t img_index = 0;
VkResult result = vkAcquireNextImageKHR(device, swapchain, UINT64_MAX, img_acquire_sem, VK_NULL_HANDLE, &img_index);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Acquiring image failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
break;
}
VkImageMemoryBarrier sc_img_to_dst = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = NULL,
.srcAccessMask = VK_ACCESS_NONE,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.image = sc_imgs[img_index],
.subresourceRange = isr,
};
VkImageMemoryBarrier img_to_src = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = NULL,
.srcAccessMask = VK_ACCESS_NONE,
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.image = image,
.subresourceRange = isr,
};
VkImageMemoryBarrier sc_img_to_present = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = NULL,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_NONE,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
.image = sc_imgs[img_index],
.subresourceRange = isr,
};
VkImageSubresourceLayers isl = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseArrayLayer = 0,
.layerCount = 1,
.mipLevel = 0,
};
VkImageCopy img_cpy = {
.extent = {caps.currentExtent.width, caps.currentExtent.height, 1},
.srcSubresource = isl,
.dstSubresource = isl,
};
result = vkBeginCommandBuffer(cmd_buf, &cbbi);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Begin command buffer failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
break;
}
vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, &img_to_src);
vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, &sc_img_to_dst);
vkCmdCopyImage(cmd_buf, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, sc_imgs[img_index], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &img_cpy);
vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0, NULL, 1, &sc_img_to_present);
vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0, NULL, 1, &img_to_gen);
result = vkEndCommandBuffer(cmd_buf);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"End command buffer failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
break;
}
VkPipelineStageFlags wait_stage[] = {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT};
VkSubmitInfo submit_info = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = NULL,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &img_acquire_sem,
.commandBufferCount = 1,
.pCommandBuffers = &cmd_buf,
.signalSemaphoreCount = 1,
.pSignalSemaphores = &signal_present_sem,
.pWaitDstStageMask = wait_stage,
};
result = vkQueueSubmit(q, 1, &submit_info, VK_NULL_HANDLE);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Queue submit failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
break;
}
VkPresentInfoKHR pi = {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.pNext = NULL,
.swapchainCount = 1,
.pSwapchains = &swapchain,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &signal_present_sem,
.pImageIndices = &img_index,
};
result = vkQueuePresentKHR(q, &pi);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Presenting image failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
break;
}
result = vkQueueWaitIdle(q);
if (result != VK_SUCCESS)
{
wchar_t buff[1024];
swprintf(buff, 1024, L"Waiting idle failed with result %d\n", (int32_t)result);
OutputDebugString(buff);
break;
}
memset(mapped_data, 255, mem_req.size);
}
else if (msg.message == WM_TIMER)
{
OutputDebugString(L"Timer\n");
// cpu_execute(c);
InvalidateRect(h_wnd, &client_rect, TRUE);
}
else
{
DispatchMessage(&msg);
}
}
DefWindowProc(msg.hwnd, msg.message, msg.lParam, msg.wParam);
}
// cpu_destroy(c);
shutdown_vulkan();
KillTimer(h_wnd, ID_GAME_TICK);
DestroyWindow(h_wnd);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment