Browse Source

Vk: expose and implement KHR_portability_subset.

pull/494/head
Vladimír Vondruš 5 years ago
parent
commit
3378ca3f57
  1. 20
      doc/snippets/MagnumVk.cpp
  2. 2
      doc/vulkan-mapping.dox
  3. 1
      doc/vulkan-support.dox
  4. 45
      src/Magnum/Vk/Device.cpp
  5. 27
      src/Magnum/Vk/Device.h
  6. 8
      src/Magnum/Vk/DeviceCreateInfo.h
  7. 115
      src/Magnum/Vk/DeviceFeatures.h
  8. 9
      src/Magnum/Vk/DeviceProperties.cpp
  9. 8
      src/Magnum/Vk/DeviceProperties.h
  10. 1
      src/Magnum/Vk/Extensions.cpp
  11. 37
      src/Magnum/Vk/Extensions.h
  12. 20
      src/Magnum/Vk/Implementation/DeviceFeatures.h
  13. 18
      src/Magnum/Vk/Implementation/deviceFeatureMapping.hpp
  14. 35
      src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp
  15. 90
      src/Magnum/Vk/Test/DeviceVkTest.cpp
  16. 1
      src/MagnumExternal/Vulkan/extensions.txt
  17. 33
      src/MagnumExternal/Vulkan/flextVk.h

20
doc/snippets/MagnumVk.cpp

@ -311,6 +311,26 @@ info.setEnabledFeatures(properties.features() & // mask away unsupported ones
/* [Device-creation-check-supported] */
}
{
Vk::Instance instance;
/* [Device-creation-portability-subset] */
Vk::DeviceProperties properties = DOXYGEN_IGNORE(Vk::pickDevice(instance));
Vk::Device device{instance, Vk::DeviceCreateInfo{properties}
/* enable triangle fans only if actually supported */
.setEnabledFeatures(properties.features() & Vk::DeviceFeature::TriangleFans)
DOXYGEN_IGNORE()
};
DOXYGEN_IGNORE()
if(device.enabledFeatures() & Vk::DeviceFeature::TriangleFans) {
// draw a triangle fan mesh
} else {
// indexed draw fallback
}
/* [Device-creation-portability-subset] */
}
{
Vk::Instance instance;
VkQueryPool pool{};

2
doc/vulkan-mapping.dox

@ -571,6 +571,8 @@ Vulkan structure | Matching API
@type_vk{PhysicalDeviceMultiviewFeatures} @m_class{m-label m-flat m-success} **KHR, 1.1** | @ref DeviceFeatures
@type_vk{PhysicalDeviceMultiviewProperties} @m_class{m-label m-flat m-success} **KHR, 1.1** | |
@type_vk{PhysicalDevicePointClippingProperties} @m_class{m-label m-flat m-success} **KHR, 1.1** | |
@type_vk{PhysicalDevicePortabilitySubsetFeaturesKHR} @m_class{m-label m-flat m-warning} **KHR** | @ref DeviceFeatures
@type_vk{PhysicalDevicePortabilitySubsetPropertiesKHR} @m_class{m-label m-flat m-warning} **KHR** | |
@type_vk{PhysicalDeviceProperties}, \n @type_vk{PhysicalDeviceProperties2} @m_class{m-label m-flat m-success} **KHR, 1.1** | @ref DeviceProperties
@type_vk{PhysicalDeviceProtectedMemoryFeatures} @m_class{m-label m-flat m-success} **1.1** | @ref DeviceFeatures
@type_vk{PhysicalDeviceProtectedMemoryProperties} @m_class{m-label m-flat m-success} **1.1** | |

1
doc/vulkan-support.dox

@ -123,6 +123,7 @@ Extension | Status
@vk_extension{EXT,vertex_attribute_divisor} | |
@vk_extension{EXT,index_type_uint8} | @ref Vk::vkIndexType() only
@vk_extension{KHR,acceleration_structure} | |
@vk_extension{KHR,portability_subset} | done except properties
@vk_extension{KHR,deferred_host_operations} | |
@vk_extension{KHR,pipeline_library} | |
@vk_extension{KHR,ray_tracing_pipeline} | |

45
src/Magnum/Vk/Device.cpp

@ -86,6 +86,15 @@ struct DeviceCreateInfo::State {
VkPhysicalDeviceFeatures2 features2{};
Implementation::DeviceFeatures features{};
DeviceFeatures enabledFeatures;
/* Some features are treated as implicitly enabled. Currently this includes
KHR_portability_subset features on devices that *don't* advertise the
extension, in the future it might be for example features unique to
Vulkan1[12]Features (which isn't present in the pNext chain), for which
the corresponding extension got enabled and thus implicitly enabled
those. For all those is common that those don't get explicitly marked as
enabled on device creation and are also not listed among enabled
features in the startup log. */
DeviceFeatures implicitFeatures;
void* firstEnabledFeature{};
/* Used for checking if the device enables extensions required by features */
#ifndef CORRADE_NO_ASSERT
@ -165,6 +174,22 @@ DeviceCreateInfo::DeviceCreateInfo(DeviceProperties& deviceProperties, const Ext
if(extensionProperties->isSupported<Extensions::KHR::create_renderpass2>())
addEnabledExtensions<Extensions::KHR::create_renderpass2>();
}
/* Enable the KHR_portability_subset extension, which *has to be*
enabled when available. Not enabling any of its features though,
that responsibility lies on the user. */
if(extensionProperties->isSupported<Extensions::KHR::portability_subset>()) {
addEnabledExtensions<Extensions::KHR::portability_subset>();
/* Otherwise, if KHR_portability_subset is not supported, mark its
features as *implicitly* supported -- those don't get explicitly
enabled and are also not listed in the list of enabled features in
the startup log */
/** @todo wrap this under a NoImplicitFeatures flag? it doesn't actually
*do* anything though */
} else {
_state->implicitFeatures = Implementation::deviceFeaturesPortabilitySubset();
}
}
/* Conservatively populate the device properties.
@ -308,8 +333,14 @@ template<class T> void structureConnectIfUsed(Containers::Reference<const void*>
}
DeviceCreateInfo& DeviceCreateInfo::setEnabledFeatures(const DeviceFeatures& features) & {
/* Remember the features to pass them to Device later */
DeviceCreateInfo& DeviceCreateInfo::setEnabledFeatures(const DeviceFeatures& features_) & {
/* Filter out implicit features as those are treated as being present even
if not explicitly enabled (such as KHR_portability_subset on devices
that *don't* advertise the extension */
const DeviceFeatures features = features_ & ~_state->implicitFeatures;
/* Remember the features to pass them to Device later. This gets combined
with implicitFeatures again for Device::enabledFeatures(). */
_state->enabledFeatures = features;
/* Clear any existing pointers to the feature structure chain. This needs
@ -346,6 +377,7 @@ DeviceCreateInfo& DeviceCreateInfo::setEnabledFeatures(const DeviceFeatures& fea
_state->features.accelerationStructure,
_state->features.samplerYcbcrConversion,
_state->features.descriptorIndexing,
_state->features.portabilitySubset,
_state->features.shaderSubgroupExtendedTypes,
_state->features._8BitStorage,
_state->features.shaderAtomicInt64,
@ -451,6 +483,8 @@ DeviceCreateInfo& DeviceCreateInfo::setEnabledFeatures(const DeviceFeatures& fea
_state->features.samplerYcbcrConversion, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES);
structureConnectIfUsed(next, _state->firstEnabledFeature,
_state->features.descriptorIndexing, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES);
structureConnectIfUsed(next, _state->firstEnabledFeature,
_state->features.portabilitySubset, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR);
structureConnectIfUsed(next, _state->firstEnabledFeature,
_state->features.shaderSubgroupExtendedTypes, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES);
structureConnectIfUsed(next, _state->firstEnabledFeature,
@ -652,7 +686,10 @@ Result Device::tryCreateInternal(Instance& instance, const DeviceCreateInfo& inf
const Version version = info._state->version != Version::None ?
info._state->version : _properties->version();
/* Print all enabled extensions if we're not told to be quiet */
/* Print all enabled extensions and features if we're not told to be quiet.
The implicit features (such as KHR_portability_subset features on
devices that *don't* advertise the extension) are not listed here but
are added to Device::enabledFeatures() below. */
if(!info._state->quietLog) {
Debug{} << "Device:" << _properties->name();
Debug{} << "Device version:" << version;
@ -678,7 +715,7 @@ Result Device::tryCreateInternal(Instance& instance, const DeviceCreateInfo& inf
}
initializeExtensions<const char*>({info->ppEnabledExtensionNames, info->enabledExtensionCount});
initialize(instance, version, info._state->enabledFeatures);
initialize(instance, version, info._state->enabledFeatures | info._state->implicitFeatures);
#ifndef CORRADE_NO_ASSERT
/* This is a dumb O(n^2) search but in an assert that's completely fine */

27
src/Magnum/Vk/Device.h

@ -115,6 +115,33 @@ explicitly enabled.
With both @ref Instance and @ref Device created, you can proceed to setting up
a @ref CommandPool.
@subsection Vk-Device-portability-subset Vulkan portability subset
To simplify porting to platforms with the Portability Subset, Magnum implicitly
enables the @vk_extension{KHR,portability_subset} extension on all devices that
advertise it, as required by the spec, so you don't need to handle that part.
This behavior can be disabled with
@ref DeviceCreateInfo::Flag::NoImplicitExtensions.
For portability-related @ref DeviceFeatures, on conformant Vulkan
implementations (which don't advertise @vk_extension{KHR,portability_subset})
these are all implicitly marked as supported in @ref DeviceProperties::features()
and then implicitly marked as enabled in @ref Device::enabledFeatures(),
independently of whether you enable them or not. On devices having only the
Portability Subset, the supported features are listed in
@ref DeviceProperties::features() but you're expected to manually enable them
on device creation --- that part is *not done implicitly* by the engine.
A workflow that supports both conformant and Portability Subset devices with a
single code path is outlined in the following snippet --- on device creation
you request features that you want (which is a no-op on conformant
implementations), and at runtime you query those features in appropriate cases
(which will be always @cpp true @ce on conformant implementations). As with
other features, all APIs that require a particular Portability Subset feature
are marked as such and also listed among others at @ref requires-vk-feature.
@snippet MagnumVk.cpp Device-creation-portability-subset
@see @ref vulkan-wrapping-optimizing-properties
@section Vk-Device-command-line Command-line options

8
src/Magnum/Vk/DeviceCreateInfo.h

@ -69,6 +69,12 @@ class MAGNUM_VK_EXPORT DeviceCreateInfo {
* @vk_extension{KHR,get_memory_requirements2} to provide a broader
* functionality. If you want to have a complete control over what
* gets enabled, set this flag.
*
* This flag also affects enabling of
* @vk_extension{KHR,portability_subset},which is *required* to be
* enabled by the spec on any device that advertises it, and
* behavior of related @ref DeviceFeatures. See
* @ref Vk-Device-portability-subset for details.
*/
NoImplicitExtensions = 1u << 31
};
@ -234,6 +240,8 @@ class MAGNUM_VK_EXPORT DeviceCreateInfo {
* (Vulkan 1.1, @vk_extension{KHR,sampler_ycbcr_conversion})
* - @type_vk_keyword{PhysicalDeviceDescriptorIndexingFeatures}
* (Vulkan 1.2, @vk_extension{EXT,descriptor_indexing})
* - @type_vk_keyword{PhysicalDevicePortabilitySubsetFeaturesKHR}
* (@vk_extension{KHR,portability_subset})
* - @type_vk_keyword{PhysicalDeviceShaderSubgroupExtendedTypesFeatures}
* (Vulkan 1.2, @vk_extension{KHR,shader_subgroup_extended_types})
* - @type_vk_keyword{PhysicalDevice8BitStorageFeatures} (Vulkan

115
src/Magnum/Vk/DeviceFeatures.h

@ -880,6 +880,121 @@ enum class DeviceFeature: UnsignedShort {
*/
RuntimeDescriptorArray,
/* VkPhysicalDevicePortabilitySubsetFeaturesKHR, #164 */
/**
* Whether constant alpha as source or destination blend color is
* supported.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
ConstantAlphaColorBlendFactors,
/**
* Whether synchronization using events is supported.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
Events,
/**
* Whether an @ref ImageView can be created with a format containing
* different number of components or a different number of bits in each
* component than the format of the underlying @ref Image.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
ImageViewFormatReinterpretation,
/**
* Whether remapping format components in an @ref ImageView is supported.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
ImageViewFormatSwizzle,
/**
* Whether a 2D view can be created on a 3D @ref Image can be created.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
ImageView2DOn3DImage,
/**
* Whether multisample 2D array @ref Image can be created.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
MultisampleArrayImage,
/**
* Whether descriptors with comparison samplers can be updated.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
MutableComparisonSamplers,
/**
* Whether rasterization using a point polygon mode is supported.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
PointPolygons,
/**
* Whether setting a mipmap LOD bias when creating a sampler is supported.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
SamplerMipLodBias,
/**
* Whether separate front and back stencil test reference values are
* supported.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
SeparateStencilMaskRef,
/**
* Whether interpolation at centroid, offset and sample is supported.
* Depends on @ref DeviceFeature::SampleRateShading.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
ShaderSampleRateInterpolationFunctions,
/**
* Whether isoline output from a tessellation shader stage is supported.
* Depends on @ref DeviceFeature::TessellationShader.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
TessellationIsolines,
/**
* Whether point output from a tessellation shader stage is supported.
* Depends on @ref DeviceFeature::TessellationShader.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
TessellationPointMode,
/**
* Whether triangle fan mesh primitives are supported.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
TriangleFans,
/**
* Whether accessing a vertex input attribute beyond the stride of
* corresponding vertex input binding is supported.
* @requires_vk_extension Extension @vk_extension{KHR,portability_subset},
* see @ref Vk-Device-portability-subset for details.
*/
VertexAttributeAccessBeyondStride,
/* VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures, #176 */
/**

9
src/Magnum/Vk/DeviceProperties.cpp

@ -309,6 +309,10 @@ const DeviceFeatures& DeviceProperties::features() {
Implementation::structureConnect(next, features.samplerYcbcrConversion, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES);
if(isOrVersionSupportedInternal<Extensions::EXT::descriptor_indexing>())
Implementation::structureConnect(next, features.descriptorIndexing, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES);
/* See below as well -- the features are implicitly marked as supported
if the KHR_portability_subset extension is *not* present */
if(isOrVersionSupportedInternal<Extensions::KHR::portability_subset>())
Implementation::structureConnect(next, features.portabilitySubset, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR);
if(isOrVersionSupportedInternal<Extensions::KHR::shader_subgroup_extended_types>())
Implementation::structureConnect(next, features.shaderSubgroupExtendedTypes, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES);
if(isOrVersionSupportedInternal<Extensions::KHR::_8bit_storage>())
@ -351,6 +355,11 @@ const DeviceFeatures& DeviceProperties::features() {
#undef _c
#undef _cver
#undef _cext
/* If the KHR_portability_subset extension is not present, its features
are marked as being implicitly supported */
if(!isOrVersionSupportedInternal<Extensions::KHR::portability_subset>())
_state->features |= Implementation::deviceFeaturesPortabilitySubset();
}
return _state->features;

8
src/Magnum/Vk/DeviceProperties.h

@ -451,6 +451,9 @@ class MAGNUM_VK_EXPORT DeviceProperties {
* - If Vulkan 1.2 or the @vk_extension{EXT,descriptor_indexing}
* extension is supported by the device, the `pNext` chain
* contains @type_vk_keyword{PhysicalDeviceDescriptorIndexingFeatures}
* - If the @vk_extension{KHR,portability_subset} extension is
* supported by the device, the `pNext` chain contains
* @type_vk_keyword{PhysicalDevicePortabilitySubsetFeaturesKHR}
* - If Vulkan 1.2 or the @vk_extension{KHR,shader_subgroup_extended_types}
* extension is supported by the device, the `pNext` chain
* contains @type_vk_keyword{PhysicalDeviceShaderSubgroupExtendedTypesFeatures}
@ -493,6 +496,11 @@ class MAGNUM_VK_EXPORT DeviceProperties {
* the device, the `pNext` chain contains
* @type_vk_keyword{PhysicalDeviceRayQueryFeaturesKHR}
*
* If the @vk_extension{KHR,portability_subset} is *not* supported by
* the device, all features related to it are implicitly marked as
* supported to simplify portability-aware logic. See
* @ref Vk-Device-portability-subset for details.
*
* @see @ref Device::enabledFeatures(),
* @fn_vk_keyword{GetPhysicalDeviceFeatures2},
* @fn_vk_keyword{GetPhysicalDeviceFeatures},

1
src/Magnum/Vk/Extensions.cpp

@ -75,6 +75,7 @@ constexpr Extension DeviceExtensions[] {
Extensions::KHR::acceleration_structure{},
Extensions::KHR::deferred_host_operations{},
Extensions::KHR::pipeline_library{},
Extensions::KHR::portability_subset{},
Extensions::KHR::ray_query{},
Extensions::KHR::ray_tracing_pipeline{},
};

37
src/Magnum/Vk/Extensions.h

@ -149,24 +149,25 @@ namespace EXT {
_extension(50, KHR,acceleration_structure, Vk11, None) // #151
_extension(51, KHR,sampler_ycbcr_conversion, Vk10, Vk11) // #157
_extension(52, KHR,bind_memory2, Vk10, Vk11) // #158
_extension(53, KHR,maintenance3, Vk10, Vk11) // #169
_extension(54, KHR,draw_indirect_count, Vk10, Vk12) // #170
_extension(55, KHR,shader_subgroup_extended_types, Vk11, Vk12) // #176
_extension_(56, KHR,8bit_storage,_8bit_storage, Vk10, Vk12) // #178
_extension(57, KHR,shader_atomic_int64, Vk10, Vk12) // #181
_extension(58, KHR,driver_properties, Vk10, Vk12) // #197
_extension(59, KHR,shader_float_controls, Vk10, Vk12) // #198
_extension(60, KHR,depth_stencil_resolve, Vk10, Vk12) // #200
_extension(61, KHR,timeline_semaphore, Vk10, Vk12) // #208
_extension(62, KHR,vulkan_memory_model, Vk10, Vk12) // #212
_extension(63, KHR,spirv_1_4, Vk11, Vk12) // #237
_extension(64, KHR,separate_depth_stencil_layouts, Vk10, Vk12) // #242
_extension(65, KHR,uniform_buffer_standard_layout, Vk10, Vk12) // #254
_extension(66, KHR,buffer_device_address, Vk10, Vk12) // #258
_extension(67, KHR,deferred_host_operations, Vk10, None) // #259
_extension(68, KHR,pipeline_library, Vk10, None) // #291
_extension(69, KHR,ray_tracing_pipeline, Vk11, None) // #348
_extension(70, KHR,ray_query, Vk11, None) // #349
_extension(53, KHR,portability_subset, Vk10, None) // #164
_extension(54, KHR,maintenance3, Vk10, Vk11) // #169
_extension(55, KHR,draw_indirect_count, Vk10, Vk12) // #170
_extension(56, KHR,shader_subgroup_extended_types, Vk11, Vk12) // #176
_extension_(57, KHR,8bit_storage,_8bit_storage, Vk10, Vk12) // #178
_extension(58, KHR,shader_atomic_int64, Vk10, Vk12) // #181
_extension(59, KHR,driver_properties, Vk10, Vk12) // #197
_extension(60, KHR,shader_float_controls, Vk10, Vk12) // #198
_extension(61, KHR,depth_stencil_resolve, Vk10, Vk12) // #200
_extension(62, KHR,timeline_semaphore, Vk10, Vk12) // #208
_extension(63, KHR,vulkan_memory_model, Vk10, Vk12) // #212
_extension(64, KHR,spirv_1_4, Vk11, Vk12) // #237
_extension(65, KHR,separate_depth_stencil_layouts, Vk10, Vk12) // #242
_extension(66, KHR,uniform_buffer_standard_layout, Vk10, Vk12) // #254
_extension(67, KHR,buffer_device_address, Vk10, Vk12) // #258
_extension(68, KHR,deferred_host_operations, Vk10, None) // #259
_extension(69, KHR,pipeline_library, Vk10, None) // #291
_extension(70, KHR,ray_tracing_pipeline, Vk11, None) // #348
_extension(71, KHR,ray_query, Vk11, None) // #349
}
#undef _extension

20
src/Magnum/Vk/Implementation/DeviceFeatures.h

@ -47,6 +47,7 @@ struct DeviceFeatures {
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationStructure;
VkPhysicalDeviceSamplerYcbcrConversionFeatures samplerYcbcrConversion;
VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexing;
VkPhysicalDevicePortabilitySubsetFeaturesKHR portabilitySubset;
VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures shaderSubgroupExtendedTypes;
VkPhysicalDevice8BitStorageFeatures _8BitStorage;
VkPhysicalDeviceShaderAtomicInt64Features shaderAtomicInt64;
@ -63,6 +64,25 @@ struct DeviceFeatures {
VkPhysicalDeviceRayQueryFeaturesKHR rayQuery;
};
constexpr Vk::DeviceFeatures deviceFeaturesPortabilitySubset() {
return
DeviceFeature::ConstantAlphaColorBlendFactors|
DeviceFeature::Events|
DeviceFeature::ImageViewFormatReinterpretation|
DeviceFeature::ImageViewFormatSwizzle|
DeviceFeature::ImageView2DOn3DImage|
DeviceFeature::MultisampleArrayImage|
DeviceFeature::MutableComparisonSamplers|
DeviceFeature::PointPolygons|
DeviceFeature::SamplerMipLodBias|
DeviceFeature::SeparateStencilMaskRef|
DeviceFeature::ShaderSampleRateInterpolationFunctions|
DeviceFeature::TessellationIsolines|
DeviceFeature::TessellationPointMode|
DeviceFeature::TriangleFans|
DeviceFeature::VertexAttributeAccessBeyondStride;
}
}}}
#endif

18
src/Magnum/Vk/Implementation/deviceFeatureMapping.hpp

@ -155,6 +155,24 @@ _ce(DescriptorBindingVariableDescriptorCount, descriptorBindingVariableDescripto
_ce(RuntimeDescriptorArray, runtimeDescriptorArray)
#undef _ce
#define _ce(value, field) _cext(value, field, portabilitySubset, KHR::portability_subset)
_ce(ConstantAlphaColorBlendFactors, constantAlphaColorBlendFactors)
_ce(Events, events)
_ce(ImageViewFormatReinterpretation, imageViewFormatReinterpretation)
_ce(ImageViewFormatSwizzle, imageViewFormatSwizzle)
_ce(ImageView2DOn3DImage, imageView2DOn3DImage)
_ce(MultisampleArrayImage, multisampleArrayImage)
_ce(MutableComparisonSamplers, mutableComparisonSamplers)
_ce(PointPolygons, pointPolygons)
_ce(SamplerMipLodBias, samplerMipLodBias)
_ce(SeparateStencilMaskRef, separateStencilMaskRef)
_ce(ShaderSampleRateInterpolationFunctions, shaderSampleRateInterpolationFunctions)
_ce(TessellationIsolines, tessellationIsolines)
_ce(TessellationPointMode, tessellationPointMode)
_ce(TriangleFans, triangleFans)
_ce(VertexAttributeAccessBeyondStride, vertexAttributeAccessBeyondStride)
#undef _ce
_cext(ShaderSubgroupExtendedTypes, shaderSubgroupExtendedTypes, shaderSubgroupExtendedTypes, KHR::shader_subgroup_extended_types)
#define _ce(value, field) _cext(value, field, _8BitStorage, KHR::_8bit_storage)

35
src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp

@ -44,6 +44,9 @@
#include "Magnum/Vk/Version.h"
#include "Magnum/Vk/VulkanTester.h"
#include "Magnum/Vk/Implementation/DeviceFeatures.h"
/* for deviceFeaturesPortabilitySubset() */
namespace Magnum { namespace Vk { namespace Test { namespace {
struct DevicePropertiesVkTest: VulkanTester {
@ -66,6 +69,8 @@ struct DevicePropertiesVkTest: VulkanTester {
void driverProperties();
void features();
void featuresNoPortability();
void featuresPortability();
void featureExpectedSupported();
void featureExpectedUnsupported();
@ -118,6 +123,8 @@ DevicePropertiesVkTest::DevicePropertiesVkTest(): VulkanTester{NoCreate} {
&DevicePropertiesVkTest::driverProperties,
&DevicePropertiesVkTest::features,
&DevicePropertiesVkTest::featuresNoPortability,
&DevicePropertiesVkTest::featuresPortability,
&DevicePropertiesVkTest::featureExpectedSupported,
&DevicePropertiesVkTest::featureExpectedUnsupported,
@ -254,6 +261,34 @@ void DevicePropertiesVkTest::features() {
}
}
void DevicePropertiesVkTest::featuresNoPortability() {
Containers::Optional<DeviceProperties> device = tryPickDevice(instance());
CORRADE_VERIFY(device);
if(device->enumerateExtensionProperties().isSupported<Extensions::KHR::portability_subset>())
CORRADE_SKIP("KHR_portability_subset supported, can't test");
/* All features should be marked as supported */
CORRADE_COMPARE_AS(device->features(), Implementation::deviceFeaturesPortabilitySubset(),
TestSuite::Compare::GreaterOrEqual);
}
void DevicePropertiesVkTest::featuresPortability() {
Containers::Optional<DeviceProperties> device = tryPickDevice(instance());
CORRADE_VERIFY(device);
if(!device->enumerateExtensionProperties().isSupported<Extensions::KHR::portability_subset>())
CORRADE_SKIP("KHR_portability_subset not supported, can't test");
Debug{} << "Supported portability subset:" << (device->features() & Implementation::deviceFeaturesPortabilitySubset());
/* Not all features should be marked as supported */
CORRADE_VERIFY((device->features() & Implementation::deviceFeaturesPortabilitySubset()) != Implementation::deviceFeaturesPortabilitySubset());
/* But there should be at least one */
CORRADE_VERIFY(device->features() & Implementation::deviceFeaturesPortabilitySubset());
}
void DevicePropertiesVkTest::featureExpectedSupported() {
Containers::Optional<DeviceProperties> device = tryPickDevice(instance());
CORRADE_VERIFY(device);

90
src/Magnum/Vk/Test/DeviceVkTest.cpp

@ -43,6 +43,9 @@
#include "Magnum/Vk/Version.h"
#include "Magnum/Vk/VulkanTester.h"
#include "Magnum/Vk/Implementation/DeviceFeatures.h"
/* for deviceFeaturesPortabilitySubset() */
#include "MagnumExternal/Vulkan/flextVkGlobal.h"
namespace Magnum { namespace Vk { namespace Test { namespace {
@ -80,6 +83,10 @@ struct DeviceVkTest: VulkanTester {
void constructFeatureWithoutExtension();
void constructNoQueue();
void constructNoPortability();
void constructNoPortabilityEnablePortabilityFeatures();
void constructPortability();
void tryCreateAlreadyCreated();
void tryCreateUnknownExtension();
@ -178,6 +185,10 @@ DeviceVkTest::DeviceVkTest(): VulkanTester{NoCreate} {
&DeviceVkTest::constructFeatureWithoutExtension,
&DeviceVkTest::constructNoQueue,
&DeviceVkTest::constructNoPortability,
&DeviceVkTest::constructNoPortabilityEnablePortabilityFeatures,
&DeviceVkTest::constructPortability,
&DeviceVkTest::tryCreateAlreadyCreated,
&DeviceVkTest::tryCreateUnknownExtension,
@ -631,8 +642,10 @@ void DeviceVkTest::constructFeatures() {
.setEnabledFeatures(DeviceFeature::RobustBufferAccess)};
CORRADE_VERIFY(device.handle());
/* Features should be reported as enabled */
CORRADE_COMPARE(device.enabledFeatures(), DeviceFeature::RobustBufferAccess);
/* Features should be reported as enabled. Exclude portability subset
features that get implicitly marked as enabled on devices w/o
KHR_portability_subset. */
CORRADE_COMPARE(device.enabledFeatures() & ~Implementation::deviceFeaturesPortabilitySubset(), DeviceFeature::RobustBufferAccess);
}
void DeviceVkTest::constructFeaturesFromExtensions() {
@ -652,8 +665,10 @@ void DeviceVkTest::constructFeaturesFromExtensions() {
.setEnabledFeatures(DeviceFeature::RobustBufferAccess|DeviceFeature::SamplerYcbcrConversion)};
CORRADE_VERIFY(device.handle());
/* Features should be reported as enabled */
CORRADE_COMPARE(device.enabledFeatures(), DeviceFeature::RobustBufferAccess|DeviceFeature::SamplerYcbcrConversion);
/* Features should be reported as enabled. Exclude portability subset
features that get implicitly marked as enabled on devices w/o
KHR_portability_subset. */
CORRADE_COMPARE(device.enabledFeatures() & ~Implementation::deviceFeaturesPortabilitySubset(), DeviceFeature::RobustBufferAccess|DeviceFeature::SamplerYcbcrConversion);
}
void DeviceVkTest::constructDeviceCreateInfoConstReference() {
@ -923,6 +938,73 @@ void DeviceVkTest::constructNoQueue() {
CORRADE_COMPARE(out.str(), "Vk::Device::tryCreate(): needs at least one queue\n");
}
void DeviceVkTest::constructNoPortability() {
DeviceProperties properties = pickDevice(instance());
if(properties.enumerateExtensionProperties().isSupported<Extensions::KHR::portability_subset>())
CORRADE_SKIP("KHR_portability_subset supported, can't test");
Queue queue{NoCreate};
Device device{instance(), DeviceCreateInfo{properties}
.addQueues(0, {0.0f}, {queue})
};
/* The extension shouldn't be registered as enabled */
CORRADE_VERIFY(!device.isExtensionEnabled<Extensions::KHR::portability_subset>());
/* All features should be marked as enabled */
CORRADE_COMPARE_AS(device.enabledFeatures(), Implementation::deviceFeaturesPortabilitySubset(),
TestSuite::Compare::GreaterOrEqual);
}
void DeviceVkTest::constructNoPortabilityEnablePortabilityFeatures() {
DeviceProperties properties = pickDevice(instance());
if(properties.enumerateExtensionProperties().isSupported<Extensions::KHR::portability_subset>())
CORRADE_SKIP("KHR_portability_subset supported, can't test");
Device device{NoCreate};
/* Explicitly enabling portability subset features shouldn't do anything
when the portability extension isn't present */
Queue queue{NoCreate};
CORRADE_COMPARE(device.tryCreate(instance(), DeviceCreateInfo{properties}
.addQueues(0, {0.0f}, {queue})
.setEnabledFeatures(Implementation::deviceFeaturesPortabilitySubset())
), Result::Success);
/* All features should be marked as enabled */
CORRADE_COMPARE_AS(device.enabledFeatures(), Implementation::deviceFeaturesPortabilitySubset(),
TestSuite::Compare::GreaterOrEqual);
}
void DeviceVkTest::constructPortability() {
DeviceProperties properties = pickDevice(instance());
if(!properties.enumerateExtensionProperties().isSupported<Extensions::KHR::portability_subset>())
CORRADE_SKIP("KHR_portability_subset not supported, can't test");
/* (Same as in DevicePropertiesVkTest.) Not all features should be marked
as supported... */
CORRADE_VERIFY((properties.features() & Implementation::deviceFeaturesPortabilitySubset()) != Implementation::deviceFeaturesPortabilitySubset());
/* ... but there should be at least one feature */
CORRADE_VERIFY(properties.features() &
Implementation::deviceFeaturesPortabilitySubset());
Queue queue{NoCreate};
Device device{instance(), DeviceCreateInfo{properties}
.addQueues(0, {0.0f}, {queue})
.setEnabledFeatures(properties.features() &
Implementation::deviceFeaturesPortabilitySubset())
};
/* All requested features should be marked as enabled */
CORRADE_COMPARE_AS(device.enabledFeatures(), properties.features() &
Implementation::deviceFeaturesPortabilitySubset(),
TestSuite::Compare::GreaterOrEqual);
}
void DeviceVkTest::tryCreateAlreadyCreated() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");

1
src/MagnumExternal/Vulkan/extensions.txt vendored

@ -65,6 +65,7 @@ extension EXT_vertex_attribute_divisor optional
extension EXT_index_type_uint8 optional
extension IMG_format_pvrtc optional
extension KHR_acceleration_structure optional
extension KHR_portability_subset optional
extension KHR_deferred_host_operations optional
extension KHR_pipeline_library optional
extension KHR_ray_tracing_pipeline optional

33
src/MagnumExternal/Vulkan/flextVk.h vendored

@ -274,6 +274,11 @@ extern "C" {
#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 11
#define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure"
/* VK_KHR_portability_subset */
#define VK_KHR_PORTABILITY_SUBSET_SPEC_VERSION 1
#define VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME "VK_KHR_portability_subset"
/* VK_KHR_pipeline_library */
#define VK_KHR_PIPELINE_LIBRARY_SPEC_VERSION 1
@ -1555,6 +1560,8 @@ typedef enum {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR = 1000150014,
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR = 1000150017,
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR = 1000150020,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR = 1000163000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR = 1000163001,
VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR = 1000347000,
@ -4721,6 +4728,32 @@ typedef struct VkCopyMemoryToAccelerationStructureInfoKHR {
VkCopyAccelerationStructureModeKHR mode;
} VkCopyMemoryToAccelerationStructureInfoKHR;
typedef struct VkPhysicalDevicePortabilitySubsetFeaturesKHR {
VkStructureType sType;
void* pNext;
VkBool32 constantAlphaColorBlendFactors;
VkBool32 events;
VkBool32 imageViewFormatReinterpretation;
VkBool32 imageViewFormatSwizzle;
VkBool32 imageView2DOn3DImage;
VkBool32 multisampleArrayImage;
VkBool32 mutableComparisonSamplers;
VkBool32 pointPolygons;
VkBool32 samplerMipLodBias;
VkBool32 separateStencilMaskRef;
VkBool32 shaderSampleRateInterpolationFunctions;
VkBool32 tessellationIsolines;
VkBool32 tessellationPointMode;
VkBool32 triangleFans;
VkBool32 vertexAttributeAccessBeyondStride;
} VkPhysicalDevicePortabilitySubsetFeaturesKHR;
typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR {
VkStructureType sType;
void* pNext;
uint32_t minVertexInputBindingStrideAlignment;
} VkPhysicalDevicePortabilitySubsetPropertiesKHR;
typedef struct VkAccelerationStructureBuildSizesInfoKHR {
VkStructureType sType;
const void* pNext;

Loading…
Cancel
Save