vulkan not working
This commit is contained in:
parent
a1be917178
commit
c45afab0dd
21 changed files with 1319 additions and 438 deletions
268
Crafter.Graphics-WindowWaylandVulkan.cpp
Normal file
268
Crafter.Graphics-WindowWaylandVulkan.cpp
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
module;
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <vulkan/vulkan_wayland.h>
|
||||
#include <vector>
|
||||
#include <wayland-client.h>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
|
||||
module Crafter.Graphics;
|
||||
import Crafter.Event;
|
||||
using namespace Crafter;
|
||||
|
||||
void WindowWaylandVulkan::CreateSwapchain()
|
||||
{
|
||||
VkResult result;
|
||||
|
||||
VkSurfaceCapabilitiesKHR capabilities;
|
||||
VulkanDevice::CHECK_VK_RESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VulkanDevice::physDevice, vulkanSurface, &capabilities));
|
||||
|
||||
uint32_t formatCount;
|
||||
VulkanDevice::CHECK_VK_RESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(VulkanDevice::physDevice, vulkanSurface, &formatCount, NULL));
|
||||
|
||||
std::vector<VkSurfaceFormatKHR> formats(formatCount);
|
||||
VulkanDevice::CHECK_VK_RESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(VulkanDevice::physDevice, vulkanSurface, &formatCount, formats.data()));
|
||||
|
||||
VkSurfaceFormatKHR chosenFormat = formats[0];
|
||||
|
||||
for (uint32_t i = 0; i < formatCount; i++)
|
||||
{
|
||||
if (formats[i].format == VK_FORMAT_B8G8R8A8_UNORM)
|
||||
{
|
||||
chosenFormat = formats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
format = chosenFormat.format;
|
||||
|
||||
imageCount = capabilities.minImageCount + 1 < capabilities.maxImageCount ? capabilities.minImageCount + 1 : capabilities.minImageCount;
|
||||
|
||||
VkSwapchainCreateInfoKHR swapchainCreateInfo = {};
|
||||
swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||
swapchainCreateInfo.surface = vulkanSurface;
|
||||
swapchainCreateInfo.minImageCount = imageCount;
|
||||
swapchainCreateInfo.imageFormat = chosenFormat.format;
|
||||
swapchainCreateInfo.imageColorSpace = chosenFormat.colorSpace;
|
||||
swapchainCreateInfo.imageExtent.width = width;
|
||||
swapchainCreateInfo.imageExtent.height = height;
|
||||
swapchainCreateInfo.imageArrayLayers = 1;
|
||||
swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
swapchainCreateInfo.preTransform = capabilities.currentTransform;
|
||||
swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
swapchainCreateInfo.presentMode = VK_PRESENT_MODE_MAILBOX_KHR;
|
||||
swapchainCreateInfo.clipped = 1;
|
||||
VulkanDevice::CHECK_VK_RESULT(vkCreateSwapchainKHR(VulkanDevice::device, &swapchainCreateInfo, NULL, &swapchain));
|
||||
|
||||
VkAttachmentDescription attachment = {};
|
||||
attachment.format = format;
|
||||
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
|
||||
VkAttachmentReference attachmentRef = {};
|
||||
attachmentRef.attachment = 0;
|
||||
attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkSubpassDescription subpass = {};
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpass.colorAttachmentCount = 1;
|
||||
subpass.pColorAttachments = &attachmentRef;
|
||||
|
||||
VkRenderPassCreateInfo renderPasscreateInfo = {};
|
||||
renderPasscreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
renderPasscreateInfo.flags = 0;
|
||||
renderPasscreateInfo.attachmentCount = 1;
|
||||
renderPasscreateInfo.pAttachments = &attachment;
|
||||
renderPasscreateInfo.subpassCount = 1;
|
||||
renderPasscreateInfo.pSubpasses = &subpass;
|
||||
VulkanDevice::CHECK_VK_RESULT(vkCreateRenderPass(VulkanDevice::device, &renderPasscreateInfo, NULL, &renderPass));
|
||||
|
||||
VulkanDevice::CHECK_VK_RESULT(vkGetSwapchainImagesKHR(VulkanDevice::device, swapchain, &imageCount, NULL));
|
||||
|
||||
std::vector<VkImage> images(imageCount);
|
||||
VulkanDevice::CHECK_VK_RESULT(vkGetSwapchainImagesKHR(VulkanDevice::device, swapchain, &imageCount, images.data()));
|
||||
|
||||
swapchainElements.resize(imageCount);
|
||||
|
||||
for (uint32_t i = 0; i < imageCount; i++)
|
||||
{
|
||||
VkCommandBufferAllocateInfo commandBufferAllocInfo = {};
|
||||
commandBufferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
commandBufferAllocInfo.commandPool = VulkanDevice::commandPool;
|
||||
commandBufferAllocInfo.commandBufferCount = 1;
|
||||
commandBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
vkAllocateCommandBuffers(VulkanDevice::device, &commandBufferAllocInfo, &swapchainElements[i].commandBuffer);
|
||||
|
||||
swapchainElements[i].image = images[i];
|
||||
|
||||
VkImageViewCreateInfo imageViewcreateInfo = {};
|
||||
imageViewcreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
imageViewcreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
imageViewcreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
imageViewcreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
imageViewcreateInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
imageViewcreateInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
imageViewcreateInfo.subresourceRange.baseMipLevel = 0;
|
||||
imageViewcreateInfo.subresourceRange.levelCount = 1;
|
||||
imageViewcreateInfo.subresourceRange.baseArrayLayer = 0;
|
||||
imageViewcreateInfo.subresourceRange.layerCount = 1;
|
||||
imageViewcreateInfo.image = swapchainElements[i].image;
|
||||
imageViewcreateInfo.format = format;
|
||||
imageViewcreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
VulkanDevice::CHECK_VK_RESULT(vkCreateImageView(VulkanDevice::device, &imageViewcreateInfo, NULL, &swapchainElements[i].imageView));
|
||||
|
||||
VkFramebufferCreateInfo framebufferCreateInfo = {};
|
||||
framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
framebufferCreateInfo.renderPass = renderPass;
|
||||
framebufferCreateInfo.attachmentCount = 1;
|
||||
framebufferCreateInfo.pAttachments = &swapchainElements[i].imageView;
|
||||
framebufferCreateInfo.width = width;
|
||||
framebufferCreateInfo.height = height;
|
||||
framebufferCreateInfo.layers = 1;
|
||||
VulkanDevice::CHECK_VK_RESULT(vkCreateFramebuffer(VulkanDevice::device, &framebufferCreateInfo, NULL, &swapchainElements[i].framebuffer));
|
||||
|
||||
VkSemaphoreCreateInfo startSemaphoreCreateInfo = {};
|
||||
startSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
VulkanDevice::CHECK_VK_RESULT(vkCreateSemaphore(VulkanDevice::device, &startSemaphoreCreateInfo, NULL, &swapchainElements[i].startSemaphore));
|
||||
|
||||
VkSemaphoreCreateInfo endSemaphoreCreateInfo = {};
|
||||
endSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
VulkanDevice::CHECK_VK_RESULT(vkCreateSemaphore(VulkanDevice::device, &endSemaphoreCreateInfo, NULL, &swapchainElements[i].endSemaphore));
|
||||
|
||||
VkFenceCreateInfo fenceCreateInfo = {};
|
||||
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
VulkanDevice::CHECK_VK_RESULT(vkCreateFence(VulkanDevice::device, &fenceCreateInfo, NULL, &swapchainElements[i].fence));
|
||||
|
||||
swapchainElements[i].lastFence = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowWaylandVulkan::DestroySwapchain()
|
||||
{
|
||||
for (uint32_t i = 0; i < imageCount; i++)
|
||||
{
|
||||
vkDestroyFence(VulkanDevice::device, swapchainElements[i].fence, NULL);
|
||||
vkDestroySemaphore(VulkanDevice::device, swapchainElements[i].endSemaphore, NULL);
|
||||
vkDestroySemaphore(VulkanDevice::device, swapchainElements[i].startSemaphore, NULL);
|
||||
vkDestroyFramebuffer(VulkanDevice::device, swapchainElements[i].framebuffer, NULL);
|
||||
vkDestroyImageView(VulkanDevice::device, swapchainElements[i].imageView, NULL);
|
||||
vkFreeCommandBuffers(VulkanDevice::device, VulkanDevice::commandPool, 1, &swapchainElements[i].commandBuffer);
|
||||
}
|
||||
|
||||
vkDestroyRenderPass(VulkanDevice::device, renderPass, NULL);
|
||||
vkDestroySwapchainKHR(VulkanDevice::device, swapchain, NULL);
|
||||
}
|
||||
|
||||
PFN_vkCmdDrawMeshTasksEXT command;
|
||||
|
||||
WindowWaylandVulkan::WindowWaylandVulkan(std::string name, std::uint32_t width, std::uint32_t height) : WindowWayland(name, width, height) {
|
||||
VkWaylandSurfaceCreateInfoKHR createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
|
||||
createInfo.display = display;
|
||||
createInfo.surface = surface;
|
||||
VulkanDevice::CHECK_VK_RESULT(vkCreateWaylandSurfaceKHR(VulkanDevice::instance, &createInfo, NULL, &vulkanSurface));
|
||||
CreateSwapchain();
|
||||
command = reinterpret_cast<PFN_vkCmdDrawMeshTasksEXT>(vkGetDeviceProcAddr(VulkanDevice::device, "vkCmdDrawMeshTasksEXT"));
|
||||
}
|
||||
|
||||
void WindowWaylandVulkan::Start() {
|
||||
thread = std::thread([this](){
|
||||
while (open && wl_display_dispatch(display) != -1) {
|
||||
|
||||
}
|
||||
});
|
||||
while(true) {
|
||||
SwapchainElement* currentElement = &swapchainElements[currentFrame];
|
||||
|
||||
VulkanDevice::CHECK_VK_RESULT(vkWaitForFences(VulkanDevice::device, 1, ¤tElement->fence, 1, UINT64_MAX));
|
||||
VulkanDevice::CHECK_VK_RESULT(vkAcquireNextImageKHR(VulkanDevice::device, swapchain, UINT64_MAX, currentElement->startSemaphore, NULL, &imageIndex));
|
||||
|
||||
SwapchainElement* element = &swapchainElements[imageIndex];
|
||||
if (element->lastFence) {
|
||||
VulkanDevice::CHECK_VK_RESULT(vkWaitForFences(VulkanDevice::device, 1, &element->lastFence, 1, UINT64_MAX));
|
||||
}
|
||||
|
||||
element->lastFence = currentElement->fence;
|
||||
|
||||
VulkanDevice::CHECK_VK_RESULT(vkResetFences(VulkanDevice::device, 1, ¤tElement->fence));
|
||||
|
||||
VkCommandBufferBeginInfo commandBeginInfo = {};
|
||||
commandBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
commandBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
|
||||
VulkanDevice::CHECK_VK_RESULT(vkBeginCommandBuffer(element->commandBuffer, &commandBeginInfo));
|
||||
|
||||
VkClearValue clearValue = {{
|
||||
1.0f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
1.0f
|
||||
}};
|
||||
|
||||
VkRenderPassBeginInfo renderBeginInfo = {};
|
||||
renderBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderBeginInfo.renderPass = renderPass;
|
||||
renderBeginInfo.framebuffer = element->framebuffer;
|
||||
renderBeginInfo.renderArea.offset.x = 0;
|
||||
renderBeginInfo.renderArea.offset.y = 0;
|
||||
renderBeginInfo.renderArea.extent.width = width;
|
||||
renderBeginInfo.renderArea.extent.height = height;
|
||||
renderBeginInfo.clearValueCount = 1;
|
||||
renderBeginInfo.pClearValues = &clearValue;
|
||||
|
||||
vkCmdBeginRenderPass(element->commandBuffer, &renderBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
VkViewport viewport = {0, 0, static_cast<float>(width), static_cast<float>(height), 0, 1};
|
||||
vkCmdSetViewport(element->commandBuffer, 0, 1, &viewport);
|
||||
|
||||
VkRect2D scissor = {{static_cast<std::int32_t>(width), static_cast<std::int32_t>(height)},{0,0}};
|
||||
vkCmdSetScissor(element->commandBuffer, 0, 1, &scissor);
|
||||
|
||||
vkCmdBindDescriptorSets(element->commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, VulkanPipeline<VulkanShader<"test.spirv", "main", VK_SHADER_STAGE_MESH_BIT_EXT>, VulkanShader<"test2.spirv", "main", VK_SHADER_STAGE_FRAGMENT_BIT>>::layout, 0, 1, &VulkanPipeline<VulkanShader<"test.spirv", "main", VK_SHADER_STAGE_MESH_BIT_EXT>, VulkanShader<"test2.spirv", "main", VK_SHADER_STAGE_FRAGMENT_BIT>>::descriptor_set, 0, nullptr);
|
||||
vkCmdBindPipeline(element->commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, VulkanPipeline<VulkanShader<"test.spirv", "main", VK_SHADER_STAGE_MESH_BIT_EXT>, VulkanShader<"test2.spirv", "main", VK_SHADER_STAGE_FRAGMENT_BIT>>::pipeline);
|
||||
|
||||
command(element->commandBuffer, 1, 1, 1);
|
||||
|
||||
vkCmdEndRenderPass(element->commandBuffer);
|
||||
|
||||
VulkanDevice::CHECK_VK_RESULT(vkEndCommandBuffer(element->commandBuffer));
|
||||
|
||||
const VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
|
||||
VkSubmitInfo submitInfo = {};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submitInfo.waitSemaphoreCount = 1;
|
||||
submitInfo.pWaitSemaphores = ¤tElement->startSemaphore;
|
||||
submitInfo.pWaitDstStageMask = &waitStage;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &element->commandBuffer;
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = ¤tElement->endSemaphore;
|
||||
|
||||
VulkanDevice::CHECK_VK_RESULT(vkQueueSubmit(VulkanDevice::queue, 1, &submitInfo, currentElement->fence));
|
||||
|
||||
VkPresentInfoKHR presentInfo = {};
|
||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
presentInfo.waitSemaphoreCount = 1;
|
||||
presentInfo.pWaitSemaphores = ¤tElement->endSemaphore;
|
||||
presentInfo.swapchainCount = 1;
|
||||
presentInfo.pSwapchains = &swapchain;
|
||||
presentInfo.pImageIndices = &imageIndex;
|
||||
|
||||
VulkanDevice::CHECK_VK_RESULT(vkQueuePresentKHR(VulkanDevice::queue, &presentInfo));
|
||||
|
||||
currentFrame = (currentFrame + 1) % imageCount;
|
||||
|
||||
wl_display_roundtrip(display);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue