123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693 |
- #include "core/VulkanWrapper.hpp"
- #include <core/File.hpp>
- #include <core/UniquePointer.hpp>
- #include "GLFW.hpp"
- #include "core/VulkanBase.hpp"
- namespace Vulkan = Core::Vulkan;
- using Vulkan::CommandBuffer;
- using Vulkan::Queue;
- using Vulkan::SwapchainImages;
- #define WRAPPER_DESTRUCT(Type, ...) \
- using Core::Vulkan::Type; \
- Type::~Type() { \
- if(device != VK_NULL_HANDLE) { \
- vkDestroy##Type##__VA_ARGS__(device, handle, nullptr); \
- } \
- }
- WRAPPER_DESTRUCT(ImageView)
- WRAPPER_DESTRUCT(Framebuffer)
- WRAPPER_DESTRUCT(Semaphore)
- WRAPPER_DESTRUCT(Fence)
- WRAPPER_DESTRUCT(Swapchain, KHR)
- WRAPPER_DESTRUCT(ShaderModule)
- WRAPPER_DESTRUCT(PipelineLayout)
- WRAPPER_DESTRUCT(Pipeline)
- WRAPPER_DESTRUCT(CommandPool)
- WRAPPER_DESTRUCT(RenderPass)
- bool ImageView::init(VkDevice d, VkImage image, VkFormat format) {
- VkImageViewCreateInfo info = {
- .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
- .image = image,
- .viewType = VK_IMAGE_VIEW_TYPE_2D,
- .format = format,
- .subresourceRange = {
- .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
- .baseMipLevel = 0,
- .levelCount = 1,
- .baseArrayLayer = 0,
- .layerCount = 1}};
- VK_CHECK_TRUE(vkCreateImageView(d, &info, nullptr, &handle));
- device = d;
- return false;
- }
- bool Framebuffer::init(
- const ImageView& iv, VkRenderPass rp, u32 width, u32 height) {
- VkFramebufferCreateInfo info = {
- .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
- .renderPass = rp,
- .attachmentCount = 1,
- .pAttachments = iv,
- .width = width,
- .height = height,
- .layers = 1};
- VK_CHECK_TRUE(vkCreateFramebuffer(iv.device, &info, nullptr, &handle));
- device = iv.device;
- return false;
- }
- bool Semaphore::init(VkDevice d) {
- VkSemaphoreCreateInfo info = {
- .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
- VK_CHECK_TRUE(vkCreateSemaphore(d, &info, nullptr, &handle));
- device = d;
- return false;
- }
- bool Fence::init(VkDevice d) {
- VkFenceCreateInfo info = {
- .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
- .flags = VK_FENCE_CREATE_SIGNALED_BIT};
- VK_CHECK_TRUE(vkCreateFence(d, &info, nullptr, &handle));
- device = d;
- return false;
- }
- void Fence::reset() {
- VK_CHECK_VOID(vkResetFences(device, 1, &handle));
- }
- void Fence::waitFor(u64 timeout) {
- VK_CHECK_VOID(vkWaitForFences(device, 1, &handle, true, timeout));
- }
- static u32 getSwapImageCount(const VkSurfaceCapabilitiesKHR* caps) {
- u32 c = caps->minImageCount + 1;
- // according to VkSurfaceCapabilitiesKHR doc:
- // maxImageCount is 0 when there is no strict limit
- if(caps->maxImageCount != 0) {
- return Core::min(c, caps->maxImageCount);
- }
- return c;
- }
- bool Swapchain::init(Data& d) {
- VkSurfaceCapabilitiesKHR caps = {0};
- if(d.base.getSurfaceCapabilities(caps)) {
- return true;
- }
- VkSwapchainCreateInfoKHR ci = {
- .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
- .surface = d.base,
- .minImageCount = getSwapImageCount(&caps),
- .imageFormat = d.surfaceFormat.format,
- .imageColorSpace = d.surfaceFormat.colorSpace,
- .imageExtent = d.size,
- .imageArrayLayers = 1,
- .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
- .imageSharingMode = d.sharingMode,
- .queueFamilyIndexCount = static_cast<u32>(d.queueFamilies.getLength()),
- .pQueueFamilyIndices = &d.queueFamilies[0],
- .preTransform = caps.currentTransform,
- .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
- .presentMode = d.presentMode,
- .clipped = VK_TRUE,
- .oldSwapchain = VK_NULL_HANDLE};
- VK_CHECK_TRUE(vkCreateSwapchainKHR(d.base, &ci, nullptr, &handle));
- device = d.base;
- return false;
- }
- bool Swapchain::nextImage(u32& imageIndex, Semaphore& s, u64 timeout) {
- VK_CHECK_TRUE(vkAcquireNextImageKHR(
- device, handle, timeout, s, VK_NULL_HANDLE, &imageIndex));
- return false;
- }
- bool ShaderModule::init(VkDevice d, const char* path) {
- List<char> f;
- if(Core::readFile(f, path)) {
- return true;
- }
- size_t l = f.getLength() - 1;
- if((l % 4) != 0) {
- VK_REPORT_ERROR("Shader size is not a multiple of 4");
- return true;
- }
- VkShaderModuleCreateInfo info = {
- .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
- .codeSize = l,
- .pCode = reinterpret_cast<u32*>(static_cast<void*>(&f[0]))};
- VK_CHECK_TRUE(vkCreateShaderModule(d, &info, nullptr, &handle));
- device = d;
- return false;
- }
- bool PipelineLayout::init(VkDevice d) {
- VkPipelineLayoutCreateInfo info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
- VK_CHECK_TRUE(vkCreatePipelineLayout(d, &info, nullptr, &handle));
- device = d;
- return false;
- }
- bool SwapchainImages::init(const Swapchain& s, VkFormat format) {
- u32 c = 0;
- VK_CHECK_TRUE(vkGetSwapchainImagesKHR(s.device, s.handle, &c, nullptr));
- images.resize(c);
- imageViews.resize(c);
- VK_CHECK_TRUE(vkGetSwapchainImagesKHR(s.device, s.handle, &c, &images[0]));
- for(u32 x = 0; x < c; x++) {
- if(imageViews[x].init(s.device, images[x], format)) {
- return true;
- }
- }
- return false;
- }
- bool RenderPass::init(VkDevice d, VkFormat format) {
- VkAttachmentDescription c = {
- .format = format,
- .samples = VK_SAMPLE_COUNT_1_BIT,
- .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
- .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
- .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
- .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
- .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
- .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR};
- VkAttachmentReference ca = {
- .attachment = 0, .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
- VkSubpassDescription subpass = {
- .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
- .colorAttachmentCount = 1,
- .pColorAttachments = &ca};
- VkSubpassDependency dependency = {
- .srcSubpass = VK_SUBPASS_EXTERNAL,
- .dstSubpass = 0,
- .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- .srcAccessMask = 0,
- .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
- };
- VkRenderPassCreateInfo info = {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
- .attachmentCount = 1,
- .pAttachments = &c,
- .subpassCount = 1,
- .pSubpasses = &subpass,
- .dependencyCount = 1,
- .pDependencies = &dependency};
- VK_CHECK_TRUE(vkCreateRenderPass(d, &info, nullptr, &handle));
- device = d;
- return false;
- }
- Pipeline::Pipeline() : viewport{.maxDepth = 1.0f}, scissor{} {
- }
- void Pipeline::updateSize(u32 width, u32 height) {
- viewport.width = static_cast<float>(width);
- viewport.height = static_cast<float>(height);
- scissor.extent.width = width;
- scissor.extent.height = height;
- }
- bool Pipeline::init(PipelineLayout& pl, RenderPass& rp) {
- ShaderModule vertexShaderModule;
- ShaderModule fragmentShaderModule;
- if(vertexShaderModule.init(pl.device, "shaders/vertex.spv") ||
- fragmentShaderModule.init(pl.device, "shaders/fragment.spv")) {
- return true;
- }
- VkPipelineShaderStageCreateInfo stages[2] = {
- {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .stage = VK_SHADER_STAGE_VERTEX_BIT,
- .module = vertexShaderModule,
- .pName = "main"},
- {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
- .module = fragmentShaderModule,
- .pName = "main"}};
- VkPipelineVertexInputStateCreateInfo vertexInputState = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO};
- VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
- .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
- .primitiveRestartEnable = false};
- VkPipelineViewportStateCreateInfo viewportState = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
- .viewportCount = 1,
- .pViewports = &viewport,
- .scissorCount = 1,
- .pScissors = &scissor};
- VkPipelineRasterizationStateCreateInfo rasterizationState = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
- .depthClampEnable = false,
- .rasterizerDiscardEnable = false,
- .polygonMode = VK_POLYGON_MODE_FILL,
- .cullMode = VK_CULL_MODE_BACK_BIT,
- .frontFace = VK_FRONT_FACE_CLOCKWISE,
- .depthBiasEnable = false,
- .depthBiasConstantFactor = 0.0f,
- .depthBiasClamp = 0.0f,
- .depthBiasSlopeFactor = 0.0f,
- .lineWidth = 1.0f};
- VkPipelineMultisampleStateCreateInfo multisampleState = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
- .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
- .sampleShadingEnable = false,
- .minSampleShading = 1.0f,
- .pSampleMask = nullptr,
- .alphaToCoverageEnable = false,
- .alphaToOneEnable = false};
- VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {
- .blendEnable = false,
- .srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
- .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
- .colorBlendOp = VK_BLEND_OP_ADD,
- .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
- .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
- .alphaBlendOp = VK_BLEND_OP_ADD,
- .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
- VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT};
- VkPipelineColorBlendStateCreateInfo colorBlendState = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
- .logicOpEnable = false,
- .logicOp = VK_LOGIC_OP_COPY,
- .attachmentCount = 1,
- .pAttachments = &colorBlendAttachmentState,
- .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f}};
- Core::Array<VkDynamicState, 2> dynamicStates = {
- {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR}};
- VkPipelineDynamicStateCreateInfo dynamicState = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
- .dynamicStateCount = dynamicStates.getLength(),
- .pDynamicStates = dynamicStates.begin()};
- VkGraphicsPipelineCreateInfo info = {
- .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
- .stageCount = 2,
- .pStages = stages,
- .pVertexInputState = &vertexInputState,
- .pInputAssemblyState = &inputAssemblyState,
- .pTessellationState = nullptr,
- .pViewportState = &viewportState,
- .pRasterizationState = &rasterizationState,
- .pMultisampleState = &multisampleState,
- .pDepthStencilState = nullptr,
- .pColorBlendState = &colorBlendState,
- .pDynamicState = &dynamicState,
- .layout = pl,
- .renderPass = rp,
- .subpass = 0,
- .basePipelineHandle = VK_NULL_HANDLE,
- .basePipelineIndex = -1};
- VK_CHECK_TRUE(vkCreateGraphicsPipelines(
- pl.device, VK_NULL_HANDLE, 1, &info, nullptr, &handle));
- device = pl.device;
- return false;
- }
- bool CommandPool::init(VkDevice d, u32 queueFamily) {
- VkCommandPoolCreateInfo info = {
- .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
- .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
- .queueFamilyIndex = queueFamily};
- VK_CHECK_TRUE(vkCreateCommandPool(d, &info, nullptr, &handle));
- device = d;
- return false;
- }
- bool CommandBuffer::init(CommandPool& cp) {
- VkCommandBufferAllocateInfo info = {
- .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
- .commandPool = cp,
- .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
- .commandBufferCount = 1};
- VK_CHECK_TRUE(vkAllocateCommandBuffers(cp.device, &info, &handle));
- device = cp.device;
- return false;
- }
- void CommandBuffer::reset() {
- VK_CHECK_VOID(vkResetCommandBuffer(handle, 0));
- }
- void CommandBuffer::begin() {
- VkCommandBufferBeginInfo info = {
- .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO};
- VK_CHECK_VOID(vkBeginCommandBuffer(handle, &info));
- }
- void CommandBuffer::end() {
- VK_CHECK_VOID(vkEndCommandBuffer(handle));
- }
- void CommandBuffer::beginRenderPass(
- RenderPass& rp, Framebuffer& f, const VkExtent2D& size) {
- VkClearValue v = {.color = {.float32 = {0.0f, 0.0f, 0.0f, 1.0f}}};
- VkRenderPassBeginInfo info = {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
- .renderPass = rp,
- .framebuffer = f,
- .renderArea = {.offset = {0, 0}, .extent = size},
- .clearValueCount = 1,
- .pClearValues = &v};
- vkCmdBeginRenderPass(handle, &info, VK_SUBPASS_CONTENTS_INLINE);
- }
- void CommandBuffer::endRenderPass() {
- vkCmdEndRenderPass(handle);
- }
- void CommandBuffer::bindPipeline(Pipeline& p) {
- vkCmdBindPipeline(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, p);
- vkCmdSetViewport(handle, 0, 1, &p.viewport);
- vkCmdSetScissor(handle, 0, 1, &p.scissor);
- }
- void CommandBuffer::draw(u32 vertices) {
- vkCmdDraw(handle, vertices, 1, 0, 0);
- }
- bool Queue::init(VkDevice d, u32 queueFamily) {
- vkGetDeviceQueue(d, queueFamily, 0, &handle);
- return handle == VK_NULL_HANDLE;
- }
- void Queue::submit(
- CommandBuffer& cb, Fence& f, Semaphore& wait, Semaphore& signal,
- VkPipelineStageFlags flags) {
- VkSubmitInfo info = {
- .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
- .waitSemaphoreCount = 1,
- .pWaitSemaphores = wait,
- .pWaitDstStageMask = &flags,
- .commandBufferCount = 1,
- .pCommandBuffers = cb,
- .signalSemaphoreCount = 1,
- .pSignalSemaphores = signal};
- VK_CHECK_VOID(vkQueueSubmit(handle, 1, &info, f));
- }
- void Queue::present(Semaphore& signal, Swapchain& s, u32 index) {
- VkPresentInfoKHR info = {
- .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
- .waitSemaphoreCount = 1,
- .pWaitSemaphores = signal,
- .swapchainCount = 1,
- .pSwapchains = s,
- .pImageIndices = &index};
- VK_CHECK_VOID(vkQueuePresentKHR(handle, &info));
- }
- struct VulkanDummy {
- Core::Vulkan::Base base{};
- struct BaseData {
- u32 graphicsFamily = 0;
- u32 presentFamily = 0;
- VkSurfaceFormatKHR surfaceFormat{};
- VkPresentModeKHR presentMode{};
- };
- BaseData baseData{};
- Queue graphicsQueue{};
- Queue presentQueue{};
- VkExtent2D swapchainSize{};
- Swapchain swapchain{};
- SwapchainImages images{};
- PipelineLayout pipelineLayout{};
- RenderPass renderPass{};
- Pipeline pipeline{};
- Core::List<Vulkan::Framebuffer> framebuffers{};
- CommandPool commandPool{};
- size_t currentFrame = 0;
- bool shouldWait = false;
- struct Frame {
- CommandBuffer commandBuffer{};
- Semaphore imageAvailableSemaphore{};
- Semaphore renderFinishedSemaphore{};
- Fence inFlightFence{};
- };
- Core::Array<Frame, 2> frames{};
- static int getSurfaceFormatPoints(const VkSurfaceFormatKHR& sf) {
- if(sf.format == VK_FORMAT_B8G8R8A8_UNORM &&
- sf.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
- return 10;
- }
- return 1;
- }
- static int getSurfacePresentModePoints(VkPresentModeKHR m) {
- if(m == VK_PRESENT_MODE_MAILBOX_KHR) {
- return 5;
- } else if(m == VK_PRESENT_MODE_FIFO_KHR) {
- return 2;
- }
- return 0;
- }
- bool getSwapchainSize(VkExtent2D* size) {
- VkSurfaceCapabilitiesKHR c = {0};
- if(base.getSurfaceCapabilities(c)) {
- return true;
- }
- if(c.currentExtent.width != 0xFFFF'FFFFu &&
- c.currentExtent.height != 0xFFFF'FFFFu) {
- *size = c.currentExtent;
- LOG_INFO("Swapchain size: #x#", size->width, size->height);
- return false;
- }
- int w = 0;
- int h = 0;
- glfwGetFramebufferSize(Core::Window::get(), &w, &h);
- if(w <= 0 || h <= 0) {
- LOG_ERROR("Could not get framebuffer size");
- return true;
- }
- LOG_INFO("Framebuffer size: #x#", w, h);
- size->width = Core::clamp(
- static_cast<u32>(w), c.minImageExtent.width,
- c.maxImageExtent.width);
- size->height = Core::clamp(
- static_cast<u32>(h), c.minImageExtent.height,
- c.maxImageExtent.height);
- LOG_INFO("Swapchain size: #x#", size->width, size->height);
- return false;
- }
- bool initSwapchain() {
- Vulkan::Swapchain::Data d = {
- .base = base,
- .surfaceFormat = baseData.surfaceFormat,
- .presentMode = baseData.presentMode};
- if(getSwapchainSize(&d.size)) {
- LOG_ERROR("Could not retrieve any swapchain size");
- return true;
- }
- swapchainSize = d.size;
- d.queueFamilies.add(baseData.graphicsFamily);
- if(baseData.graphicsFamily != baseData.presentFamily) {
- d.queueFamilies.add(baseData.presentFamily);
- d.sharingMode = VK_SHARING_MODE_CONCURRENT;
- } else {
- d.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
- }
- return swapchain.init(d);
- }
- bool initDevice() {
- bool same = baseData.graphicsFamily == baseData.presentFamily;
- Core::List<Vulkan::DeviceQueueData> data;
- data.add(baseData.graphicsFamily, 1.0f);
- if(!same) {
- data.add(baseData.presentFamily, 1.0f);
- };
- Core::List<const char*> extensions;
- extensions.add(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
- if(base.initDevice(data, extensions)) {
- return true;
- } else if(graphicsQueue.init(base, baseData.graphicsFamily)) {
- LOG_ERROR("Cannot get device graphics queue");
- return true;
- } else if(presentQueue.init(base, baseData.presentFamily)) {
- LOG_ERROR("Cannot get device present queue");
- return true;
- }
- return false;
- }
- static int getDevicePoints(Vulkan::Base& b, BaseData& d) {
- int points = 0;
- VkPhysicalDeviceProperties p;
- b.getPhysicalDeviceProperties(p);
- LOG_INFO("Checking '#'", p.deviceName);
- switch(p.deviceType) {
- case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: points += 100; break;
- case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: points += 50; break;
- case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: points += 20; break;
- default: break;
- }
- d.graphicsFamily = b.findQueueFamily(VK_QUEUE_GRAPHICS_BIT);
- if(d.graphicsFamily == Vulkan::INVALID_QUEUE_FAMILY) {
- LOG_INFO("> ... has no graphics family");
- points = -1;
- }
- d.presentFamily = b.findSurfaceQueueFamily();
- if(d.presentFamily == Vulkan::INVALID_QUEUE_FAMILY) {
- LOG_INFO("> ... has no present family");
- points = -1;
- }
- if(!b.hasExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
- LOG_INFO("> ... has no swapchain support");
- points = -1;
- }
- if(b.findSurfaceFormat(d.surfaceFormat, getSurfaceFormatPoints)) {
- LOG_INFO("> ... has no matching surface format");
- points = -1;
- } else {
- points += getSurfaceFormatPoints(d.surfaceFormat);
- }
- if(b.findSurfacePresentMode(
- d.presentMode, getSurfacePresentModePoints)) {
- LOG_INFO("> ... has no matching present mode");
- points = -1;
- } else {
- points += getSurfacePresentModePoints(d.presentMode);
- }
- LOG_INFO("> Final points: #", points);
- return points;
- }
- bool initPhysicalDevice() {
- LOG_INFO("Searching for physical devices ...");
- if(base.findPhysicalDevice(baseData, getDevicePoints)) {
- LOG_ERROR("No matching physical device was found");
- return true;
- }
- VkPhysicalDeviceProperties p;
- base.getPhysicalDeviceProperties(p);
- LOG_INFO("Best Device: #", p.deviceName);
- return false;
- }
- bool initSwapchainImages() {
- if(images.init(swapchain, baseData.surfaceFormat.format)) {
- LOG_ERROR("Could not get swapchain images");
- return true;
- }
- LOG_INFO("Found # images", images.images.getLength());
- return false;
- }
- bool initPipeline() {
- pipeline.updateSize(swapchainSize.width, swapchainSize.height);
- return pipeline.init(pipelineLayout, renderPass);
- }
- bool initFramebuffers() {
- framebuffers.resize(images.imageViews.getLength());
- size_t i = 0;
- for(Framebuffer& f : framebuffers) {
- if(f.init(
- images.imageViews[i++], renderPass, swapchainSize.width,
- swapchainSize.height)) {
- return true;
- }
- }
- return false;
- }
- void fillCommandBuffer(CommandBuffer& cb, u32 index) {
- cb.begin();
- cb.beginRenderPass(renderPass, framebuffers[index], swapchainSize);
- cb.bindPipeline(pipeline);
- cb.draw(6);
- cb.endRenderPass();
- cb.end();
- }
- bool initFrames() {
- for(Frame& f : frames) {
- if(f.commandBuffer.init(commandPool) ||
- f.imageAvailableSemaphore.init(base) ||
- f.renderFinishedSemaphore.init(base) ||
- f.inFlightFence.init(base)) {
- return true;
- }
- }
- return false;
- }
- bool init() {
- return base.init() || initPhysicalDevice() || initDevice() ||
- initSwapchain() || initSwapchainImages() ||
- pipelineLayout.init(base) ||
- renderPass.init(base, baseData.surfaceFormat.format) ||
- initPipeline() || initFramebuffers() ||
- commandPool.init(base, baseData.graphicsFamily) || initFrames();
- }
- bool render() {
- if(shouldWait) {
- return false;
- }
- Frame& f = frames[currentFrame];
- f.inFlightFence.waitFor();
- f.inFlightFence.reset();
- u32 imageIndex = 0;
- if(swapchain.nextImage(imageIndex, f.imageAvailableSemaphore)) {
- return true;
- }
- f.commandBuffer.reset();
- fillCommandBuffer(f.commandBuffer, imageIndex);
- graphicsQueue.submit(
- f.commandBuffer, f.inFlightFence, f.imageAvailableSemaphore,
- f.renderFinishedSemaphore,
- VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
- presentQueue.present(f.renderFinishedSemaphore, swapchain, imageIndex);
- currentFrame = (currentFrame + 1) % frames.getLength();
- return false;
- }
- };
- static Core::UniquePointer<VulkanDummy> dummy;
- bool Vulkan::init() {
- dummy = new VulkanDummy();
- return dummy->init();
- }
- void Vulkan::render() {
- if(dummy->render()) {
- dummy->shouldWait = true;
- }
- }
- void Vulkan::destroy() {
- dummy->base.waitForIdle();
- dummy = nullptr;
- }
|