From ab404bf672bb4b974bc397fe6689f84f5c17903b Mon Sep 17 00:00:00 2001 From: kotofyt Date: Sat, 6 Sep 2025 21:38:01 +0300 Subject: [PATCH] Vulkan stuff --- engine/engine.cpp | 5 +- materialsystem/vulkan/rendercontext.cpp | 392 +++++++++++++++++++++--- public/materialsystem/materialsystem.h | 20 +- 3 files changed, 375 insertions(+), 42 deletions(-) diff --git a/engine/engine.cpp b/engine/engine.cpp index 4ca6efe..22867e6 100644 --- a/engine/engine.cpp +++ b/engine/engine.cpp @@ -14,14 +14,13 @@ extern "C" void FunnyMain( int argc, char **argv ) filesystem->Init(); gamewindow->Init(); + Materials()->Init(); ServerGameDLL()->Init(); - Materials()->Init(); - - for (;;) { gamewindow->UpdateWindow(); + Materials()->Frame(0); }; }; diff --git a/materialsystem/vulkan/rendercontext.cpp b/materialsystem/vulkan/rendercontext.cpp index 819055b..57f3889 100644 --- a/materialsystem/vulkan/rendercontext.cpp +++ b/materialsystem/vulkan/rendercontext.cpp @@ -21,6 +21,229 @@ const char *g_vkDeviceExtensions[] = { SupportedVulkanExtensions_t g_vkAvailableExtensions; +uint32_t g_iDrawFamily; +uint32_t g_iPresentFamily; + +VkQueue g_vkDrawQueue; +VkQueue g_vkPresentQueue; + +VkInstance g_vkInstance; +VkPhysicalDevice g_vkPhysicalDevice; +VkDevice g_vkDevice; +VkSwapchainKHR g_vkSwapchain; + +CUtlVector g_vkFences; +CUtlVector g_vkGraphicsSemaphores; +CUtlVector g_vkPresentSemaphores; + +VkCommandPool g_vkCommandPool; +CUtlVector g_vkCommandBuffers; + +CUtlVector g_vkSwapchainImages; +VkFormat g_vkWindowImageFormat; + +class CVkImage: public IImage +{ +public: + CVkImage(); + CVkImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType ); + ~CVkImage(); + + virtual void SetDebugName( const char *szName ) override; + virtual uint32_t GetImageWidth() override; + virtual uint32_t GetImageHeight() override; + virtual EImageFormat GetImageFormat() override; + virtual EMultisampleType GetMultisampleType() override; + + void CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType ); + void CreateImageView(); + + static VkImageViewType GetImageViewType( enum EImageType eImageType ); + static VkFormat GetImageFormat( enum EImageFormat eImageFormat ); + + uint32_t m_nWidth; + uint32_t m_nHeight; + EImageFormat m_eFormat; + EMultisampleType m_eMultisampleType; + EImageType m_eImageType; + + VkImage m_image; + VkImageView m_imageView; + VmaAllocation m_allocation; +}; + +CVkImage::CVkImage() +{ + +} + +CVkImage::CVkImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType) +{ + CreateImage(nWidth, nHeight, eFormat, eMultisampleType); + CreateImageView(); +} + +CVkImage::~CVkImage() +{ + +} + +VkImageViewType CVkImage::GetImageViewType( enum EImageType eImageType ) +{ + switch ( eImageType ) + { + case IMAGE_TYPE_1D: + return VK_IMAGE_VIEW_TYPE_1D; + case IMAGE_TYPE_2D: + return VK_IMAGE_VIEW_TYPE_2D; + case IMAGE_TYPE_3D: + return VK_IMAGE_VIEW_TYPE_3D; + case IMAGE_TYPE_CUBE: + return VK_IMAGE_VIEW_TYPE_CUBE; + case IMAGE_TYPE_1D_ARRAY: + return VK_IMAGE_VIEW_TYPE_1D_ARRAY; + case IMAGE_TYPE_2D_ARRAY: + return VK_IMAGE_VIEW_TYPE_2D_ARRAY; + case IMAGE_TYPE_CUBE_ARRAY: + return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; + } +} + +VkFormat CVkImage::GetImageFormat( enum EImageFormat eImageFormat ) +{ + switch ( eImageFormat ) + { + case IMAGE_FORMAT_R8_UINT: + return VK_FORMAT_R8_UINT; + case IMAGE_FORMAT_RGBA8_UNORM: + return VK_FORMAT_R8G8B8A8_UNORM; + case IMAGE_FORMAT_BGRA8_UNORM: + return VK_FORMAT_B8G8R8A8_UNORM; + case IMAGE_FORMAT_RGBA8_UINT: + return VK_FORMAT_R8G8B8A8_UINT; + case IMAGE_FORMAT_RGBA8_SINT: + return VK_FORMAT_R8G8B8A8_SINT; + case IMAGE_FORMAT_RGBA16_SFLOAT: + return VK_FORMAT_R16G16B16A16_SFLOAT; + case IMAGE_FORMAT_RGBA32_SFLOAT: + return VK_FORMAT_R32G32B32A32_SFLOAT; + case IMAGE_FORMAT_D32_SFLOAT: + return VK_FORMAT_D32_SFLOAT; + case IMAGE_FORMAT_WINDOW: + return g_vkWindowImageFormat; + } +} + +void CVkImage::CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType ) +{ + +} + +void CVkImage::CreateImageView() +{ + VkImageViewCreateInfo stImageViewCreateInfo = {}; + VkImageViewType eImageViewType; + + stImageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + stImageViewCreateInfo.image = m_image; + stImageViewCreateInfo.viewType = GetImageViewType(m_eImageType); + stImageViewCreateInfo.format = GetImageFormat(m_eFormat); + if (m_eFormat == IMAGE_FORMAT_D32_SFLOAT) + stImageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + else + stImageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + stImageViewCreateInfo.subresourceRange.layerCount = 1; + stImageViewCreateInfo.subresourceRange.levelCount = 1; + vkCreateImageView(g_vkDevice, &stImageViewCreateInfo, NULL, &m_imageView); +} +void CVkImage::SetDebugName( const char *szName ) +{ + +} + + +uint32_t CVkImage::GetImageWidth() +{ + return m_nWidth; +} + +uint32_t CVkImage::GetImageHeight() +{ + return m_nHeight; +} + +EImageFormat CVkImage::GetImageFormat() +{ + return m_eFormat; +} + +EMultisampleType CVkImage::GetMultisampleType() +{ + return m_eMultisampleType; +} + + +class CVkBuffer: public IBuffer +{ +public: + CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlignment ); + ~CVkBuffer(); + + virtual void SetDebugName( const char *szName ) override; + virtual void Lock() override; + virtual void Unlock() override; + virtual void *Map() override; + virtual void Unmap() override; + virtual uint32_t GetSize() override; + + VmaAllocation allocation; + VkBuffer buffer; + VkDeviceAddress address; + uint32_t nSize; +}; + +CVkBuffer::CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlignment ) +{ +} + +CVkBuffer::~CVkBuffer() +{ + +} + + +void CVkBuffer::SetDebugName( const char *szName ) +{ + +} + +void CVkBuffer::Lock() +{ + +} + +void CVkBuffer::Unlock() +{ + +} + +void *CVkBuffer::Map() +{ + +} + +void CVkBuffer::Unmap() +{ + +} + +uint32_t CVkBuffer::GetSize() +{ + +} + + + class CVkRenderContext: public IRenderContext { public: @@ -35,17 +258,23 @@ public: virtual void DestroyBuffer( IBuffer *pBuffer ) override; virtual void DestroyImage( IImage *pImage ) override; -private: + IBuffer *CreateBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage ); IBuffer *CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsageFlags2 eUsage ); +private: VkPhysicalDevice SelectPhysicalDevice( CUtlVector physicalDevices ); CUtlVector GetDeviceExtensions(); + VkCommandBuffer GetCommandBuffer(); + void CreateSwapchain(); void DestroySwapchain(); }; +CVkRenderContext s_vkRenderContext; +IRenderContext *g_pVkRenderContext = &s_vkRenderContext; + //----------------------------------------------------------------------------- // Creates vertex buffer. Wrapper over CreateBuffer //----------------------------------------------------------------------------- @@ -67,7 +296,8 @@ IIndexBuffer *CVkRenderContext::CreateIndexBuffer( uint32_t nSize ) //----------------------------------------------------------------------------- IBuffer *CreateBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage ) { - + CVkBuffer *pBuffer = new CVkBuffer(nSize, eUsage, 0); + return pBuffer; } //----------------------------------------------------------------------------- @@ -94,7 +324,7 @@ IImage *CVkRenderContext::CreateStorageImage( uint32_t x, uint32_t y, EImageForm void CVkRenderContext::DestroyBuffer( IBuffer *pBuffer ) { - + delete (CVkBuffer*)pBuffer; } void CVkRenderContext::DestroyImage( IImage *pImage ) @@ -102,19 +332,6 @@ void CVkRenderContext::DestroyImage( IImage *pImage ) } -CVkRenderContext s_vkRenderContext; -IRenderContext *g_pVkRenderContext = &s_vkRenderContext; - - -uint32_t g_iDrawFamily; -uint32_t g_iPresentFamily; - -VkInstance g_vkInstance; -VkPhysicalDevice g_vkPhysicalDevice; -VkDevice g_vkDevice; -VkSwapchainKHR g_vkSwapchain; - - void CVkRenderContext::Init() { VkResult r; @@ -195,7 +412,6 @@ void CVkRenderContext::Init() i++; } - // Create device stDeviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; stDeviceQueueCreateInfo.queueCount = 1; @@ -207,14 +423,73 @@ void CVkRenderContext::Init() stDeviceCreateInfo.pQueueCreateInfos = &stDeviceQueueCreateInfo; stDeviceCreateInfo.enabledExtensionCount = enabledDeviceExtensions.GetSize(); stDeviceCreateInfo.ppEnabledExtensionNames = enabledDeviceExtensions.GetData(); - vkCreateDevice(g_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &g_vkDevice); - + r = vkCreateDevice(g_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &g_vkDevice); + VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); + for (auto &extension: enabledDeviceExtensions) + V_printf("%s\n", extension); + vkGetDeviceQueue(g_vkDevice, g_iDrawFamily, 0, &g_vkDrawQueue); + vkGetDeviceQueue(g_vkDevice, g_iPresentFamily, 0, &g_vkPresentQueue); + CreateSwapchain(); + + g_vkCommandBuffers.Resize(g_vkSwapchainImages.GetSize()); + + VkCommandPoolCreateInfo commandPoolCreateInfo = {}; + commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + commandPoolCreateInfo.queueFamilyIndex = g_iDrawFamily; + commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + vkCreateCommandPool(g_vkDevice, &commandPoolCreateInfo, NULL, &g_vkCommandPool); + + VkCommandBufferAllocateInfo commandBufferAllocInfo = {}; + commandBufferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + commandBufferAllocInfo.commandPool = g_vkCommandPool; + commandBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + commandBufferAllocInfo.commandBufferCount = g_vkSwapchainImages.GetSize(); + vkAllocateCommandBuffers(g_vkDevice, &commandBufferAllocInfo, g_vkCommandBuffers.GetData()); + + } void CVkRenderContext::Frame( float fDeltaTime ) { + static uint32_t s_nImageIndex = 0; + uint32_t nImageIndex = 0; + vkWaitForFences(g_vkDevice, 1, &g_vkFences[s_nImageIndex], UINT64_MAX, VK_TRUE); + VkResult r = vkAcquireNextImageKHR(g_vkDevice, g_vkSwapchain, UINT64_MAX, g_vkGraphicsSemaphores[s_nImageIndex], NULL, &nImageIndex); + + VkCommandBufferBeginInfo commandBufferBeginInfo = {}; + commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + vkBeginCommandBuffer(GetCommandBuffer(), &commandBufferBeginInfo); + vkEndCommandBuffer(GetCommandBuffer()); + + vkResetFences(g_vkDevice, 1, &g_vkFences[s_nImageIndex]); + + VkCommandBuffer currentCommandBuffer = GetCommandBuffer(); + VkPipelineStageFlags uPipelineStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + VkSubmitInfo stSubmitInfo = {}; + stSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + stSubmitInfo.waitSemaphoreCount = 1; + stSubmitInfo.pWaitSemaphores = &g_vkGraphicsSemaphores[s_nImageIndex]; + stSubmitInfo.pWaitDstStageMask = &uPipelineStageFlags; + stSubmitInfo.commandBufferCount = 1; + stSubmitInfo.pCommandBuffers = ¤tCommandBuffer; + stSubmitInfo.signalSemaphoreCount = 1; + stSubmitInfo.pSignalSemaphores = &g_vkPresentSemaphores[nImageIndex]; + + vkQueueSubmit(g_vkDrawQueue, 1, &stSubmitInfo, g_vkFences[s_nImageIndex]); + + VkPresentInfoKHR stPresentInfo = {}; + stPresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + stPresentInfo.waitSemaphoreCount = 1; + stPresentInfo.pWaitSemaphores = &g_vkPresentSemaphores[nImageIndex]; + stPresentInfo.swapchainCount = 1; + stPresentInfo.pSwapchains = &g_vkSwapchain; + stPresentInfo.pImageIndices = &nImageIndex; + + vkQueuePresentKHR(g_vkPresentQueue, &stPresentInfo); + + s_nImageIndex = (s_nImageIndex + 1) % g_vkSwapchainImages.GetSize(); } void CVkRenderContext::CreateSwapchain() @@ -227,21 +502,30 @@ void CVkRenderContext::CreateSwapchain() uint32_t nSurfacePresentModes = 0; CUtlVector surfacePresentModes; + const VkFormat preferedSurfaceFormats[] = { + VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_R8G8B8A8_UNORM, + }; + VkSurfaceFormatKHR stSelectedFormat; + + VkSwapchainCreateInfoKHR stSwapchainCreateInfo = {}; + VkFenceCreateInfo stFenceCreateInfo = {}; + VkSemaphoreCreateInfo stSemaphoreCreateInfo = {}; + + uint32_t nSwapchainImages; + CUtlVector swapchainImages; + gamewindow->CreateVulkanSurface(g_vkInstance); vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vkPhysicalDevice, (VkSurfaceKHR)gamewindow->GetVulkanSurface(), &surfaceCapatibilities); - const VkFormat preferedSurfaceFormats[] = { - VK_FORMAT_B8G8R8A8_UNORM, - VK_FORMAT_R8G8B8A8_UNORM, - }; vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, (VkSurfaceKHR)gamewindow->GetVulkanSurface(), &numSurfaceFormats, NULL); surfaceFormats.Resize(numSurfaceFormats); vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, (VkSurfaceKHR)gamewindow->GetVulkanSurface(), &numSurfaceFormats, surfaceFormats.GetData()); - VkSurfaceFormatKHR selectedFormat = surfaceFormats[0]; + stSelectedFormat = surfaceFormats[0]; for (auto &format: surfaceFormats) { @@ -249,7 +533,7 @@ void CVkRenderContext::CreateSwapchain() { if (format.format == preferedSurfaceFormats[i]) { - selectedFormat = format; + stSelectedFormat = format; goto formatPicked; } } @@ -260,20 +544,48 @@ formatPicked: surfacePresentModes.Resize(nSurfacePresentModes); vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, (VkSurfaceKHR)gamewindow->GetVulkanSurface(), &nSurfacePresentModes, surfacePresentModes.GetData()); - VkSwapchainCreateInfoKHR swapchainCreateInfo = {}; - swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - swapchainCreateInfo.surface = (VkSurfaceKHR)gamewindow->GetVulkanSurface(); - swapchainCreateInfo.imageFormat = selectedFormat.format; - swapchainCreateInfo.imageColorSpace = selectedFormat.colorSpace; - swapchainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; - swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; - swapchainCreateInfo.preTransform = surfaceCapatibilities.currentTransform; - swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - swapchainCreateInfo.imageArrayLayers = 1; - swapchainCreateInfo.imageExtent = surfaceCapatibilities.minImageExtent; - swapchainCreateInfo.minImageCount = surfaceCapatibilities.minImageCount; - vkCreateSwapchainKHR(g_vkDevice, &swapchainCreateInfo, NULL, &g_vkSwapchain); + stSwapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + stSwapchainCreateInfo.surface = (VkSurfaceKHR)gamewindow->GetVulkanSurface(); + stSwapchainCreateInfo.imageFormat = stSelectedFormat.format; + stSwapchainCreateInfo.imageColorSpace = stSelectedFormat.colorSpace; + stSwapchainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + stSwapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + stSwapchainCreateInfo.preTransform = surfaceCapatibilities.currentTransform; + stSwapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + stSwapchainCreateInfo.imageArrayLayers = 1; + stSwapchainCreateInfo.imageExtent = surfaceCapatibilities.minImageExtent; + stSwapchainCreateInfo.minImageCount = surfaceCapatibilities.minImageCount; + vkCreateSwapchainKHR(g_vkDevice, &stSwapchainCreateInfo, NULL, &g_vkSwapchain); + g_vkWindowImageFormat = stSwapchainCreateInfo.imageFormat; + + vkGetSwapchainImagesKHR(g_vkDevice, g_vkSwapchain, &nSwapchainImages, NULL); + g_vkSwapchainImages.Resize(nSwapchainImages); + swapchainImages.Resize(nSwapchainImages); + g_vkFences.Resize(nSwapchainImages); + g_vkGraphicsSemaphores.Resize(nSwapchainImages); + g_vkPresentSemaphores.Resize(nSwapchainImages); + vkGetSwapchainImagesKHR(g_vkDevice, g_vkSwapchain, &nSwapchainImages, swapchainImages.GetData()); + + for ( int i = 0; i < swapchainImages.GetSize(); i++ ) + { + CVkImage *pImage; + pImage = new CVkImage; + pImage->m_image = swapchainImages[i]; + pImage->m_eImageType = IMAGE_TYPE_2D; + pImage->m_eMultisampleType = MULTISAMPLE_TYPE_NONE; + pImage->m_eFormat = IMAGE_FORMAT_WINDOW; + pImage->CreateImageView(); + g_vkSwapchainImages[i] = pImage; + + stFenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + stFenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; + vkCreateFence(g_vkDevice, &stFenceCreateInfo, NULL, &g_vkFences[i]); + + stSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + vkCreateSemaphore(g_vkDevice, &stSemaphoreCreateInfo, NULL, &g_vkGraphicsSemaphores[i]); + vkCreateSemaphore(g_vkDevice, &stSemaphoreCreateInfo, NULL, &g_vkPresentSemaphores[i]); + } } @@ -370,3 +682,7 @@ CUtlVector CVkRenderContext::GetDeviceExtensions() return enabledExtensions; } +VkCommandBuffer CVkRenderContext::GetCommandBuffer() +{ + return g_vkCommandBuffers[0]; +} diff --git a/public/materialsystem/materialsystem.h b/public/materialsystem/materialsystem.h index 049965e..7988d2e 100644 --- a/public/materialsystem/materialsystem.h +++ b/public/materialsystem/materialsystem.h @@ -18,6 +18,8 @@ public: virtual void Unlock() = 0; virtual void *Map() = 0; virtual void Unmap() = 0; + + virtual uint32_t GetSize() = 0; }; abstract_class IVertexBuffer : public IBuffer @@ -48,6 +50,19 @@ enum EImageFormat IMAGE_FORMAT_RGBA32_SFLOAT, IMAGE_FORMAT_D32_SFLOAT, + + IMAGE_FORMAT_WINDOW, +}; + +enum EImageType +{ + IMAGE_TYPE_1D, + IMAGE_TYPE_2D, + IMAGE_TYPE_3D, + IMAGE_TYPE_CUBE, + IMAGE_TYPE_1D_ARRAY, + IMAGE_TYPE_2D_ARRAY, + IMAGE_TYPE_CUBE_ARRAY, }; enum EMultisampleType @@ -61,7 +76,10 @@ enum EMultisampleType abstract_class IImage : public IRenderingObject { public: - + virtual uint32_t GetImageWidth() = 0; + virtual uint32_t GetImageHeight() = 0; + virtual EImageFormat GetImageFormat() = 0; + virtual EMultisampleType GetMultisampleType() = 0; }; abstract_class IRenderContext: public IAppSystem {