Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cassert>
- #include <iostream>
- #include <vector>
- #include <array>
- #include <cstring>
- #define GLFW_INCLUDE_VULKAN
- #include <GLFW/glfw3.h>
- #define VKCHECK(x) if ((x) != VK_SUCCESS) fprintf(stderr, "Failure while executing Vulkan command at line %d\n", __LINE__)
- static bool getMemoryTypeFromProperties(VkPhysicalDeviceMemoryProperties memProps, uint32_t typeBits, VkFlags requirementsMask, uint32_t* typeIndex)
- {
- for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i) {
- if ((typeBits & 1) == 1) {
- if ((memProps.memoryTypes[i].propertyFlags & requirementsMask) == requirementsMask) {
- *typeIndex = i;
- return true;
- }
- }
- typeBits >>= 1;
- }
- return false;
- }
- /*static std::array<const char*, 8> instanceValidationLayerNames = {{
- "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation",
- "VK_LAYER_LUNARG_device_limits", "VK_LAYER_LUNARG_object_tracker",
- "VK_LAYER_LUNARG_image", "VK_LAYER_LUNARG_core_validation",
- "VK_LAYER_LUNARG_swapchain", "VK_LAYER_GOOGLE_unique_objects"
- }
- };*/
- static std::array<const char*, 1> instanceValidationLayerNames = {{ "VK_LAYER_LUNARG_standard_validation" }};
- static void setImageLayout(VkCommandBuffer& cmdBuf, VkDevice device, VkCommandPool cmdPool, VkImage image, VkImageAspectFlags aspectMask, VkImageLayout oldImageLayout, VkImageLayout newImageLayout, VkAccessFlagBits srcAccessMask)
- {
- // allocate a command buffer if we don't already have one
- if (cmdBuf == VK_NULL_HANDLE) {
- VkCommandBufferAllocateInfo cmdBufAllocInfo = {};
- cmdBufAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
- cmdBufAllocInfo.pNext = nullptr;
- cmdBufAllocInfo.commandPool = cmdPool;
- cmdBufAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
- cmdBufAllocInfo.commandBufferCount = 1;
- VKCHECK(vkAllocateCommandBuffers(device, &cmdBufAllocInfo, &cmdBuf));
- VkCommandBufferInheritanceInfo cmdBufInhInfo = {};
- cmdBufInhInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
- cmdBufInhInfo.pNext = nullptr;
- cmdBufInhInfo.renderPass = VK_NULL_HANDLE;
- cmdBufInhInfo.subpass = 0;
- cmdBufInhInfo.framebuffer = VK_NULL_HANDLE;
- cmdBufInhInfo.occlusionQueryEnable = VK_FALSE;
- cmdBufInhInfo.queryFlags = 0;
- cmdBufInhInfo.pipelineStatistics = 0;
- VkCommandBufferBeginInfo cmdBufBeginInfo = {};
- cmdBufBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- cmdBufBeginInfo.pNext = nullptr;
- cmdBufBeginInfo.flags = 0;
- cmdBufBeginInfo.pInheritanceInfo = &cmdBufInhInfo;
- VKCHECK(vkBeginCommandBuffer(cmdBuf, &cmdBufBeginInfo));
- }
- VkImageMemoryBarrier imageMemBarrier = {};
- imageMemBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
- imageMemBarrier.pNext = nullptr;
- imageMemBarrier.srcAccessMask = srcAccessMask;
- imageMemBarrier.dstAccessMask = 0;
- imageMemBarrier.oldLayout = oldImageLayout;
- imageMemBarrier.newLayout = newImageLayout;
- imageMemBarrier.image = image;
- imageMemBarrier.subresourceRange = { aspectMask, 0, 1, 0, 1 };
- if (newImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
- imageMemBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- } else if (newImageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
- imageMemBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- } else if (newImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
- imageMemBarrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
- } else if (newImageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
- imageMemBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
- }
- VkPipelineStageFlags srcStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- VkPipelineStageFlags destStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- vkCmdPipelineBarrier(cmdBuf, srcStages, destStages, 0, 0, nullptr, 0, nullptr, 1, &imageMemBarrier);
- }
- static bool checkInstanceLayers(uint32_t checkCount, const char* const* checkNames, uint32_t layerCount, VkLayerProperties* layers)
- {
- for (uint32_t i = 0; i < checkCount; ++i) {
- bool found = false;
- for (uint32_t j = 0; j < layerCount; ++j) {
- if (std::strcmp(checkNames[i], layers[j].layerName) == 0) {
- found = true;
- break;
- }
- }
- if (!found) {
- fprintf(stderr, "Cannot find instance layer %s\n", checkNames[i]);
- return false;
- }
- }
- return true;
- }
- static const bool validate = true;
- int main()
- {
- glfwInit();
- assert(glfwVulkanSupported());
- // enable validation if wanted
- bool validationFound = false;
- if (validate) {
- uint32_t propCount;
- VKCHECK(vkEnumerateInstanceLayerProperties(&propCount, nullptr));
- std::vector<VkLayerProperties> instanceLayerProps(propCount);
- VKCHECK(vkEnumerateInstanceLayerProperties(&propCount, instanceLayerProps.data()));
- validationFound = checkInstanceLayers((uint32_t)instanceValidationLayerNames.size(), instanceValidationLayerNames.data(), propCount, instanceLayerProps.data());
- }
- if (!validationFound) {
- fprintf(stderr, "Validation was requested, but not all required validation layers were found.\n");
- return 1;
- }
- PFN_vkCreateInstance pfnCreateInstance = (PFN_vkCreateInstance)glfwGetInstanceProcAddress(VK_NULL_HANDLE, "vkCreateInstance");
- PFN_vkDestroyInstance pfnDestroyInstance = (PFN_vkDestroyInstance)glfwGetInstanceProcAddress(VK_NULL_HANDLE, "vkDestroyInstance");
- unsigned int instanceExtCount;
- const char** reqInstanceExts = glfwGetRequiredInstanceExtensions(&instanceExtCount);
- if (reqInstanceExts) {
- printf("Required instance extensions:\n");
- for (unsigned int i = 0; i < instanceExtCount; ++i) {
- puts(reqInstanceExts[i]);
- }
- }
- std::array<const char*, 8> instanceExts;
- std::memcpy(instanceExts.data(), reqInstanceExts, sizeof(const char*) * instanceExtCount);
- if (validate) {
- instanceExts[instanceExtCount++] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME; // we just assume it's there
- }
- VkApplicationInfo appInfo = {};
- appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
- appInfo.pNext = nullptr;
- appInfo.pApplicationName = "glfwvktest";
- appInfo.applicationVersion = 1;
- appInfo.pEngineName = "glfwvktest";
- appInfo.engineVersion = 1;
- appInfo.apiVersion = VK_API_VERSION_1_0;
- VkInstanceCreateInfo instanceCreateInfo = {};
- instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
- instanceCreateInfo.pNext = nullptr;
- instanceCreateInfo.flags = 0;
- instanceCreateInfo.pApplicationInfo = &appInfo;
- instanceCreateInfo.enabledLayerCount = (uint32_t)instanceValidationLayerNames.size();
- instanceCreateInfo.ppEnabledLayerNames = instanceValidationLayerNames.data();
- instanceCreateInfo.enabledExtensionCount = instanceExtCount;
- instanceCreateInfo.ppEnabledExtensionNames = instanceExts.data();
- VkDebugReportCallbackCreateInfoEXT dbgCreateInfo = {};
- dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
- dbgCreateInfo.pNext = nullptr;
- dbgCreateInfo.pfnCallback = static_cast<PFN_vkDebugReportCallbackEXT>([](VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData) -> VkBool32 {
- if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
- {
- fprintf(stderr, "ERROR: [%s] Code %d : %s\n", pLayerPrefix, msgCode, pMsg);
- } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT)
- {
- fprintf(stderr, "WARNING: [%s] Code %d : %s\n", pLayerPrefix, msgCode, pMsg);
- } else {
- fprintf(stderr, "INFO: [%s] Code %d : %s\n", pLayerPrefix, msgCode, pMsg);
- }
- return VK_FALSE;
- });
- dbgCreateInfo.pUserData = nullptr;
- dbgCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
- instanceCreateInfo.pNext = &dbgCreateInfo;
- VkInstance instance;
- VKCHECK(pfnCreateInstance(&instanceCreateInfo, nullptr, &instance));
- // set the debug report callback
- PFN_vkCreateDebugReportCallbackEXT pfnCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)glfwGetInstanceProcAddress(instance, "vkCreateDebugReportCallbackEXT");
- PFN_vkDestroyDebugReportCallbackEXT pfnDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)glfwGetInstanceProcAddress(instance, "vkDestroyDebugReportCallbackEXT");
- VkDebugReportCallbackEXT debugReportCallback;
- if (validate) {
- VKCHECK(pfnCreateDebugReportCallbackEXT(instance, &dbgCreateInfo, nullptr, &debugReportCallback));
- }
- PFN_vkCreateDevice pfnCreateDevice = (PFN_vkCreateDevice)glfwGetInstanceProcAddress(instance, "vkCreateDevice");
- PFN_vkDestroyDevice pfnDestroyDevice = (PFN_vkDestroyDevice)glfwGetInstanceProcAddress(instance, "vkDestroyDevice");
- PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr");
- PFN_vkEnumeratePhysicalDevices pfnEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices)glfwGetInstanceProcAddress(instance, "vkEnumeratePhysicalDevices");
- PFN_vkGetPhysicalDeviceQueueFamilyProperties pfnGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties)glfwGetInstanceProcAddress(instance, "vkGetPhysicalDeviceQueueFamilyProperties");
- PFN_vkDestroySurfaceKHR pfnDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)glfwGetInstanceProcAddress(instance, "vkDestroySurfaceKHR");
- uint32_t gpuCount;
- VKCHECK(pfnEnumeratePhysicalDevices(instance, &gpuCount, nullptr));
- VkPhysicalDevice gpu;
- {
- std::vector<VkPhysicalDevice> gpus(gpuCount);
- VKCHECK(pfnEnumeratePhysicalDevices(instance, &gpuCount, gpus.data()));
- gpu = gpus[0];
- }
- uint32_t deviceExtensionCount = 0;
- VKCHECK(vkEnumerateDeviceExtensionProperties(gpu, nullptr, &deviceExtensionCount, nullptr));
- std::array<const char*, 4> enabledDeviceExtensions;
- uint32_t enabledDeviceExtensionCount = 0;
- bool swapchainExtFound = false;
- {
- std::vector<VkExtensionProperties> deviceExtensions(deviceExtensionCount);
- VKCHECK(vkEnumerateDeviceExtensionProperties(gpu, nullptr, &deviceExtensionCount, deviceExtensions.data()));
- for (uint32_t i = 0; i < deviceExtensionCount; ++i) {
- if (std::strcmp(VK_KHR_SWAPCHAIN_EXTENSION_NAME, deviceExtensions[i].extensionName) == 0) {
- swapchainExtFound = true;
- enabledDeviceExtensions[enabledDeviceExtensionCount++] = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
- }
- }
- }
- if (!swapchainExtFound) {
- assert(false && "Need the swapchain extension, but it wasn't found");
- }
- uint32_t queueFamilyCount;
- pfnGetPhysicalDeviceQueueFamilyProperties(gpu, &queueFamilyCount, nullptr);
- uint32_t suitableQueueFamilyIndex;
- {
- std::vector<VkQueueFamilyProperties> queueFamilyProperties(queueFamilyCount);
- pfnGetPhysicalDeviceQueueFamilyProperties(gpu, &queueFamilyCount, queueFamilyProperties.data());
- for (uint32_t i = 0; i < queueFamilyCount; ++i) {
- if (queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
- if (glfwGetPhysicalDevicePresentationSupport(instance, gpu, i)) {
- suitableQueueFamilyIndex = i;
- break;
- }
- }
- }
- }
- VkDeviceQueueCreateInfo queueCreateInfo = {};
- queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queueCreateInfo.pNext = nullptr;
- queueCreateInfo.flags = 0;
- queueCreateInfo.queueFamilyIndex = suitableQueueFamilyIndex;
- queueCreateInfo.queueCount = 1;
- float queuePriority = 0.0f;
- queueCreateInfo.pQueuePriorities = &queuePriority;
- VkDeviceCreateInfo deviceCreateInfo = {};
- deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
- deviceCreateInfo.pNext = nullptr;
- deviceCreateInfo.flags = 0;
- deviceCreateInfo.queueCreateInfoCount = 1;
- deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
- deviceCreateInfo.enabledLayerCount = (uint32_t)instanceValidationLayerNames.size(); // TODO: layer checking omitted
- deviceCreateInfo.ppEnabledLayerNames = instanceValidationLayerNames.data();
- deviceCreateInfo.enabledExtensionCount = enabledDeviceExtensionCount;
- deviceCreateInfo.ppEnabledExtensionNames = enabledDeviceExtensions.data();
- deviceCreateInfo.pEnabledFeatures = nullptr;
- VkDevice device;
- VKCHECK(pfnCreateDevice(gpu, &deviceCreateInfo, nullptr, &device));
- glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
- uint32_t width = 1280;
- uint32_t height = 720;
- GLFWwindow* window = glfwCreateWindow(width, height, "Vulkan on GLFW", nullptr, nullptr);
- VkSurfaceKHR surface;
- glfwCreateWindowSurface(instance, window, nullptr, &surface);
- VkBool32 surfSupported = VK_FALSE;
- VKCHECK(vkGetPhysicalDeviceSurfaceSupportKHR(gpu, suitableQueueFamilyIndex, surface, &surfSupported));
- assert(surfSupported == VK_TRUE);
- VkQueue queue;
- vkGetDeviceQueue(device, suitableQueueFamilyIndex, 0, &queue);
- VkSurfaceCapabilitiesKHR surfCaps;
- VKCHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu, surface, &surfCaps));
- VkPhysicalDeviceMemoryProperties memProps;
- vkGetPhysicalDeviceMemoryProperties(gpu, &memProps);
- uint32_t presentModeCount;
- VKCHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(gpu, surface, &presentModeCount, nullptr));
- VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
- {
- std::vector<VkPresentModeKHR> presentModes(presentModeCount);
- VKCHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(gpu, surface, &presentModeCount, presentModes.data()));
- for (uint32_t i = 0; i < presentModeCount; ++i) {
- if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
- swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
- break;
- }
- if ((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) &&
- (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) {
- swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
- }
- }
- }
- VkExtent2D swapchainExtent = {};
- if (surfCaps.currentExtent.width == 0xffffffff) {
- swapchainExtent.width = width;
- swapchainExtent.height = height;
- } else {
- swapchainExtent = surfCaps.currentExtent;
- width = surfCaps.currentExtent.width;
- height = surfCaps.currentExtent.height;
- }
- VkSurfaceTransformFlagBitsKHR preTransform;
- if (surfCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
- preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
- } else {
- preTransform = surfCaps.currentTransform;
- }
- uint32_t formatCount;
- VKCHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(gpu, surface, &formatCount, nullptr));
- VkFormat suitableFormat;
- VkColorSpaceKHR suitableColorSpace;
- {
- std::vector<VkSurfaceFormatKHR> surfFormats(formatCount);
- VKCHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(gpu, surface, &formatCount, surfFormats.data()));
- if ((formatCount == 1) && (surfFormats[0].format == VK_FORMAT_UNDEFINED)) {
- suitableFormat = VK_FORMAT_B8G8R8A8_UNORM;
- } else {
- assert(formatCount >= 1);
- suitableFormat = surfFormats[0].format;
- }
- suitableColorSpace = surfFormats[0].colorSpace;
- }
- VkSwapchainCreateInfoKHR swapchainCreateInfo = {};
- swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
- swapchainCreateInfo.pNext = nullptr;
- swapchainCreateInfo.flags = 0;
- swapchainCreateInfo.surface = surface;
- swapchainCreateInfo.minImageCount = 2;
- swapchainCreateInfo.imageFormat = suitableFormat;
- swapchainCreateInfo.imageColorSpace = suitableColorSpace;
- swapchainCreateInfo.imageExtent = swapchainExtent;
- swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
- swapchainCreateInfo.preTransform = preTransform;
- swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
- swapchainCreateInfo.imageArrayLayers = 1;
- swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
- swapchainCreateInfo.queueFamilyIndexCount = 0;
- swapchainCreateInfo.pQueueFamilyIndices = nullptr;
- swapchainCreateInfo.presentMode = swapchainPresentMode;
- swapchainCreateInfo.oldSwapchain = VK_NULL_HANDLE;
- swapchainCreateInfo.clipped = VK_TRUE;
- PFN_vkCreateSwapchainKHR pfnCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)pfnGetDeviceProcAddr(device, "vkCreateSwapchainKHR");
- PFN_vkDestroySwapchainKHR pfnDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)pfnGetDeviceProcAddr(device, "vkDestroySwapchainKHR");
- PFN_vkGetSwapchainImagesKHR pfnGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)pfnGetDeviceProcAddr(device, "vkGetSwapchainImagesKHR");
- PFN_vkAcquireNextImageKHR pfnAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)pfnGetDeviceProcAddr(device, "vkAcquireNextImageKHR");
- PFN_vkQueuePresentKHR pfnQueuePresentKHR = (PFN_vkQueuePresentKHR)pfnGetDeviceProcAddr(device, "vkQueuePresentKHR");
- VkSwapchainKHR swapchain;
- VKCHECK(pfnCreateSwapchainKHR(device, &swapchainCreateInfo, nullptr, &swapchain));
- std::array<VkImage, 2> swapchainImages;
- uint32_t swapchainImageCount;
- VKCHECK(pfnGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, nullptr));
- assert(swapchainImageCount == 2);
- VKCHECK(pfnGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, swapchainImages.data()));
- uint32_t currentSwapchainImage = 0;
- // create a command pool
- VkCommandPoolCreateInfo cmdPoolCreateInfo = {};
- cmdPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
- cmdPoolCreateInfo.pNext = nullptr;
- cmdPoolCreateInfo.flags = 0;
- cmdPoolCreateInfo.queueFamilyIndex = suitableQueueFamilyIndex;
- VkCommandPool cmdPool;
- VKCHECK(vkCreateCommandPool(device, &cmdPoolCreateInfo, nullptr, &cmdPool));
- // create a depth buffer
- VkFormat depthFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
- VkImageCreateInfo dsImageCreateInfo = {};
- dsImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
- dsImageCreateInfo.pNext = nullptr;
- dsImageCreateInfo.flags = 0;
- dsImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
- dsImageCreateInfo.format = depthFormat;
- dsImageCreateInfo.extent = { width, height, 1 };
- dsImageCreateInfo.mipLevels = 1;
- dsImageCreateInfo.arrayLayers = 1;
- dsImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
- dsImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
- dsImageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
- VkImageViewCreateInfo dsivCreateInfo = {};
- dsivCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
- dsivCreateInfo.pNext = nullptr;
- dsivCreateInfo.flags = 0;
- dsivCreateInfo.image = VK_NULL_HANDLE;
- dsivCreateInfo.format = depthFormat;
- dsivCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
- dsivCreateInfo.subresourceRange.baseMipLevel = 0;
- dsivCreateInfo.subresourceRange.levelCount = 1;
- dsivCreateInfo.subresourceRange.baseArrayLayer = 0;
- dsivCreateInfo.subresourceRange.layerCount = 1;
- dsivCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
- VkMemoryRequirements dsMemReqs;
- VkImage dsImage;
- VKCHECK(vkCreateImage(device, &dsImageCreateInfo, nullptr, &dsImage));
- vkGetImageMemoryRequirements(device, dsImage, &dsMemReqs);
- VkMemoryAllocateInfo dsMemAllocInfo = {};
- dsMemAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
- dsMemAllocInfo.pNext = nullptr;
- dsMemAllocInfo.allocationSize = dsMemReqs.size;
- dsMemAllocInfo.memoryTypeIndex = 0;
- bool ok = getMemoryTypeFromProperties(memProps, dsMemReqs.memoryTypeBits, 0, &dsMemAllocInfo.memoryTypeIndex);
- assert(ok);
- VkDeviceMemory dsMemory;
- VKCHECK(vkAllocateMemory(device, &dsMemAllocInfo, nullptr, &dsMemory));
- VKCHECK(vkBindImageMemory(device, dsImage, dsMemory, 0));
- VkCommandBuffer cmdBuf = VK_NULL_HANDLE;
- setImageLayout(cmdBuf, device, cmdPool, dsImage, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, (VkAccessFlagBits)0);
- VkImageView dsImageView;
- dsivCreateInfo.image = dsImage;
- VKCHECK(vkCreateImageView(device, &dsivCreateInfo, nullptr, &dsImageView));
- VkImageViewCreateInfo ivCreateInfo = {};
- ivCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
- ivCreateInfo.pNext = nullptr;
- ivCreateInfo.flags = 0;
- ivCreateInfo.format = suitableFormat;
- ivCreateInfo.components = {
- VK_COMPONENT_SWIZZLE_R,
- VK_COMPONENT_SWIZZLE_G,
- VK_COMPONENT_SWIZZLE_B,
- VK_COMPONENT_SWIZZLE_A
- };
- ivCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- ivCreateInfo.subresourceRange.baseMipLevel = 0;
- ivCreateInfo.subresourceRange.levelCount = 1;
- ivCreateInfo.subresourceRange.baseArrayLayer = 0;
- ivCreateInfo.subresourceRange.layerCount = 1;
- ivCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
- std::array<VkImageView, 2> presentViews;
- for (uint32_t i = 0; i < 2; ++i) {
- ivCreateInfo.image = swapchainImages[i];
- VKCHECK(vkCreateImageView(device, &ivCreateInfo, nullptr, &presentViews[i]));
- }
- VkAttachmentDescription attachments[2] = {};
- attachments[0].format = suitableFormat;
- attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
- attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- attachments[1].format = depthFormat;
- attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
- attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- VkAttachmentReference colorReference = {};
- colorReference.attachment = 0;
- colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- VkAttachmentReference depthStencilReference = {};
- depthStencilReference.attachment = 1;
- depthStencilReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- VkSubpassDescription subpassDesc = {};
- subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
- subpassDesc.flags = 0;
- subpassDesc.inputAttachmentCount = 0;
- subpassDesc.pInputAttachments = nullptr;
- subpassDesc.colorAttachmentCount = 1;
- subpassDesc.pColorAttachments = &colorReference;
- subpassDesc.pResolveAttachments = nullptr;
- subpassDesc.pDepthStencilAttachment = &depthStencilReference;
- subpassDesc.preserveAttachmentCount = 0;
- subpassDesc.pPreserveAttachments = nullptr;
- VkRenderPassCreateInfo rpCreateInfo = {};
- rpCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
- rpCreateInfo.pNext = nullptr;
- rpCreateInfo.flags = 0;
- rpCreateInfo.attachmentCount = 2;
- rpCreateInfo.pAttachments = attachments;
- rpCreateInfo.subpassCount = 1;
- rpCreateInfo.pSubpasses = &subpassDesc;
- rpCreateInfo.dependencyCount = 0;
- rpCreateInfo.pDependencies = nullptr;
- VkRenderPass renderPass;
- VKCHECK(vkCreateRenderPass(device, &rpCreateInfo, nullptr, &renderPass));
- std::array<VkImageView, 2> fbAttachments;
- fbAttachments[1] = dsImageView;
- VkFramebufferCreateInfo fbCreateInfo = {};
- fbCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
- fbCreateInfo.pNext = nullptr;
- fbCreateInfo.flags = 0;
- fbCreateInfo.renderPass = renderPass;
- fbCreateInfo.attachmentCount = 2;
- fbCreateInfo.pAttachments = fbAttachments.data();
- fbCreateInfo.width = width;
- fbCreateInfo.height = height;
- fbCreateInfo.layers = 1;
- std::array<VkFramebuffer, 2> framebuffers;
- for (uint32_t i = 0; i < 2; ++i) {
- fbAttachments[0] = presentViews[i];
- VKCHECK(vkCreateFramebuffer(device, &fbCreateInfo, nullptr, framebuffers.data() + i));
- }
- // flush preparation commands
- VKCHECK(vkEndCommandBuffer(cmdBuf));
- VkSubmitInfo submitInfo = {};
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.pNext = nullptr;
- submitInfo.waitSemaphoreCount = 0;
- submitInfo.pWaitSemaphores = nullptr;
- submitInfo.pWaitDstStageMask = nullptr;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &cmdBuf;
- submitInfo.signalSemaphoreCount = 0;
- submitInfo.pSignalSemaphores = nullptr;
- VKCHECK(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
- VKCHECK(vkQueueWaitIdle(queue));
- vkFreeCommandBuffers(device, cmdPool, 1, &cmdBuf);
- cmdBuf = VK_NULL_HANDLE;
- // and create new ones for rendering
- VkCommandBufferAllocateInfo cmdBufAllocInfo = {};
- cmdBufAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
- cmdBufAllocInfo.pNext = nullptr;
- cmdBufAllocInfo.commandPool = cmdPool;
- cmdBufAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
- cmdBufAllocInfo.commandBufferCount = 2;
- std::array<VkCommandBuffer, 2> cmdBufs;
- VKCHECK(vkAllocateCommandBuffers(device, &cmdBufAllocInfo, cmdBufs.data()));
- VkCommandBufferInheritanceInfo cmdBufInhInfo = {};
- cmdBufInhInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
- cmdBufInhInfo.pNext = nullptr;
- cmdBufInhInfo.renderPass = VK_NULL_HANDLE;
- cmdBufInhInfo.subpass = 0;
- cmdBufInhInfo.framebuffer = VK_NULL_HANDLE;
- cmdBufInhInfo.occlusionQueryEnable = VK_FALSE;
- cmdBufInhInfo.queryFlags = 0;
- cmdBufInhInfo.pipelineStatistics = 0;
- VkCommandBufferBeginInfo cmdBufBeginInfo = {};
- cmdBufBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- cmdBufBeginInfo.pNext = nullptr;
- cmdBufBeginInfo.flags = 0;
- cmdBufBeginInfo.pInheritanceInfo = &cmdBufInhInfo;
- std::array<VkClearValue, 2> clearValues = {};
- clearValues[0].color.float32[0] = 0.5f;
- clearValues[0].color.float32[1] = 0.5f;
- clearValues[0].color.float32[2] = 0.5f;
- clearValues[0].color.float32[3] = 1.0f;
- clearValues[1].depthStencil = { 1.0f, 0 };
- // build our drawing command buffers
- for (uint32_t i = 0; i < 2; ++i) {
- VKCHECK(vkBeginCommandBuffer(cmdBufs[i], &cmdBufBeginInfo));
- VkImageMemoryBarrier imageMemBarrier = {};
- imageMemBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
- imageMemBarrier.pNext = nullptr;
- imageMemBarrier.srcAccessMask = 0;
- imageMemBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- imageMemBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- imageMemBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- imageMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- imageMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- imageMemBarrier.image = swapchainImages[i];
- imageMemBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
- vkCmdPipelineBarrier(cmdBufs[i], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemBarrier);
- VkRenderPassBeginInfo rpBeginInfo = {};
- rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
- rpBeginInfo.pNext = nullptr;
- rpBeginInfo.renderPass = renderPass;
- rpBeginInfo.framebuffer = framebuffers[i];
- rpBeginInfo.renderArea.offset.x = 0;
- rpBeginInfo.renderArea.offset.y = 0;
- rpBeginInfo.renderArea.extent.width = width;
- rpBeginInfo.renderArea.extent.height = height;
- rpBeginInfo.clearValueCount = 2;
- rpBeginInfo.pClearValues = clearValues.data();
- vkCmdBeginRenderPass(cmdBufs[i], &rpBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
- VkViewport viewport = {};
- viewport.width = static_cast<float>(width);
- viewport.height = static_cast<float>(height);
- viewport.minDepth = 0.0f;
- viewport.maxDepth = 1.0f;
- vkCmdSetViewport(cmdBufs[i], 0, 1, &viewport);
- VkRect2D scissor = {};
- scissor.extent.width = width;
- scissor.extent.height = height;
- scissor.offset.x = 0;
- scissor.offset.y = 0;
- vkCmdSetScissor(cmdBufs[i], 0, 1, &scissor);
- vkCmdEndRenderPass(cmdBufs[i]);
- VkImageMemoryBarrier prePresentBarrier = {};
- prePresentBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
- prePresentBarrier.pNext = nullptr;
- prePresentBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- prePresentBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
- prePresentBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- prePresentBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
- prePresentBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- prePresentBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- prePresentBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
- prePresentBarrier.image = swapchainImages[i];
- vkCmdPipelineBarrier(cmdBufs[i], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &prePresentBarrier);
- VKCHECK(vkEndCommandBuffer(cmdBufs[i]));
- }
- // main loop
- while (!glfwWindowShouldClose(window)) {
- glfwPollEvents();
- // do the rendering
- VkSemaphore presentCompleteSemaphore;
- VkSemaphoreCreateInfo pcsCreateInfo = {};
- pcsCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
- pcsCreateInfo.pNext = nullptr;
- pcsCreateInfo.flags = 0;
- VKCHECK(vkCreateSemaphore(device, &pcsCreateInfo, nullptr, &presentCompleteSemaphore));
- VkResult res = pfnAcquireNextImageKHR(device, swapchain, UINT64_MAX, presentCompleteSemaphore, VK_NULL_HANDLE, ¤tSwapchainImage);
- if (res == VK_ERROR_OUT_OF_DATE_KHR) {
- assert(false && "Swapchain is out-of-date!");
- } else if (res == VK_SUBOPTIMAL_KHR) {
- } else {
- assert(res == VK_SUCCESS);
- }
- VkSubmitInfo submitInfo = {};
- VkPipelineStageFlags pipelineStageFlags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.pNext = nullptr;
- submitInfo.waitSemaphoreCount = 1;
- submitInfo.pWaitSemaphores = &presentCompleteSemaphore;
- submitInfo.pWaitDstStageMask = &pipelineStageFlags;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &cmdBufs[currentSwapchainImage];
- submitInfo.signalSemaphoreCount = 0;
- submitInfo.pSignalSemaphores = nullptr;
- res = vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
- assert(res == VK_SUCCESS);
- VkPresentInfoKHR present = {};
- present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
- present.pNext = nullptr;
- present.swapchainCount = 1;
- present.pSwapchains = &swapchain;
- present.pImageIndices = ¤tSwapchainImage;
- res = pfnQueuePresentKHR(queue, &present);
- if (res == VK_ERROR_OUT_OF_DATE_KHR) {
- assert(false && "Swapchain out of date!");
- } else if (res == VK_SUBOPTIMAL_KHR) {
- } else {
- assert(res == VK_SUCCESS);
- }
- res = vkQueueWaitIdle(queue);
- assert(res == VK_SUCCESS);
- vkDestroySemaphore(device, presentCompleteSemaphore, nullptr);
- }
- // free allocated resources
- vkDestroyRenderPass(device, renderPass, nullptr);
- vkDestroyImageView(device, dsImageView, nullptr);
- vkDestroyImage(device, dsImage, nullptr);
- vkFreeMemory(device, dsMemory, nullptr);
- vkFreeCommandBuffers(device, cmdPool, 2, cmdBufs.data());
- vkDestroyCommandPool(device, cmdPool, nullptr);
- for (VkImageView pv : presentViews) {
- vkDestroyImageView(device, pv, nullptr);
- }
- for (VkFramebuffer fb : framebuffers) {
- vkDestroyFramebuffer(device, fb, nullptr);
- }
- pfnDestroySwapchainKHR(device, swapchain, nullptr);
- pfnDestroySurfaceKHR(instance, surface, nullptr);
- glfwDestroyWindow(window);
- pfnDestroyDevice(device, nullptr);
- pfnDestroyDebugReportCallbackEXT(instance, debugReportCallback, nullptr);
- pfnDestroyInstance(instance, nullptr);
- glfwTerminate();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement