Skip to content

Instantly share code, notes, and snippets.

@TheServer201
Created May 6, 2017 18:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheServer201/26c280d0779423dc714da4a299636ff7 to your computer and use it in GitHub Desktop.
Save TheServer201/26c280d0779423dc714da4a299636ff7 to your computer and use it in GitHub Desktop.
Simple vkCmdClearColorImage example
// gcc -Os -s -I. -L. -municode -nostartfiles -e _entry -Wl,--gc-sections vulkan.c -o vulkan -lvulkan-1
#define VK_USE_PLATFORM_WIN32_KHR
#include <vulkan/vulkan.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct
{
VkDevice Device;
VkSwapchainKHR Swapchain;
VkSemaphore WaitSemaphore, SignalSemaphore;
uint32_t commandBufferCount;
VkCommandBuffer *CommandBuffers;
VkQueue Queue;
} VkWindow;
void PrintVkResult(uint8_t *Name, VkResult Result)
{
uint8_t s[128];
sprintf(s, "%s -> ", Name);
#define CASE_STRING(r, s) case r: strcat(s, #r); break;
switch (Result)
{
CASE_STRING(VK_SUCCESS, s)
CASE_STRING(VK_NOT_READY, s)
CASE_STRING(VK_TIMEOUT, s)
CASE_STRING(VK_EVENT_SET, s)
CASE_STRING(VK_EVENT_RESET, s)
CASE_STRING(VK_INCOMPLETE, s)
CASE_STRING(VK_ERROR_OUT_OF_HOST_MEMORY, s)
CASE_STRING(VK_ERROR_OUT_OF_DEVICE_MEMORY, s)
CASE_STRING(VK_ERROR_INITIALIZATION_FAILED, s)
CASE_STRING(VK_ERROR_DEVICE_LOST, s)
CASE_STRING(VK_ERROR_MEMORY_MAP_FAILED, s)
CASE_STRING(VK_ERROR_LAYER_NOT_PRESENT, s)
CASE_STRING(VK_ERROR_EXTENSION_NOT_PRESENT, s)
CASE_STRING(VK_ERROR_FEATURE_NOT_PRESENT, s)
CASE_STRING(VK_ERROR_INCOMPATIBLE_DRIVER, s)
CASE_STRING(VK_ERROR_TOO_MANY_OBJECTS, s)
CASE_STRING(VK_ERROR_FORMAT_NOT_SUPPORTED, s)
CASE_STRING(VK_ERROR_FRAGMENTED_POOL, s)
CASE_STRING(VK_ERROR_SURFACE_LOST_KHR, s)
CASE_STRING(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, s)
CASE_STRING(VK_SUBOPTIMAL_KHR, s)
CASE_STRING(VK_ERROR_OUT_OF_DATE_KHR, s)
CASE_STRING(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR, s)
CASE_STRING(VK_ERROR_VALIDATION_FAILED_EXT, s)
CASE_STRING(VK_ERROR_INVALID_SHADER_NV, s)
CASE_STRING(VK_ERROR_OUT_OF_POOL_MEMORY_KHR, s)
CASE_STRING(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX, s)
}
#undef CASE_STRING
puts(s);
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg == WM_KEYUP && wParam == VK_ESCAPE)
{
DestroyWindow(hWnd);
}
else
{
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
}
DWORD WINAPI ThreadProc(LPVOID Param)
{
VkResult Result;
VkWindow Window = *(VkWindow*)Param;
VkPipelineStageFlags WaitDstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
VkSubmitInfo SubmitInfo = { 0 };
SubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
SubmitInfo.waitSemaphoreCount = 1;
SubmitInfo.pWaitSemaphores = &Window.WaitSemaphore;
SubmitInfo.pWaitDstStageMask = &WaitDstStageMask;
SubmitInfo.commandBufferCount = Window.commandBufferCount;
SubmitInfo.pCommandBuffers = Window.CommandBuffers;
SubmitInfo.signalSemaphoreCount = 1;
SubmitInfo.pSignalSemaphores = &Window.SignalSemaphore;
VkPresentInfoKHR PresentInfo = { 0 };
PresentInfo.waitSemaphoreCount = 1;
PresentInfo.pWaitSemaphores = &Window.SignalSemaphore;
PresentInfo.swapchainCount = 1;
PresentInfo.pSwapchains = &Window.Swapchain;
while (1)
{
uint32_t ImageIndex;
Result = vkAcquireNextImageKHR(Window.Device, Window.Swapchain, UINT64_MAX, Window.WaitSemaphore, VK_NULL_HANDLE, &ImageIndex);
if (Result != VK_SUCCESS)
{
PrintVkResult("vkAcquireNextImageKHR", Result);
}
Result = vkQueueSubmit(Window.Queue, 1, &SubmitInfo, VK_NULL_HANDLE);
if (Result != VK_SUCCESS)
{
PrintVkResult("vkQueueSubmit", Result);
}
PresentInfo.pImageIndices = &ImageIndex;
vkQueuePresentKHR(Window.Queue, &PresentInfo);
if (Result != VK_SUCCESS)
{
PrintVkResult("vkQueuePresentKHR", Result);
}
}
return 0;
}
void entry()
{
uint32_t i;
WNDCLASSEX WndClassEx = { 0 };
WndClassEx.cbSize = sizeof(WndClassEx);
WndClassEx.lpfnWndProc = WindowProc;
WndClassEx.lpszClassName = TEXT("RotMG");
RegisterClassEx(&WndClassEx);
HMONITOR hMonitor = MonitorFromWindow(NULL, MONITOR_DEFAULTTONEAREST);
MONITORINFO MonitorInfo;
MonitorInfo.cbSize = sizeof(MonitorInfo);
GetMonitorInfo(hMonitor, &MonitorInfo);
RECT RectMonitor = MonitorInfo.rcMonitor;
VkExtent2D ScreenExtent;
ScreenExtent.width = RectMonitor.right - RectMonitor.left;
ScreenExtent.height = RectMonitor.bottom - RectMonitor.top;
HWND hWnd = CreateWindowEx(WS_EX_LEFT, WndClassEx.lpszClassName, NULL, WS_POPUP, RectMonitor.left, RectMonitor.top, ScreenExtent.width, ScreenExtent.height, 0, 0, NULL, NULL);
VkResult Result;
VkInstanceCreateInfo InstanceCreateInfo = { 0 };
InstanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
const char *InstanceEnabledExtensionNames[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME };
InstanceCreateInfo.enabledExtensionCount = 2;
InstanceCreateInfo.ppEnabledExtensionNames = InstanceEnabledExtensionNames;
VkInstance Instance;
Result = vkCreateInstance(&InstanceCreateInfo, NULL, &Instance);
PrintVkResult("vkCreateInstance", Result);
VkWin32SurfaceCreateInfoKHR SurfaceCreateInfo = { 0 };
SurfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
SurfaceCreateInfo.hwnd = hWnd;
VkSurfaceKHR Surface;
Result = vkCreateWin32SurfaceKHR(Instance, &SurfaceCreateInfo, NULL, &Surface);
PrintVkResult("vkCreateWin32SurfaceKHR", Result);
uint32_t PhysicalDeviceCount;
Result = vkEnumeratePhysicalDevices(Instance, &PhysicalDeviceCount, NULL);
VkPhysicalDevice PhysicalDevices[PhysicalDeviceCount];
Result |= vkEnumeratePhysicalDevices(Instance, &PhysicalDeviceCount, PhysicalDevices);
PrintVkResult("vkEnumeratePhysicalDevices", Result);
VkPhysicalDevice PhysicalDevice = PhysicalDevices[0];
/* VkPhysicalDeviceProperties Properties;
* vkGetPhysicalDeviceProperties(PhysicalDevice, &Properties);
*
* uint32_t apiVersion = Properties.apiVersion;
* printf("Using %s with Vulkan %d.%d.%d\n", Properties.deviceName, VK_VERSION_MAJOR(apiVersion), VK_VERSION_MINOR(apiVersion), VK_VERSION_PATCH(apiVersion));
*/
uint32_t QueueFamilyPropertyCount;
vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &QueueFamilyPropertyCount, NULL);
VkQueueFamilyProperties QueueFamilyProperties[QueueFamilyPropertyCount];
vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &QueueFamilyPropertyCount, QueueFamilyProperties);
uint32_t queueFamilyIndex;
for (i = 0; i < QueueFamilyPropertyCount; i++)
{
VkBool32 Supported;
Result = vkGetPhysicalDeviceSurfaceSupportKHR(PhysicalDevice, i, Surface, &Supported);
PrintVkResult("vkGetPhysicalDeviceSurfaceSupportKHR", Result);
if (Supported && (QueueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT))
{
queueFamilyIndex = i;
break;
}
}
VkDeviceQueueCreateInfo QueueCreateInfo = { 0 };
QueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
QueueCreateInfo.queueFamilyIndex = queueFamilyIndex;
const float QueuePriorities[] = { 1.0f };
QueueCreateInfo.queueCount = 1;
QueueCreateInfo.pQueuePriorities = QueuePriorities;
VkDeviceCreateInfo DeviceCreateInfo = { 0 };
DeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
DeviceCreateInfo.queueCreateInfoCount = 1;
DeviceCreateInfo.pQueueCreateInfos = &QueueCreateInfo;
const char *DeviceEnabledExtensionNames[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
DeviceCreateInfo.enabledExtensionCount = 1;
DeviceCreateInfo.ppEnabledExtensionNames = DeviceEnabledExtensionNames;
VkDevice Device;
Result = vkCreateDevice(PhysicalDevice, &DeviceCreateInfo, NULL, &Device);
PrintVkResult("vkCreateDevice", Result);
VkQueue Queue;
vkGetDeviceQueue(Device, queueFamilyIndex, 0, &Queue);
VkSurfaceCapabilitiesKHR SurfaceCapabilities;
Result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(PhysicalDevice, Surface, &SurfaceCapabilities);
PrintVkResult("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", Result);
uint32_t SurfaceFormatCount;
Result = vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &SurfaceFormatCount, NULL);
VkSurfaceFormatKHR SurfaceFormats[SurfaceFormatCount];
Result |= vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &SurfaceFormatCount, SurfaceFormats);
PrintVkResult("vkGetPhysicalDeviceSurfaceFormatsKHR", Result);
VkSwapchainCreateInfoKHR SwapchainCreateInfo = { 0 };
SwapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
SwapchainCreateInfo.surface = Surface;
uint32_t SwapchainImageCount = SurfaceCapabilities.minImageCount;
SwapchainCreateInfo.minImageCount = SwapchainImageCount;
VkSurfaceFormatKHR SurfaceFormat = SurfaceFormats[0];
SwapchainCreateInfo.imageFormat = SurfaceFormat.format;
SwapchainCreateInfo.imageColorSpace = SurfaceFormat.colorSpace;
SwapchainCreateInfo.imageExtent = ScreenExtent;
SwapchainCreateInfo.imageArrayLayers = 1;
SwapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
SwapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
SwapchainCreateInfo.preTransform = SurfaceCapabilities.currentTransform;
SwapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
SwapchainCreateInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
SwapchainCreateInfo.clipped = VK_TRUE;
VkSwapchainKHR Swapchain;
Result = vkCreateSwapchainKHR(Device, &SwapchainCreateInfo, NULL, &Swapchain);
PrintVkResult("vkCreateSwapchainKHR", Result);
VkImage SwapchainImages[SwapchainImageCount];
Result = vkGetSwapchainImagesKHR(Device, Swapchain, &SwapchainImageCount, SwapchainImages);
PrintVkResult("vkGetSwapchainImagesKHR", Result);
VkCommandPoolCreateInfo CommandPoolCreateInfo;
CommandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
CommandPoolCreateInfo.pNext = NULL;
CommandPoolCreateInfo.flags = 0;
CommandPoolCreateInfo.queueFamilyIndex = queueFamilyIndex;
VkCommandPool CommandPool;
Result = vkCreateCommandPool(Device, &CommandPoolCreateInfo, NULL, &CommandPool);
PrintVkResult("vkCreateCommandPool", Result);
VkCommandBufferAllocateInfo CommandBufferAllocateInfo;
CommandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
CommandBufferAllocateInfo.pNext = NULL;
CommandBufferAllocateInfo.commandPool = CommandPool;
CommandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
CommandBufferAllocateInfo.commandBufferCount = SwapchainImageCount;
VkCommandBuffer CommandBuffers[SwapchainImageCount];
Result = vkAllocateCommandBuffers(Device, &CommandBufferAllocateInfo, CommandBuffers);
PrintVkResult("vkAllocateCommandBuffers", Result);
VkCommandBufferBeginInfo CommandBufferBeginInfo;
CommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
CommandBufferBeginInfo.pNext = NULL;
CommandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
CommandBufferBeginInfo.pInheritanceInfo = NULL;
VkImageSubresourceRange ImageSubresourceRange;
ImageSubresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
ImageSubresourceRange.baseMipLevel = 0;
ImageSubresourceRange.levelCount = 1;
ImageSubresourceRange.baseArrayLayer = 0;
ImageSubresourceRange.layerCount = 1;
VkClearColorValue ClearColorValue = { 1.0, 0.0, 0.0, 0.0 };
for (i = 0; i < SwapchainImageCount; i++)
{
VkCommandBuffer CommandBuffer = CommandBuffers[i];
Result = vkBeginCommandBuffer(CommandBuffer, &CommandBufferBeginInfo);
PrintVkResult("vkBeginCommandBuffer", Result);
vkCmdClearColorImage(CommandBuffer, SwapchainImages[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &ClearColorValue, 1, &ImageSubresourceRange);
Result = vkEndCommandBuffer(CommandBuffer);
PrintVkResult("vkEndCommandBuffer", Result);
}
VkSemaphoreCreateInfo SemaphoreCreateInfo;
SemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
SemaphoreCreateInfo.pNext = NULL;
SemaphoreCreateInfo.flags = 0;
VkSemaphore WaitSemaphore, SignalSemaphore;
Result = vkCreateSemaphore(Device, &SemaphoreCreateInfo, NULL, &WaitSemaphore);
Result |= vkCreateSemaphore(Device, &SemaphoreCreateInfo, NULL, &SignalSemaphore);
PrintVkResult("vkCreateSemaphore", Result);
VkWindow Window;
Window.Device = Device;
Window.Swapchain = Swapchain;
Window.WaitSemaphore = WaitSemaphore;
Window.SignalSemaphore = SignalSemaphore;
Window.commandBufferCount = SwapchainImageCount;
Window.CommandBuffers = CommandBuffers;
Window.Queue = Queue;
HANDLE hThread = CreateThread(NULL, 0, ThreadProc, &Window, 0, NULL);
ShowWindow(hWnd, SW_SHOW);
MSG Msg;
while (GetMessage(&Msg, hWnd, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
TerminateThread(hThread, 0);
vkDestroySemaphore(Device, WaitSemaphore, NULL);
vkDestroySemaphore(Device, SignalSemaphore, NULL);
vkFreeCommandBuffers(Device, CommandPool, SwapchainImageCount, CommandBuffers);
vkDestroyCommandPool(Device, CommandPool, NULL);
vkDestroySwapchainKHR(Device, Swapchain, NULL);
vkDestroyDevice(Device, NULL);
vkDestroySurfaceKHR(Instance, Surface, NULL);
vkDestroyInstance(Instance, NULL);
DestroyWindow(hWnd);
UnregisterClass(WndClassEx.lpszClassName, NULL);
exit(EXIT_SUCCESS);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment