summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2020-08-11 19:48:23 +0000
committerazhirnov <zh1dron@gmail.com>2020-08-11 19:49:36 +0000
commitdc9a4e784c8bb97fbb16a01624c7b8f0544977a4 (patch)
treeb4a07f6e2029ca9d20999acfd940ea8e2556cb9d /Graphics/GraphicsEngineVulkan
parentBash function for format validation in submodules (#155) (diff)
downloadDiligentCore-dc9a4e784c8bb97fbb16a01624c7b8f0544977a4.tar.gz
DiligentCore-dc9a4e784c8bb97fbb16a01624c7b8f0544977a4.zip
Added mesh shader
added mesh shader support to DX12 and Vulkan, added DXIL compiler for Shader Model 6.x
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp4
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp26
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp24
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp31
-rw-r--r--Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp22
-rw-r--r--Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp16
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp22
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp4
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp21
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp31
13 files changed, 179 insertions, 28 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
index 83e2c077..4dd6ae1e 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
@@ -142,6 +142,10 @@ public:
virtual void DILIGENT_CALL_TYPE DrawIndirect (const DrawIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final;
/// Implementation of IDeviceContext::DrawIndexedIndirect() in Vulkan backend.
virtual void DILIGENT_CALL_TYPE DrawIndexedIndirect(const DrawIndexedIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final;
+ /// Implementation of IDeviceContext::DrawMesh() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE DrawMesh (const DrawMeshAttribs& Attribs) override final;
+ /// Implementation of IDeviceContext::DrawMeshIndirect() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE DrawMeshIndirect (const DrawMeshIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final;
/// Implementation of IDeviceContext::DispatchCompute() in Vulkan backend.
virtual void DILIGENT_CALL_TYPE DispatchCompute (const DispatchComputeAttribs& Attribs) override final;
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
index aca69cac..01f37a76 100644
--- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
@@ -156,7 +156,7 @@ private:
VulkanUtilities::PipelineWrapper m_Pipeline;
PipelineLayout m_PipelineLayout;
- Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1};
+ std::array<Int8, 8> m_ResourceLayoutIndex;
bool m_HasStaticResources = false;
bool m_HasNonStaticResources = false;
};
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp
index 1465024b..5e4f5062 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp
@@ -138,6 +138,32 @@ public:
vkCmdDrawIndexedIndirect(m_VkCmdBuffer, Buffer, Offset, DrawCount, Stride);
}
+ __forceinline void DrawMesh(uint32_t TaskCount, uint32_t FirstTask)
+ {
+#ifdef VK_NV_mesh_shader
+ VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
+ VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawMeshTasksNV() must be called inside render pass (19.3)");
+ VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound");
+
+ vkCmdDrawMeshTasksNV(m_VkCmdBuffer, TaskCount, FirstTask);
+#else
+ UNSUPPORTED("DrawMesh is not supported in current Vulkan headers");
+#endif
+ }
+
+ __forceinline void DrawMeshIndirect(VkBuffer Buffer, VkDeviceSize Offset, uint32_t DrawCount, uint32_t Stride)
+ {
+#ifdef VK_NV_mesh_shader
+ VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
+ VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawMeshTasksNV() must be called inside render pass (19.3)");
+ VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound");
+
+ vkCmdDrawMeshTasksIndirectNV(m_VkCmdBuffer, Buffer, Offset, DrawCount, Stride);
+#else
+ UNSUPPORTED("DrawMeshIndirect is not supported in current Vulkan headers");
+#endif
+ }
+
__forceinline void Dispatch(uint32_t GroupCountX, uint32_t GroupCountY, uint32_t GroupCountZ)
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp
index 3fcb736d..0ca092c6 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp
@@ -63,6 +63,7 @@ public:
// clang-format off
bool IsLayerAvailable (const char* LayerName) const;
bool IsExtensionAvailable(const char* ExtensionName)const;
+ bool IsExtensionEnabled (const char* ExtensionName)const;
VkPhysicalDevice SelectPhysicalDevice()const;
@@ -82,6 +83,7 @@ private:
std::vector<VkLayerProperties> m_Layers;
std::vector<VkExtensionProperties> m_Extensions;
+ std::vector<const char*> m_EnabledExtensions;
std::vector<VkPhysicalDevice> m_PhysicalDevices;
};
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
index 24212950..17bc2e4a 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
@@ -29,7 +29,7 @@
#include <memory>
#include <vector>
-#include "VulkanHeaders.h"
+#include "VulkanInstance.hpp"
namespace VulkanUtilities
{
@@ -37,6 +37,18 @@ namespace VulkanUtilities
class VulkanPhysicalDevice
{
public:
+ struct ExtensionFeatures
+ {
+#ifdef VK_NV_mesh_shader
+ VkPhysicalDeviceMeshShaderFeaturesNV MeshShader;
+#endif
+ };
+
+ struct ExtensionProperties
+ {
+ };
+
+public:
// clang-format off
VulkanPhysicalDevice (const VulkanPhysicalDevice&) = delete;
VulkanPhysicalDevice (VulkanPhysicalDevice&&) = delete;
@@ -44,7 +56,8 @@ public:
VulkanPhysicalDevice& operator = (VulkanPhysicalDevice&&) = delete;
// clang-format on
- static std::unique_ptr<VulkanPhysicalDevice> Create(VkPhysicalDevice vkDevice);
+ static std::unique_ptr<VulkanPhysicalDevice> Create(VkPhysicalDevice vkDevice,
+ std::shared_ptr<VulkanInstance> Instance);
// clang-format off
uint32_t FindQueueFamily (VkQueueFlags QueueFlags) const;
@@ -59,15 +72,20 @@ public:
const VkPhysicalDeviceProperties& GetProperties() const { return m_Properties; }
const VkPhysicalDeviceFeatures& GetFeatures() const { return m_Features; }
+ const ExtensionProperties& GetExtProperties() const { return m_ExtProperties; }
+ const ExtensionFeatures& GetExtFeatures() const { return m_ExtFeatures; }
VkFormatProperties GetPhysicalDeviceFormatProperties(VkFormat imageFormat) const;
private:
- VulkanPhysicalDevice(VkPhysicalDevice vkDevice);
+ VulkanPhysicalDevice(VkPhysicalDevice vkDevice,
+ std::shared_ptr<VulkanInstance> Instance);
const VkPhysicalDevice m_VkDevice;
VkPhysicalDeviceProperties m_Properties = {};
VkPhysicalDeviceFeatures m_Features = {};
VkPhysicalDeviceMemoryProperties m_MemoryProperties = {};
+ ExtensionProperties m_ExtProperties = {};
+ ExtensionFeatures m_ExtFeatures = {};
std::vector<VkQueueFamilyProperties> m_QueueFamilyProperties;
std::vector<VkExtensionProperties> m_SupportedExtensions;
};
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index d61ddc97..a8ec8364 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -256,7 +256,7 @@ void DeviceContextVkImpl::SetPipelineState(IPipelineState* pPipelineState)
// This is necessary because if the command list had been flushed
// and the first PSO set on the command list was a compute pipeline,
// the states would otherwise never be committed (since m_pPipelineState != nullptr)
- CommitStates = OldPSODesc.IsComputePipeline;
+ CommitStates = OldPSODesc.IsComputePipeline();
// We also need to update scissor rect if ScissorEnable state was disabled in previous pipeline
CommitScissor = !OldPSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable;
}
@@ -264,7 +264,7 @@ void DeviceContextVkImpl::SetPipelineState(IPipelineState* pPipelineState)
TDeviceContextBase::SetPipelineState(pPipelineStateVk, 0 /*Dummy*/);
EnsureVkCmdBuffer();
- if (PSODesc.IsComputePipeline)
+ if (PSODesc.IsComputePipeline())
{
auto vkPipeline = pPipelineStateVk->GetVkPipeline();
m_CommandBuffer.BindComputePipeline(vkPipeline);
@@ -553,6 +553,31 @@ void DeviceContextVkImpl::DrawIndexedIndirect(const DrawIndexedIndirectAttribs&
++m_State.NumCommands;
}
+void DeviceContextVkImpl::DrawMesh(const DrawMeshAttribs& Attribs)
+{
+ if (!DvpVerifyDrawMeshArguments(Attribs))
+ return;
+
+ PrepareForDraw(Attribs.Flags);
+
+ m_CommandBuffer.DrawMesh(Attribs.ThreadGroupCount, 0);
+ ++m_State.NumCommands;
+}
+
+void DeviceContextVkImpl::DrawMeshIndirect(const DrawMeshIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)
+{
+ if (!DvpVerifyDrawMeshIndirectArguments(Attribs, pAttribsBuffer))
+ return;
+
+ // We must prepare indirect draw attribs buffer first because state transitions must
+ // be performed outside of render pass, and PrepareForDraw commits render pass
+ BufferVkImpl* pIndirectDrawAttribsVk = PrepareIndirectDrawAttribsBuffer(pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode);
+
+ PrepareForDraw(Attribs.Flags);
+
+ m_CommandBuffer.DrawMeshIndirect(pIndirectDrawAttribsVk->GetVkBuffer(), pIndirectDrawAttribsVk->GetDynamicOffset(m_ContextId, this) + Attribs.IndirectDrawArgsOffset, 1, 0);
+ ++m_State.NumCommands;
+}
void DeviceContextVkImpl::PrepareForDispatchCompute()
{
@@ -1067,7 +1092,7 @@ void DeviceContextVkImpl::SetScissorRects(Uint32 NumRects, const Rect* pRects, U
if (m_pPipelineState)
{
const auto& PSODesc = m_pPipelineState->GetDesc();
- if (!PSODesc.IsComputePipeline && PSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable)
+ if (PSODesc.IsAnyGraphicsPipeline() && PSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable)
{
VERIFY(NumRects == m_NumScissorRects, "Unexpected number of scissor rects");
CommitScissorRects();
diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
index 8d72a0b5..58aea393 100644
--- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
@@ -144,7 +144,7 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
reinterpret_cast<VkAllocationCallbacks*>(EngineCI.pVkAllocator));
auto vkDevice = Instance->SelectPhysicalDevice();
- auto PhysicalDevice = VulkanUtilities::VulkanPhysicalDevice::Create(vkDevice);
+ auto PhysicalDevice = VulkanUtilities::VulkanPhysicalDevice::Create(vkDevice, Instance);
const auto& PhysicalDeviceFeatures = PhysicalDevice->GetFeatures();
// If an implementation exposes any queue family that supports graphics operations,
@@ -155,7 +155,7 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
QueueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
QueueInfo.flags = 0; // reserved for future use
// All commands that are allowed on a queue that supports transfer operations are also allowed on a
- // queue that supports either graphics or compute operations.Thus, if the capabilities of a queue family
+ // queue that supports either graphics or compute operations. Thus, if the capabilities of a queue family
// include VK_QUEUE_GRAPHICS_BIT or VK_QUEUE_COMPUTE_BIT, then reporting the VK_QUEUE_TRANSFER_BIT
// capability separately for that queue family is optional (4.1).
QueueInfo.queueFamilyIndex = PhysicalDevice->FindQueueFamily(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT);
@@ -200,6 +200,24 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_KHR_MAINTENANCE1_EXTENSION_NAME // To allow negative viewport height
};
+
+ // To enable some device extensions you must enable instance extension VK_KHR_get_physical_device_properties2
+ // and add feature description to DeviceCreateInfo.pNext.
+ bool SupportsFeatures2 = Instance->IsExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
+ void** NextExt = const_cast<void **>(&DeviceCreateInfo.pNext);
+
+ // Enable mesh shader extension.
+#ifdef VK_NV_mesh_shader
+ VkPhysicalDeviceMeshShaderFeaturesNV MeshShaderFeats = PhysicalDevice->GetExtFeatures().MeshShader;
+
+ if (SupportsFeatures2 && PhysicalDevice->IsExtensionSupported(VK_NV_MESH_SHADER_EXTENSION_NAME))
+ {
+ DeviceExtensions.push_back(VK_NV_MESH_SHADER_EXTENSION_NAME);
+ *NextExt = &MeshShaderFeats;
+ NextExt = &MeshShaderFeats.pNext;
+ }
+#endif
+
DeviceCreateInfo.ppEnabledExtensionNames = DeviceExtensions.empty() ? nullptr : DeviceExtensions.data();
DeviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(DeviceExtensions.size());
diff --git a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp
index 7742cd63..be1bf51d 100644
--- a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp
@@ -157,7 +157,7 @@ std::array<RefCntAutoPtr<IPipelineState>, 4> GenerateMipsVkHelper::CreatePSOs(TE
PipelineStateCreateInfo PSOCreateInfo;
PipelineStateDesc& PSODesc = PSOCreateInfo.PSODesc;
- PSODesc.IsComputePipeline = true;
+ PSODesc.PipelineType = COMPUTE_PIPELINE;
PSODesc.Name = name.c_str();
PSODesc.ComputePipeline.pCS = pCS;
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
index 32a68780..8fa63070 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
@@ -46,12 +46,16 @@ static VkShaderStageFlagBits ShaderTypeToVkShaderStageFlagBit(SHADER_TYPE Shader
switch (ShaderType)
{
// clang-format off
- case SHADER_TYPE_VERTEX: return VK_SHADER_STAGE_VERTEX_BIT;
- case SHADER_TYPE_HULL: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
- case SHADER_TYPE_DOMAIN: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
- case SHADER_TYPE_GEOMETRY: return VK_SHADER_STAGE_GEOMETRY_BIT;
- case SHADER_TYPE_PIXEL: return VK_SHADER_STAGE_FRAGMENT_BIT;
- case SHADER_TYPE_COMPUTE: return VK_SHADER_STAGE_COMPUTE_BIT;
+ case SHADER_TYPE_VERTEX: return VK_SHADER_STAGE_VERTEX_BIT;
+ case SHADER_TYPE_HULL: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
+ case SHADER_TYPE_DOMAIN: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
+ case SHADER_TYPE_GEOMETRY: return VK_SHADER_STAGE_GEOMETRY_BIT;
+ case SHADER_TYPE_PIXEL: return VK_SHADER_STAGE_FRAGMENT_BIT;
+ case SHADER_TYPE_COMPUTE: return VK_SHADER_STAGE_COMPUTE_BIT;
+#ifdef VK_NV_mesh_shader
+ case SHADER_TYPE_AMPLIFICATION: return VK_SHADER_STAGE_TASK_BIT_NV;
+ case SHADER_TYPE_MESH: return VK_SHADER_STAGE_MESH_BIT_NV;
+#endif
// clang-format on
default:
UNEXPECTED("Unknown shader type");
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
index 99b27d2c..063978f9 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
@@ -173,6 +173,8 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun
m_ShaderResourceLayouts = ALLOCATE(ShaderResLayoutAllocator, "Raw memory for ShaderResourceLayoutVk", ShaderResourceLayoutVk, m_NumShaders * 2);
m_StaticResCaches = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceCacheVk", ShaderResourceCacheVk, m_NumShaders);
m_StaticVarsMgrs = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderVariableManagerVk", ShaderVariableManagerVk, m_NumShaders);
+ m_ResourceLayoutIndex.fill(-1);
+
for (Uint32 s = 0; s < m_NumShaders; ++s)
{
new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk(LogicalDevice);
@@ -228,12 +230,16 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun
switch (ShaderType)
{
// clang-format off
- case SHADER_TYPE_VERTEX: StageCI.stage = VK_SHADER_STAGE_VERTEX_BIT; break;
- case SHADER_TYPE_HULL: StageCI.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; break;
- case SHADER_TYPE_DOMAIN: StageCI.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; break;
- case SHADER_TYPE_GEOMETRY: StageCI.stage = VK_SHADER_STAGE_GEOMETRY_BIT; break;
- case SHADER_TYPE_PIXEL: StageCI.stage = VK_SHADER_STAGE_FRAGMENT_BIT; break;
- case SHADER_TYPE_COMPUTE: StageCI.stage = VK_SHADER_STAGE_COMPUTE_BIT; break;
+ case SHADER_TYPE_VERTEX: StageCI.stage = VK_SHADER_STAGE_VERTEX_BIT; break;
+ case SHADER_TYPE_HULL: StageCI.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; break;
+ case SHADER_TYPE_DOMAIN: StageCI.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; break;
+ case SHADER_TYPE_GEOMETRY: StageCI.stage = VK_SHADER_STAGE_GEOMETRY_BIT; break;
+ case SHADER_TYPE_PIXEL: StageCI.stage = VK_SHADER_STAGE_FRAGMENT_BIT; break;
+ case SHADER_TYPE_COMPUTE: StageCI.stage = VK_SHADER_STAGE_COMPUTE_BIT; break;
+#ifdef VK_NV_mesh_shader
+ case SHADER_TYPE_AMPLIFICATION: StageCI.stage = VK_SHADER_STAGE_TASK_BIT_NV; break;
+ case SHADER_TYPE_MESH: StageCI.stage = VK_SHADER_STAGE_MESH_BIT_NV; break;
+#endif
default: UNEXPECTED("Unknown shader type");
// clang-format on
}
@@ -269,7 +275,7 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun
}
// Create pipeline
- if (m_Desc.IsComputePipeline)
+ if (m_Desc.IsComputePipeline())
{
auto& ComputePipeline = m_Desc.ComputePipeline;
@@ -642,7 +648,7 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind
}
// Prepare descriptor sets, and also bind them if there are no dynamic descriptors
VERIFY_EXPR(pDescrSetBindInfo != nullptr);
- m_PipelineLayout.PrepareDescriptorSets(pCtxVkImpl, m_Desc.IsComputePipeline, ResourceCache, *pDescrSetBindInfo, DynamicDescrSet);
+ m_PipelineLayout.PrepareDescriptorSets(pCtxVkImpl, m_Desc.IsComputePipeline(), ResourceCache, *pDescrSetBindInfo, DynamicDescrSet);
// Dynamic descriptor sets are not released individually. Instead, all dynamic descriptor pools
// are released at the end of the frame by DeviceContextVkImpl::FinishFrame().
}
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index 4e6049b0..66ea8716 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -156,6 +156,7 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters*
auto& Features = m_DeviceCaps.Features;
const auto& vkDeviceFeatures = m_PhysicalDevice->GetFeatures();
+ const auto& vkExtFeatures = m_PhysicalDevice->GetExtFeatures();
Features.SeparablePrograms = True;
Features.IndirectRendering = True;
@@ -179,6 +180,9 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters*
Features.PixelUAVWritesAndAtomics = vkDeviceFeatures.fragmentStoresAndAtomics != VK_FALSE;
Features.TextureUAVExtendedFormats = vkDeviceFeatures.shaderStorageImageExtendedFormats != VK_FALSE;
+ // All devices that supports mesh shader also supports task shader, so it is not necessary to use two separate features.
+ Features.MeshShaders = vkExtFeatures.MeshShader.meshShader != VK_FALSE && vkExtFeatures.MeshShader.taskShader != VK_FALSE;
+
const auto& vkDeviceLimits = m_PhysicalDevice->GetProperties().limits;
auto& TexCaps = m_DeviceCaps.TexCaps;
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp
index aa6235f3..603da02a 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp
@@ -27,6 +27,7 @@
#include <vector>
#include <cstring>
+#include "VulkanUtilities/VulkanInstance.hpp"
#if DILIGENT_USE_VOLK
# define VOLK_IMPLEMENTATION
@@ -34,7 +35,6 @@
#endif
#include "VulkanErrors.hpp"
-#include "VulkanUtilities/VulkanInstance.hpp"
#include "VulkanUtilities/VulkanDebug.hpp"
#if !DILIGENT_NO_GLSLANG
@@ -64,6 +64,15 @@ bool VulkanInstance::IsExtensionAvailable(const char* ExtensionName) const
return false;
}
+bool VulkanInstance::IsExtensionEnabled(const char* ExtensionName) const
+{
+ for (const auto& Extension : m_EnabledExtensions)
+ if (strcmp(Extension, ExtensionName) == 0)
+ return true;
+
+ return false;
+}
+
std::shared_ptr<VulkanInstance> VulkanInstance::Create(bool EnableValidation,
uint32_t GlobalExtensionCount,
const char* const* ppGlobalExtensionNames,
@@ -138,6 +147,14 @@ VulkanInstance::VulkanInstance(bool EnableValidation,
#endif
};
+ // This extension added to core in 1.1, but current version is 1.0
+#ifdef VK_KHR_get_physical_device_properties2
+ if (IsExtensionAvailable(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
+ {
+ GlobalExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
+ }
+#endif
+
if (ppGlobalExtensionNames != nullptr)
{
for (uint32_t ext = 0; ext < GlobalExtensionCount; ++ext)
@@ -213,6 +230,8 @@ VulkanInstance::VulkanInstance(bool EnableValidation,
volkLoadInstance(m_VkInstance);
#endif
+ m_EnabledExtensions = std::move(GlobalExtensions);
+
// If requested, we enable the default validation layers for debugging
if (m_DebugUtilsEnabled)
{
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
index 22eee45e..f18d6872 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
@@ -33,13 +33,15 @@
namespace VulkanUtilities
{
-std::unique_ptr<VulkanPhysicalDevice> VulkanPhysicalDevice::Create(VkPhysicalDevice vkDevice)
+std::unique_ptr<VulkanPhysicalDevice> VulkanPhysicalDevice::Create(VkPhysicalDevice vkDevice,
+ std::shared_ptr<VulkanInstance> Instance)
{
- auto* PhysicalDevice = new VulkanPhysicalDevice{vkDevice};
+ auto* PhysicalDevice = new VulkanPhysicalDevice{vkDevice, Instance};
return std::unique_ptr<VulkanPhysicalDevice>{PhysicalDevice};
}
-VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice) :
+VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice,
+ std::shared_ptr<VulkanInstance> Instance) :
m_VkDevice{vkDevice}
{
VERIFY_EXPR(m_VkDevice != VK_NULL_HANDLE);
@@ -65,6 +67,29 @@ VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice) :
(void)res;
VERIFY_EXPR(ExtensionCount == m_SupportedExtensions.size());
}
+
+ if (Instance->IsExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
+ {
+ VkPhysicalDeviceFeatures2 Feats2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
+ VkPhysicalDeviceProperties2 Props2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2};
+ void** NextFeat = &Feats2.pNext;
+ //void** NextProp = &Props2.pNext;
+
+ // Enable mesh shader extension.
+#ifdef VK_NV_mesh_shader
+ if (IsExtensionSupported(VK_NV_MESH_SHADER_EXTENSION_NAME))
+ {
+ *NextFeat = &m_ExtFeatures.MeshShader;
+ NextFeat = &m_ExtFeatures.MeshShader.pNext;
+ m_ExtFeatures.MeshShader.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV;
+ }
+#endif
+
+ // Initialize device extension features by current physical device features.
+ // Some flags may not be supported by hardware.
+ vkGetPhysicalDeviceFeatures2KHR(m_VkDevice, &Feats2);
+ vkGetPhysicalDeviceProperties2KHR(m_VkDevice, &Props2);
+ }
}
uint32_t VulkanPhysicalDevice::FindQueueFamily(VkQueueFlags QueueFlags) const