Вот мой код: < /p>
Код: Выделить всё
// g++ -std=c++20 -O2 -o Triangle main.cpp -lglfw -ldl -lvulkan
#include
#include
#include
#define VULKAN_HPP_NO_CONSTRUCTORS
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
#include
#include
#include
#include
#include
#include
#include
#include
#define GLFW_INCLUDE_VULKAN
#include
#include
#include
#include
constexpr uint32_t WIDTH = 800;
constexpr uint32_t HEIGHT = 600;
const char *TITLE = "Vulkan";
const std::vector validationLayers = {
"VK_LAYER_KHRONOS_validation",
};
#ifdef NDEBUG
bool enableValidationLayers = false;
#else
bool enableValidationLayers = true;
#endif
class TriangleApplication {
private:
GLFWwindow *window;
vk::raii::Context context;
vk::raii::Instance instance = nullptr;
vk::raii::DebugUtilsMessengerEXT debugMessenger = nullptr;
vk::raii::SurfaceKHR surface = nullptr;
vk::raii::PhysicalDevice physicalDevice = nullptr;
vk::raii::Device device = nullptr;
vk::PhysicalDeviceFeatures deviceFeatures;
uint32_t graphicsIndex = -1;
vk::Queue graphicsQueue = nullptr;
uint32_t presentIndex = -1;
vk::Queue presentQueue = nullptr;
vk::raii::SwapchainKHR swapChain = nullptr;
std::vector swapChainImages;
vk::Format swapChainImageFormat = vk::Format::eUndefined;
vk::Extent2D swapChainExtent;
std::vector requiredDeviceExtensions = {
vk::KHRSwapchainExtensionName,
vk::KHRSpirv14ExtensionName,
vk::KHRSynchronization2ExtensionName,
vk::KHRCreateRenderpass2ExtensionName,
};
void initWindow() {
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
window = glfwCreateWindow(WIDTH, HEIGHT, TITLE, nullptr, nullptr);
}
void initVulkan() {
createInstance();
createSurface();
setupDebugMessenger();
pickPhysicalDevice();
createLogicalDevice();
createSwapChain();
}
void createSwapChain() {
auto surfaceCapabilities =
physicalDevice.getSurfaceCapabilitiesKHR(surface);
swapChainImageFormat =
chooseSwapChainFormat(physicalDevice.getSurfaceFormatsKHR(surface))
.format;
swapChainExtent = chooseSwapChainExtent(surfaceCapabilities);
auto minImageCount = std::max(3u, surfaceCapabilities.minImageCount);
minImageCount = (surfaceCapabilities.maxImageCount > 0 &&
minImageCount > surfaceCapabilities.maxImageCount)
? surfaceCapabilities.maxImageCount
: minImageCount;
vk::SwapchainCreateInfoKHR swapChainCreateInfo{
.flags = vk::SwapchainCreateFlagsKHR(),
.surface = surface,
.minImageCount = minImageCount,
.imageFormat = swapChainImageFormat,
.imageColorSpace = vk::ColorSpaceKHR::eSrgbNonlinear,
.imageExtent = swapChainExtent,
.imageArrayLayers = 1,
.imageUsage = vk::ImageUsageFlagBits::eColorAttachment,
.imageSharingMode = vk::SharingMode::eExclusive,
.preTransform = surfaceCapabilities.currentTransform,
.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque,
.presentMode = chooseSwapChainPresentMode(
physicalDevice.getSurfacePresentModesKHR(surface)),
.clipped = true,
.oldSwapchain = nullptr,
};
if (graphicsIndex == presentIndex) {
uint32_t queueFamilyIndices[] = {graphicsIndex};
swapChainCreateInfo.imageSharingMode = vk::SharingMode::eExclusive;
swapChainCreateInfo.queueFamilyIndexCount = 0;
swapChainCreateInfo.pQueueFamilyIndices = nullptr;
} else {
uint32_t queueFamilyIndices[] = {graphicsIndex, presentIndex};
swapChainCreateInfo.imageSharingMode = vk::SharingMode::eConcurrent;
swapChainCreateInfo.queueFamilyIndexCount = 2;
swapChainCreateInfo.pQueueFamilyIndices = queueFamilyIndices;
}
swapChain = vk::raii::SwapchainKHR(device, swapChainCreateInfo);
}
vk::SurfaceFormatKHR chooseSwapChainFormat(
const std::vector &availableFormats) {
for (const auto &availableFormat : availableFormats) {
if (availableFormat.format == vk::Format::eB8G8R8A8Srgb &&
availableFormat.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear) {
return availableFormat;
}
}
return availableFormats[0];
}
vk::PresentModeKHR chooseSwapChainPresentMode(
const std::vector &availablePresentModes) {
for (const auto &availablePresentMode : availablePresentModes) {
if (availablePresentMode == vk::PresentModeKHR::eMailbox) {
return availablePresentMode;
}
}
return vk::PresentModeKHR::eFifo;
}
vk::Extent2D
chooseSwapChainExtent(const vk::SurfaceCapabilitiesKHR &surfaceCapabilites) {
if (surfaceCapabilites.currentExtent.width !=
std::numeric_limits::max()) {
return surfaceCapabilites.currentExtent;
}
int width, height;
glfwGetFramebufferSize(window, &width, &height);
return {
std::clamp(width, surfaceCapabilites.minImageExtent.width,
surfaceCapabilites.maxImageExtent.width),
std::clamp(height, surfaceCapabilites.minImageExtent.height,
surfaceCapabilites.maxImageExtent.height),
};
}
void createSurface() {
VkSurfaceKHR _surface;
if (glfwCreateWindowSurface(*instance, window, nullptr, &_surface) != 0) {
throw std::runtime_error("failed to create window surface!");
}
surface = vk::raii::SurfaceKHR(instance, _surface);
}
void createLogicalDevice() {
std::vector queueFamilyProperties =
physicalDevice.getQueueFamilyProperties();
for (size_t i = 0; i < queueFamilyProperties.size(); i++) {
if ((queueFamilyProperties[i].queueFlags &
vk::QueueFlagBits::eGraphics) != static_cast(0)) {
graphicsIndex = i;
}
VkBool32 presentSupport =
physicalDevice.getSurfaceSupportKHR(i, *surface);
if (presentSupport) {
presentIndex = i;
}
if (graphicsIndex != -1 && presentSupport != -1) {
break;
}
}
if (graphicsIndex == -1) {
throw std::runtime_error("No graphics queue family found!");
}
if (presentIndex == -1) {
throw std::runtime_error("No present queue family found!");
}
std::cout
Подробнее здесь: [url]https://stackoverflow.com/questions/79736586/segmentation-fault-when-creating-vulkan-swapchain[/url]
Мобильная версия