From 74275292bf81b200aa5251c195870474acf8b353 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 5 Mar 2020 17:24:55 +0100 Subject: [PATCH] Some cleanup --- examples/VulkanTest/main.cpp | 23 ------------ include/Nazara/Renderer/Enums.hpp | 53 +++++++++++++++++++--------- src/Nazara/VulkanRenderer/Vulkan.cpp | 30 ++++++++++++---- 3 files changed, 61 insertions(+), 45 deletions(-) diff --git a/examples/VulkanTest/main.cpp b/examples/VulkanTest/main.cpp index 617584ffd..a60dd2f07 100644 --- a/examples/VulkanTest/main.cpp +++ b/examples/VulkanTest/main.cpp @@ -301,29 +301,9 @@ int main() clearValues.data() // const VkClearValue *pClearValues }; - VkClearAttachment clearAttachment = { - VK_IMAGE_ASPECT_COLOR_BIT, - 0U, - clearValues[0] - }; - - VkClearAttachment clearAttachmentDepth = { - VK_IMAGE_ASPECT_DEPTH_BIT, - 0U, - clearValues[1] - }; - - VkClearRect clearRect = { - renderArea, - 0U, - 1U - }; - renderCmd.Begin(); renderCmd.BeginRenderPass(render_pass_begin_info); - //renderCmd.ClearAttachment(clearAttachment, clearRect); - //renderCmd.ClearAttachment(clearAttachmentDepth, clearRect); renderCmd.BindIndexBuffer(indexBufferImpl->GetBufferHandle(), 0, VK_INDEX_TYPE_UINT16); renderCmd.BindVertexBuffer(0, vertexBufferImpl->GetBufferHandle(), 0); renderCmd.BindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, descriptorSet); @@ -365,9 +345,6 @@ int main() syncData.inflightFence.Create(vulkanDevice.shared_from_this(), VK_FENCE_CREATE_SIGNALED_BIT); } - /*std::vector> imageFences; - for (std::size_t i = 0; i < imageCount; ++i) - imageFences.emplace_back(sync[i % sync.size()].inflightFence);*/ std::vector inflightFences(imageCount, nullptr); std::size_t currentFrame = 0; diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index 3ea481e17..9a18d8dbf 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -7,31 +7,41 @@ #ifndef NAZARA_ENUMS_RENDERER_HPP #define NAZARA_ENUMS_RENDERER_HPP +#include + namespace Nz { - enum RenderAPI + enum class RenderAPI { - RenderAPI_Direct3D, ///< Microsoft Render API, only works on MS platforms - RenderAPI_Mantle, ///< AMD Render API, Vulkan predecessor, only works on AMD GPUs - RenderAPI_Metal, ///< Apple Render API, only works on OS X platforms - RenderAPI_OpenGL, ///< Khronos Render API, works on Web/Desktop/Mobile and some consoles - RenderAPI_Vulkan, ///< New Khronos Render API, made to replace OpenGL, works on desktop (Windows/Linux) and mobile (Android) + Direct3D, ///< Microsoft Render API, only works on MS platforms + Mantle, ///< AMD Render API, Vulkan predecessor, only works on AMD GPUs + Metal, ///< Apple Render API, only works on OS X platforms + OpenGL, ///< Khronos Render API, works on Web/Desktop/Mobile and some consoles + Vulkan, ///< New Khronos Render API, made to replace OpenGL, works on desktop (Windows/Linux) and mobile (Android), and Apple platform using MoltenVK - RenderAPI_Other, ///< RenderAPI not corresponding to an entry of the enum, or result of a failed query + Unknown, ///< RenderAPI not corresponding to an entry of the enum, or result of a failed query - RenderAPI_Max = RenderAPI_Other + Max = Unknown }; - enum RenderDeviceType + enum class RenderDeviceType { - RenderDeviceType_Integrated, ///< Hardware-accelerated chipset integrated to a CPU (ex: Intel Graphics HD 4000) - RenderDeviceType_Dedicated, ///< Hardware-accelerated GPU (ex: AMD R9 390) - RenderDeviceType_Software, ///< Software-renderer - RenderDeviceType_Virtual, ///< Proxy renderer relaying instructions to another unknown device + Integrated, ///< Hardware-accelerated chipset integrated to a CPU (ex: Intel Graphics HD 4000) + Dedicated, ///< Hardware-accelerated GPU (ex: AMD R9 390) + Software, ///< Software-renderer + Virtual, ///< Proxy renderer relaying instructions to another unknown device - RenderDeviceType_Unknown, ///< Device type not corresponding to an entry of the enum, or result of a failed query + Unknown, ///< Device type not corresponding to an entry of the enum, or result of a failed query - RenderDeviceType_Max = RenderDeviceType_Unknown + Max = Unknown + }; + + enum class ShaderBindingType + { + Texture, + UniformBuffer, + + Max = UniformBuffer }; enum class ShaderLanguage @@ -45,8 +55,19 @@ namespace Nz enum class ShaderStageType { Fragment, - Vertex + Vertex, + + Max = Vertex }; + + struct EnumAsFlags + { + static constexpr ShaderStageType max = ShaderStageType::Max; + }; + + using ShaderStageTypeFlags = Flags; + + constexpr ShaderStageTypeFlags ShaderStageType_All = ShaderStageType::Fragment | ShaderStageType::Vertex; } #endif // NAZARA_ENUMS_RENDERER_HPP diff --git a/src/Nazara/VulkanRenderer/Vulkan.cpp b/src/Nazara/VulkanRenderer/Vulkan.cpp index f45555110..c54a8a199 100644 --- a/src/Nazara/VulkanRenderer/Vulkan.cpp +++ b/src/Nazara/VulkanRenderer/Vulkan.cpp @@ -274,7 +274,7 @@ namespace Nz // Find a queue that supports graphics operations UInt32 graphicsQueueNodeIndex = UINT32_MAX; UInt32 presentQueueNodeIndex = UINT32_MAX; - UInt32 transfertQueueNodeFamily = UINT32_MAX; + UInt32 transferQueueNodeFamily = UINT32_MAX; for (UInt32 i = 0; i < queueFamilies.size(); i++) { bool supportPresentation = false; @@ -285,6 +285,7 @@ namespace Nz { if (supportPresentation) { + // Queue family support both graphics and presentation to our surface, choose it graphicsQueueNodeIndex = i; presentQueueNodeIndex = i; break; @@ -296,21 +297,38 @@ namespace Nz presentQueueNodeIndex = i; } + if (graphicsQueueNodeIndex == UINT32_MAX) + { + // A Vulkan device without graphics support may technically exists but I've yet to see one + NazaraError("Device does not support graphics operations"); + return {}; + } + + if (presentQueueNodeIndex == UINT32_MAX) + { + // On multi-GPU systems, it's very possible to have surfaces unsupported by some + NazaraError("Device cannot present this surface"); + return {}; + } + + // Search for a transfer queue (first one being different to the graphics one) for (UInt32 i = 0; i < queueFamilies.size(); i++) { - if (queueFamilies[i].queueFlags & (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_TRANSFER_BIT)) //< Compute and graphics queue implicitly support transfer operations + // Transfer bit is not mandatory if compute and graphics bits are set (as they implicitly support transfer) + if (queueFamilies[i].queueFlags & (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_TRANSFER_BIT)) { - transfertQueueNodeFamily = i; - if (transfertQueueNodeFamily != graphicsQueueNodeIndex) + transferQueueNodeFamily = i; + if (transferQueueNodeFamily != graphicsQueueNodeIndex) break; } } + assert(transferQueueNodeFamily != UINT32_MAX); std::array queuesFamilies = { { {graphicsQueueNodeIndex, 1.f}, {presentQueueNodeIndex, 1.f}, - {transfertQueueNodeFamily, 1.f} + {transferQueueNodeFamily, 1.f} } }; @@ -456,7 +474,7 @@ namespace Nz { const std::vector& queueFamilyInfo = devicePtr->GetEnabledQueues(); UInt32 presentableQueueFamilyIndex = UINT32_MAX; - for (Vk::Device::QueueFamilyInfo queueInfo : queueFamilyInfo) + for (const Vk::Device::QueueFamilyInfo& queueInfo : queueFamilyInfo) { bool supported = false; if (surface.GetSupportPresentation(gpu, queueInfo.familyIndex, &supported) && supported)