Last active
April 28, 2023 04:37
-
-
Save nihalkenkre/f89539b6e582cce009531e3a73e247bd to your computer and use it in GitHub Desktop.
Looking to copy an image into a swapchain image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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