Skip to content

Commit

Permalink
[VK] Enable device features VkPhysicalDeviceNestedCommandBufferFeatur…
Browse files Browse the repository at this point in the history
…esEXT if available (fixes #121).

This enables VkPhysicalDeviceNestedCommandBufferFeaturesEXT in the logical Vulkan device if it's available in the physical device.

TODO: The construction of pNext-chains needs some rework, as this is still very hardcoded.
  • Loading branch information
LukasBanana committed Jul 28, 2024
1 parent 17800ec commit 68f7b57
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 54 deletions.
2 changes: 1 addition & 1 deletion sources/Renderer/Vulkan/Command/VKCommandBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ constexpr std::uint32_t VKCommandBuffer::maxNumCommandBuffers;
// Returns the maximum for a indirect multi draw command
static std::uint32_t GetMaxDrawIndirectCount(const VKPhysicalDevice& physicalDevice)
{
if (physicalDevice.GetFeatures().multiDrawIndirect != VK_FALSE)
if (physicalDevice.GetFeatures().features.multiDrawIndirect != VK_FALSE)
return physicalDevice.GetProperties().limits.maxDrawIndirectCount;
else
return 1u;
Expand Down
22 changes: 16 additions & 6 deletions sources/Renderer/Vulkan/VKDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ void VKDevice::WaitIdle()
// Device-only layers are deprecated -> set 'enabledLayerCount' and 'ppEnabledLayerNames' members to zero during device creation.
// see https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#extended-functionality-device-layer-deprecation
void VKDevice::CreateLogicalDevice(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceFeatures* features,
const char* const* extensions,
std::uint32_t numExtensions)
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceFeatures2* features,
const char* const* extensions,
std::uint32_t numExtensions)
{
/* Initialize queue create description */
queueFamilyIndices_ = VKFindQueueFamilies(physicalDevice, (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT));
Expand Down Expand Up @@ -90,15 +90,25 @@ void VKDevice::CreateLogicalDevice(
VkDeviceCreateInfo createInfo;
{
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.queueCreateInfoCount = static_cast<std::uint32_t>(queueCreateInfos.size());
createInfo.pQueueCreateInfos = queueCreateInfos.data();
createInfo.enabledLayerCount = 0; // deprecated and ignored
createInfo.ppEnabledLayerNames = nullptr; // deprecated and ignored
createInfo.enabledExtensionCount = numExtensions;
createInfo.ppEnabledExtensionNames = extensions;
createInfo.pEnabledFeatures = features;

/* If must pass the feature flags either through the chain of pNext (Vulkan 1.1+), or only through pEnabledFeatures (Vulkan 1.0) */
if (features->pNext != nullptr)
{
createInfo.pNext = features;
createInfo.pEnabledFeatures = nullptr;
}
else
{
createInfo.pNext = nullptr;
createInfo.pEnabledFeatures = &(features->features);
}
}
VkResult result = vkCreateDevice(physicalDevice, &createInfo, nullptr, device_.ReleaseAndGetAddressOf());
VKThrowIfFailed(result, "failed to create Vulkan logical device");
Expand Down
8 changes: 4 additions & 4 deletions sources/Renderer/Vulkan/VKDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ class VKDevice
VKDevice& operator = (VKDevice&& device);

void CreateLogicalDevice(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceFeatures* features,
const char* const* extensions,
std::uint32_t numExtensions
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceFeatures2* features,
const char* const* extensions,
std::uint32_t numExtensions
);

void LoadLogicalDeviceWeakRef(VkPhysicalDevice physicalDevice, VkDevice device);
Expand Down
82 changes: 45 additions & 37 deletions sources/Renderer/Vulkan/VKPhysicalDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ void VKPhysicalDevice::QueryRendererInfo(RendererInfo& info)
void VKPhysicalDevice::QueryRenderingCaps(RenderingCapabilities& caps)
{
/* Map limits to output rendering capabilites */
const VkPhysicalDeviceFeatures& features = features_.features;
const VkPhysicalDeviceLimits& limits = properties_.limits;

/* Query common attributes */
Expand All @@ -234,7 +235,7 @@ void VKPhysicalDevice::QueryRenderingCaps(RenderingCapabilities& caps)
caps.shadingLanguages = { ShadingLanguage::SPIRV, ShadingLanguage::SPIRV_100 };
caps.textureFormats = GetDefaultSupportedVKTextureFormats();

if (features_.textureCompressionBC != VK_FALSE)
if (features.textureCompressionBC != VK_FALSE)
{
const std::vector<Format> compressedTextureFormats = GetCompressedVKTextureFormatsS3TC();
caps.textureFormats.insert(caps.textureFormats.end(), compressedTextureFormats.begin(), compressedTextureFormats.end());
Expand All @@ -245,7 +246,7 @@ void VKPhysicalDevice::QueryRenderingCaps(RenderingCapabilities& caps)
caps.features.has3DTextures = true;
caps.features.hasCubeTextures = true;
caps.features.hasArrayTextures = true;
caps.features.hasCubeArrayTextures = (features_.imageCubeArray != VK_FALSE);
caps.features.hasCubeArrayTextures = (features.imageCubeArray != VK_FALSE);
caps.features.hasMultiSampleTextures = true;
caps.features.hasMultiSampleArrayTextures = true;
caps.features.hasTextureViews = true;
Expand All @@ -254,18 +255,18 @@ void VKPhysicalDevice::QueryRenderingCaps(RenderingCapabilities& caps)
caps.features.hasBufferViews = true;
caps.features.hasConstantBuffers = true;
caps.features.hasStorageBuffers = true;
caps.features.hasGeometryShaders = (features_.geometryShader != VK_FALSE);
caps.features.hasTessellationShaders = (features_.tessellationShader != VK_FALSE);
caps.features.hasGeometryShaders = (features.geometryShader != VK_FALSE);
caps.features.hasTessellationShaders = (features.tessellationShader != VK_FALSE);
caps.features.hasTessellatorStage = caps.features.hasTessellationShaders;
caps.features.hasComputeShaders = true;
caps.features.hasInstancing = true;
caps.features.hasOffsetInstancing = true;
caps.features.hasIndirectDrawing = (features_.drawIndirectFirstInstance != VK_FALSE);
caps.features.hasViewportArrays = (features_.multiViewport != VK_FALSE);
caps.features.hasIndirectDrawing = (features.drawIndirectFirstInstance != VK_FALSE);
caps.features.hasViewportArrays = (features.multiViewport != VK_FALSE);
caps.features.hasConservativeRasterization = SupportsExtension(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME);
caps.features.hasStreamOutputs = SupportsExtension(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
caps.features.hasLogicOp = (features_.logicOp != VK_FALSE);
caps.features.hasPipelineStatistics = (features_.pipelineStatisticsQuery != VK_FALSE);
caps.features.hasLogicOp = (features.logicOp != VK_FALSE);
caps.features.hasPipelineStatistics = (features.pipelineStatisticsQuery != VK_FALSE);
caps.features.hasRenderCondition = SupportsExtension(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME);
caps.features.hasPipelineCaching = true;

Expand Down Expand Up @@ -386,33 +387,10 @@ bool VKPhysicalDevice::EnableExtensions(const char** extensions, bool required)

void VKPhysicalDevice::QueryDeviceInfo()
{
if (HasExtension(VKExt::KHR_get_physical_device_properties2))
{
/* Query physical device features and properties with extensions */
QueryDeviceFeaturesWithExtensions();
QueryDevicePropertiesWithExtensions();
QueryDeviceMemoryPropertiesWithExtensions();
}
else
{
/* Query physical device features and memory properties */
vkGetPhysicalDeviceFeatures(physicalDevice_, &features_);
vkGetPhysicalDeviceProperties(physicalDevice_, &properties_);
vkGetPhysicalDeviceMemoryProperties(physicalDevice_, &memoryProperties_);
}
}

void VKPhysicalDevice::QueryDeviceFeaturesWithExtensions()
{
/*VkPhysicalDeviceFeatures2 featuresExt;
{
featuresExt.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
//TODO...
}
vkGetPhysicalDeviceFeatures2(physicalDevice_, &featuresExt);
features_ = featuresExt.features;*/

vkGetPhysicalDeviceFeatures(physicalDevice_, &features_);
/* Query physical device features and properties with extensions */
QueryDeviceFeatures();
QueryDeviceProperties();
QueryDeviceMemoryProperties();
}

struct VKBaseStructureInfo
Expand All @@ -421,8 +399,32 @@ struct VKBaseStructureInfo
void* pNext;
};

void VKPhysicalDevice::QueryDevicePropertiesWithExtensions()
void VKPhysicalDevice::QueryDeviceFeatures()
{
#if VK_KHR_get_physical_device_properties2

VKBaseStructureInfo* currentDesc = nullptr;

#ifdef VK_EXT_nested_command_buffer
featuresNestedCmdBuffers_.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NESTED_COMMAND_BUFFER_FEATURES_EXT;
currentDesc = reinterpret_cast<VKBaseStructureInfo*>(&featuresNestedCmdBuffers_);
#endif

features_.pNext = currentDesc;

vkGetPhysicalDeviceFeatures2(physicalDevice_, &features_);

#else

vkGetPhysicalDeviceFeatures(physicalDevice_, &(features_.features));

#endif
}

void VKPhysicalDevice::QueryDeviceProperties()
{
#if VK_KHR_get_physical_device_properties2

VKBaseStructureInfo* currentDesc = nullptr;

auto ChainDescritpor = [&currentDesc](void* descPtr, VkStructureType type)
Expand Down Expand Up @@ -452,9 +454,15 @@ void VKPhysicalDevice::QueryDevicePropertiesWithExtensions()

/* Store primary device properties */
properties_ = propertiesExt.properties;

#else

vkGetPhysicalDeviceProperties(physicalDevice_, &properties_);

#endif
}

void VKPhysicalDevice::QueryDeviceMemoryPropertiesWithExtensions()
void VKPhysicalDevice::QueryDeviceMemoryProperties()
{
vkGetPhysicalDeviceMemoryProperties(physicalDevice_, &memoryProperties_);
}
Expand Down
13 changes: 8 additions & 5 deletions sources/Renderer/Vulkan/VKPhysicalDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class VKPhysicalDevice
}

// Returns the Vulkan specific features of the physical device.
inline const VkPhysicalDeviceFeatures& GetFeatures() const
inline const VkPhysicalDeviceFeatures2& GetFeatures() const
{
return features_;
}
Expand Down Expand Up @@ -101,9 +101,9 @@ class VKPhysicalDevice
bool EnableExtensions(const char** extensions, bool required = false);

void QueryDeviceInfo();
void QueryDeviceFeaturesWithExtensions();
void QueryDevicePropertiesWithExtensions();
void QueryDeviceMemoryPropertiesWithExtensions();
void QueryDeviceFeatures();
void QueryDeviceProperties();
void QueryDeviceMemoryProperties();

private:

Expand All @@ -114,7 +114,10 @@ class VKPhysicalDevice
std::vector<const char*> enabledExtensionNames_;

// Common device properties and features
VkPhysicalDeviceFeatures features_ = {};
VkPhysicalDeviceFeatures2 features_ = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 };
#ifdef VK_EXT_nested_command_buffer
VkPhysicalDeviceNestedCommandBufferFeaturesEXT featuresNestedCmdBuffers_ = {};
#endif
VkPhysicalDeviceProperties properties_ = {};
VkPhysicalDeviceMemoryProperties memoryProperties_ = {};

Expand Down
1 change: 0 additions & 1 deletion sources/Renderer/Vulkan/VKRenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,6 @@ void VKRenderSystem::Release(PipelineCache& pipelineCache)
pipelineCaches_.erase(&pipelineCache);
}


/* ----- Pipeline States ----- */

PipelineState* VKRenderSystem::CreatePipelineState(const GraphicsPipelineDescriptor& pipelineStateDesc, PipelineCache* pipelineCache)
Expand Down

0 comments on commit 68f7b57

Please sign in to comment.