From c6e198f2fda6afee28022b4d2a4e2b435337d290 Mon Sep 17 00:00:00 2001 From: s-ol Date: Sun, 21 Mar 2021 17:05:46 +0100 Subject: Enable VulkanLogicalDevice with external devices --- .../VulkanUtilities/VulkanLogicalDevice.hpp | 16 ++-- .../interface/EngineFactoryVk.h | 17 ++-- .../GraphicsEngineVulkan/src/EngineFactoryVk.cpp | 90 ++++++++++++++++++---- .../src/VulkanUtilities/VulkanLogicalDevice.cpp | 26 ++++--- 4 files changed, 106 insertions(+), 43 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp index 34639140..b2b6a08a 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp @@ -95,10 +95,10 @@ public: const ExtensionFeatures& EnabledExtFeatures, const VkAllocationCallbacks* vkAllocator); - static std::shared_ptr Create(const VulkanPhysicalDevice& PhysicalDevice, - const VkDevice& Device, - VkPipelineStageFlags EnabledShaderStages, - const VkAllocationCallbacks* vkAllocator); + static std::shared_ptr Create(const VulkanPhysicalDevice& PhysicalDevice, + const VkDevice& Device, + const VkPhysicalDeviceFeatures& EnabledFeatures, + const VkAllocationCallbacks* vkAllocator); // clang-format off VulkanLogicalDevice (const VulkanLogicalDevice&) = delete; @@ -236,10 +236,10 @@ private: const VkDeviceCreateInfo& DeviceCI, const ExtensionFeatures& EnabledExtFeatures, const VkAllocationCallbacks* vkAllocator); - VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDevice, - const VkDevice& Device, - VkPipelineStageFlags EnabledShaderStages, - const VkAllocationCallbacks* vkAllocator); + VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDevice, + const VkDevice& Device, + const VkPhysicalDeviceFeatures& EnabledFeatures, + const VkAllocationCallbacks* vkAllocator); template (EngineCI.pVkAllocator)); + auto vkAllocator = Instance->GetVkAllocator(); + + auto PhysicalDevice = VulkanUtilities::VulkanPhysicalDevice::Create(VkPhysicalDevice, *Instance); + auto LogicalDevice = VulkanUtilities::VulkanLogicalDevice::Create(*PhysicalDevice, VkLogicalDevice, PhysicalDeviceFeatures, vkAllocator); + + auto GetFeatureState = [](DEVICE_FEATURE_STATE RequestedState, bool IsFeatureSupported, const char* FeatureName) + { + switch (RequestedState) + { + case DEVICE_FEATURE_STATE_DISABLED: + return DEVICE_FEATURE_STATE_DISABLED; + + case DEVICE_FEATURE_STATE_ENABLED: + { + if (IsFeatureSupported) + return DEVICE_FEATURE_STATE_ENABLED; + else + LOG_ERROR_AND_THROW(FeatureName, " not supported by this device"); + } + + case DEVICE_FEATURE_STATE_OPTIONAL: + return IsFeatureSupported ? DEVICE_FEATURE_STATE_ENABLED : DEVICE_FEATURE_STATE_DISABLED; + + default: + UNEXPECTED("Unexpected feature state"); + return DEVICE_FEATURE_STATE_DISABLED; + } + }; + +#define ENABLE_FEATURE(vkFeature, State, FeatureName) \ + do \ + { \ + State = \ + GetFeatureState(State, PhysicalDeviceFeatures.vkFeature != VK_FALSE, FeatureName); \ + } while (false) + auto ImageCubeArrayFeature = DEVICE_FEATURE_STATE_OPTIONAL; + auto SamplerAnisotropyFeature = DEVICE_FEATURE_STATE_OPTIONAL; + // clang-format off + ENABLE_FEATURE(geometryShader, EngineCI.Features.GeometryShaders, "Geometry shaders are"); + ENABLE_FEATURE(tessellationShader, EngineCI.Features.Tessellation, "Tessellation is"); + ENABLE_FEATURE(pipelineStatisticsQuery, EngineCI.Features.PipelineStatisticsQueries, "Pipeline statistics queries are"); + ENABLE_FEATURE(occlusionQueryPrecise, EngineCI.Features.OcclusionQueries, "Occlusion queries are"); + ENABLE_FEATURE(imageCubeArray, ImageCubeArrayFeature, "Image cube arrays are"); + ENABLE_FEATURE(fillModeNonSolid, EngineCI.Features.WireframeFill, "Wireframe fill is"); + ENABLE_FEATURE(samplerAnisotropy, SamplerAnisotropyFeature, "Anisotropic texture filtering is"); + ENABLE_FEATURE(depthBiasClamp, EngineCI.Features.DepthBiasClamp, "Depth bias clamp is"); + ENABLE_FEATURE(depthClamp, EngineCI.Features.DepthClamp, "Depth clamp is"); + ENABLE_FEATURE(independentBlend, EngineCI.Features.IndependentBlend, "Independent blend is"); + ENABLE_FEATURE(dualSrcBlend, EngineCI.Features.DualSourceBlend, "Dual-source blend is"); + ENABLE_FEATURE(multiViewport, EngineCI.Features.MultiViewport, "Multiviewport is"); + ENABLE_FEATURE(textureCompressionBC, EngineCI.Features.TextureCompressionBC, "BC texture compression is"); + ENABLE_FEATURE(vertexPipelineStoresAndAtomics, EngineCI.Features.VertexPipelineUAVWritesAndAtomics, "Vertex pipeline UAV writes and atomics are"); + ENABLE_FEATURE(fragmentStoresAndAtomics, EngineCI.Features.PixelUAVWritesAndAtomics, "Pixel UAV writes and atomics are"); + ENABLE_FEATURE(shaderStorageImageExtendedFormats, EngineCI.Features.TextureUAVExtendedFormats, "Texture UAV extended formats are"); + // clang-format on +#undef ENABLE_FEATURE - VkPipelineStageFlags PipelineStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT; - auto VulkanLogicalDevice = VulkanUtilities::VulkanLogicalDevice::Create(*VulkanPhysicalDevice, LogicalDevice, PipelineStages, nullptr); RefCntAutoPtr pCmdQueueVk{ - NEW_RC_OBJ(RawMemAllocator, "CommandQueueVk instance", CommandQueueVkImpl)(VulkanLogicalDevice, Queue, QueueFamilyIndex)}; + NEW_RC_OBJ(RawMemAllocator, "CommandQueueVk instance", CommandQueueVkImpl)(LogicalDevice, Queue, QueueFamilyIndex)}; std::array CommandQueues = {{pCmdQueueVk}}; OnRenderDeviceCreated = [&](RenderDeviceVkImpl* pRenderDeviceVk) @@ -575,9 +633,9 @@ void EngineFactoryVkImpl::AttachToVulkanDevice(const VkInstance& Instanc }; AttachToVulkanDevice( - VulkanInstance, - std::move(VulkanPhysicalDevice), - VulkanLogicalDevice, + Instance, + std::move(PhysicalDevice), + LogicalDevice, CommandQueues.size(), CommandQueues.data(), EngineCI, ppDevice, diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp index b9d986fa..e3faa434 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp @@ -43,12 +43,12 @@ std::shared_ptr VulkanLogicalDevice::Create(const VulkanPhy return std::shared_ptr{LogicalDevice}; } -std::shared_ptr VulkanLogicalDevice::Create(const VulkanPhysicalDevice& PhysicalDevice, - const VkDevice& Device, - VkPipelineStageFlags EnabledShaderStages, - const VkAllocationCallbacks* vkAllocator) +std::shared_ptr VulkanLogicalDevice::Create(const VulkanPhysicalDevice& PhysicalDevice, + const VkDevice& Device, + const VkPhysicalDeviceFeatures& EnabledFeatures, + const VkAllocationCallbacks* vkAllocator) { - auto* LogicalDevice = new VulkanLogicalDevice{PhysicalDevice, Device, EnabledShaderStages, vkAllocator}; + auto* LogicalDevice = new VulkanLogicalDevice{PhysicalDevice, Device, EnabledFeatures, vkAllocator}; return std::shared_ptr{LogicalDevice}; } @@ -85,14 +85,13 @@ VulkanLogicalDevice::VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDe m_EnabledShaderStages |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR; } -VulkanLogicalDevice::VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDevice, - const VkDevice& Device, - VkPipelineStageFlags EnabledShaderStages, - const VkAllocationCallbacks* vkAllocator) : +VulkanLogicalDevice::VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDevice, + const VkDevice& Device, + const VkPhysicalDeviceFeatures& EnabledFeatures, + const VkAllocationCallbacks* vkAllocator) : m_VkDevice{Device}, m_VkAllocator{vkAllocator}, - m_EnabledShaderStages{EnabledShaderStages}, - m_EnabledFeatures{}, + m_EnabledFeatures{EnabledFeatures}, m_EnabledExtFeatures{} { #if DILIGENT_USE_VOLK @@ -100,6 +99,11 @@ VulkanLogicalDevice::VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDe // https://github.com/zeux/volk#optimizing-device-calls volkLoadDevice(m_VkDevice); #endif + m_EnabledShaderStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + if (EnabledFeatures.geometryShader) + m_EnabledShaderStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT; + if (EnabledFeatures.tessellationShader) + m_EnabledShaderStages |= VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT; } -- cgit v1.2.3