diff --git a/examples_tests b/examples_tests index 4ed2e6c851..dfd962b547 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 4ed2e6c851fc1fc16e3918ac2eb91b3f0136f140 +Subproject commit dfd962b547b7acc9347664475bb869d00f4f3b26 diff --git a/include/nbl/asset/IImage.h b/include/nbl/asset/IImage.h index 14e0d27bca..664a308c3b 100644 --- a/include/nbl/asset/IImage.h +++ b/include/nbl/asset/IImage.h @@ -1,9 +1,8 @@ -// Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O. +// Copyright (C) 2018-2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h - -#ifndef __NBL_ASSET_I_IMAGE_H_INCLUDED__ -#define __NBL_ASSET_I_IMAGE_H_INCLUDED__ +#ifndef _NBL_ASSET_I_IMAGE_H_INCLUDED_ +#define _NBL_ASSET_I_IMAGE_H_INCLUDED_ #include "nbl/core/util/bitflag.h" #include "nbl/core/containers/refctd_dynamic_array.h" @@ -136,18 +135,18 @@ class IImage : public IDescriptor }; struct SSubresourceRange { - E_ASPECT_FLAGS aspectMask = E_ASPECT_FLAGS::EAF_NONE; - uint32_t baseMipLevel = 0u; - uint32_t levelCount = 0u; - uint32_t baseArrayLayer = 0u; - uint32_t layerCount = 0u; + core::bitflag aspectMask = E_ASPECT_FLAGS::EAF_NONE; + uint32_t baseMipLevel = 0u; + uint32_t levelCount = 0u; + uint32_t baseArrayLayer = 0u; + uint32_t layerCount = 0u; }; struct SSubresourceLayers { - E_ASPECT_FLAGS aspectMask = E_ASPECT_FLAGS::EAF_NONE; - uint32_t mipLevel = 0u; - uint32_t baseArrayLayer = 0u; - uint32_t layerCount = 0u; + core::bitflag aspectMask = E_ASPECT_FLAGS::EAF_NONE; + uint32_t mipLevel = 0u; + uint32_t baseArrayLayer = 0u; + uint32_t layerCount = 0u; auto operator<=>(const SSubresourceLayers&) const = default; }; @@ -214,7 +213,7 @@ class IImage : public IDescriptor inline bool isValid() const { // TODO: more complex check of compatible aspects when planar format support arrives - if (srcSubresource.aspectMask^dstSubresource.aspectMask) + if ((srcSubresource.aspectMask^dstSubresource.aspectMask).value) return false; if (srcSubresource.layerCount!=dstSubresource.layerCount) @@ -235,14 +234,14 @@ class IImage : public IDescriptor }; struct SCreationParams { - E_TYPE type; - E_SAMPLE_COUNT_FLAGS samples; - E_FORMAT format; - VkExtent3D extent; - uint32_t mipLevels; - uint32_t arrayLayers; - core::bitflag flags = ECF_NONE; - core::bitflag usage = EUF_NONE; + E_TYPE type; + E_SAMPLE_COUNT_FLAGS samples; + E_FORMAT format; + VkExtent3D extent; + uint32_t mipLevels; + uint32_t arrayLayers; + core::bitflag flags = ECF_NONE; + core::bitflag usage = EUF_NONE; inline bool operator==(const SCreationParams& rhs) const { @@ -329,6 +328,8 @@ class IImage : public IDescriptor return false; if (_params.extent.width != _params.extent.height) return false; + if (_params.extent.depth > 1u) + return false; if (_params.arrayLayers < 6u) return false; if (_params.samples != ESCF_1_BIT) @@ -587,7 +588,7 @@ class IImage : public IDescriptor //if (!formatHasAspects(m_creationParams.format,subresource.aspectMask)) //return false; // The aspectMask member of imageSubresource must only have a single bit set - if (!core::bitCount(static_cast(subresource.aspectMask)) == 1u) + if (!core::bitCount(subresource.aspectMask.value) == 1u) return false; if (subresource.mipLevel >= m_creationParams.mipLevels) return false; @@ -716,7 +717,7 @@ class IImage : public IDescriptor for (auto it2=it+1u; it2!=pRegionsEnd; it2++) { const auto& subresource2 = it2->getDstSubresource(); - if (!(subresource2.aspectMask&subresource.aspectMask)) + if (!(subresource2.aspectMask&subresource.aspectMask).value) continue; if (subresource2.mipLevel!=subresource.mipLevel) continue; diff --git a/include/nbl/asset/IImageView.h b/include/nbl/asset/IImageView.h index 25d5fb251e..c6b6dbb318 100644 --- a/include/nbl/asset/IImageView.h +++ b/include/nbl/asset/IImageView.h @@ -1,9 +1,8 @@ -// Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O. +// Copyright (C) 2018-2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h - -#ifndef __NBL_ASSET_I_IMAGE_VIEW_H_INCLUDED__ -#define __NBL_ASSET_I_IMAGE_VIEW_H_INCLUDED__ +#ifndef _NBL_ASSET_I_IMAGE_VIEW_H_INCLUDED_ +#define _NBL_ASSET_I_IMAGE_VIEW_H_INCLUDED_ #include "nbl/asset/IImage.h" @@ -16,8 +15,8 @@ template class IImageView : public IDescriptor { public: - _NBL_STATIC_INLINE_CONSTEXPR size_t remaining_mip_levels = ~static_cast(0u); - _NBL_STATIC_INLINE_CONSTEXPR size_t remaining_array_layers = ~static_cast(0u); + static inline constexpr uint32_t remaining_mip_levels = ~static_cast(0u); + static inline constexpr uint32_t remaining_array_layers = ~static_cast(0u); // no flags for now, yet enum E_CREATE_FLAGS @@ -80,12 +79,18 @@ class IImageView : public IDescriptor }; struct SCreationParams { - E_CREATE_FLAGS flags = static_cast(0); - core::smart_refctd_ptr image; - E_TYPE viewType; - E_FORMAT format; - SComponentMapping components; - IImage::SSubresourceRange subresourceRange; + E_CREATE_FLAGS flags = static_cast(0); + // These are the set of usages for this ImageView, they must be a subset of the usages that `image` was created with. + // If you leave it as the default NONE we'll inherit all usages from the `image`, setting it to anything else is + // ONLY useful when creating multiple views of an image created with EXTENDED_USAGE to use different view formats. + // Example: Create SRGB image with usage STORAGE, and two views with formats SRGB and R32_UINT. Then the SRGB view + // CANNOT have STORAGE usage because the format doesn't support it, but the R32_UINT can. + core::bitflag subUsages = IImage::EUF_NONE; + core::smart_refctd_ptr image; + E_TYPE viewType; + E_FORMAT format; + SComponentMapping components = {}; + IImage::SSubresourceRange subresourceRange = {IImage::EAF_COLOR_BIT,0,remaining_mip_levels,0,remaining_array_layers}; }; //! inline static bool validateCreationParameters(const SCreationParams& _params) @@ -97,11 +102,45 @@ class IImageView : public IDescriptor return false; const auto& imgParams = _params.image->getCreationParameters(); - bool mutableFormat = imgParams.flags.hasFlags(IImage::ECF_MUTABLE_FORMAT_BIT); + /* TODO: LAter + image must have been created with a usage value containing at least one of VK_IMAGE_USAGE_SAMPLED_BIT, + VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV, or VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT + if (imgParams.) + return false; + */ + + // declared usages that are not a subset + if (!imgParams.usage.hasFlags(_params.subUsages)) + return false; + + const bool mutableFormat = imgParams.flags.hasFlags(IImage::ECF_MUTABLE_FORMAT_BIT); + const bool blockTexelViewCompatible = imgParams.flags.hasFlags(IImage::ECF_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT); + const auto& subresourceRange = _params.subresourceRange; if (mutableFormat) { - //if (!isFormatCompatible(_params.format,imgParams.format)) - //return false; + // https://registry.khronos.org/vulkan/specs/1.2/html/vkspec.html#VUID-VkImageCreateInfo-flags-01573 + // BlockTexelViewCompatible implies MutableFormat + if (blockTexelViewCompatible) + { + // https://registry.khronos.org/vulkan/specs/1.2/html/vkspec.html#VUID-VkImageViewCreateInfo-image-01583 + // If image was created with the VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT flag, format must be compatible with, + // or must be an uncompressed format that is size-compatible with, the format used to create image + if (getTexelOrBlockBytesize(_params.format)!=getTexelOrBlockBytesize(imgParams.format)) + return false; + // https://registry.khronos.org/vulkan/specs/1.2/html/vkspec.html#VUID-VkImageViewCreateInfo-image-07072 + // If image was created with the VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT flag and + // format is a non-compressed format, the levelCount and layerCount members of subresourceRange must both be 1 + if (!asset::isBlockCompressionFormat(_params.format) && (subresourceRange.levelCount!=1u || subresourceRange.layerCount!=1u)) + return false; + } + // https://registry.khronos.org/vulkan/specs/1.2/html/vkspec.html#VUID-VkImageViewCreateInfo-image-01761 + // If image was created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag, but without the VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT flag, + // and if the format of the image is not a multi-planar format, format must be compatible with the format used to create image + else if (getFormatClass(_params.format)!=getFormatClass(imgParams.format)) + return false; + else if (asset::isBlockCompressionFormat(_params.format)!=asset::isBlockCompressionFormat(imgParams.format)) + return false; /* TODO: if the format of the image is a multi-planar format, and if subresourceRange.aspectMask @@ -110,90 +149,51 @@ class IImageView : public IDescriptor as defined in Compatible formats of planes of multi-planar formats */ } - - - const auto& subresourceRange = _params.subresourceRange; - - if (imgParams.flags.hasFlags(IImage::ECF_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT)) - { - /* - TODO: format must be compatible with, or must be an uncompressed format that is size-compatible with, - the format used to create image. - */ - if (subresourceRange.levelCount!=1u || subresourceRange.layerCount!=1u) - return false; - } - else - { - if (mutableFormat) - { - /* - TODO: if the format of the image is not a multi-planar format, - format must be compatible with the format used to create image, - as defined in Format Compatibility Classes - */ - } - } - - if (!mutableFormat || asset::isPlanarFormat(imgParams.format)) + else if (_params.format!=imgParams.format) { - /* - TODO: format must be compatible with, or must be an uncompressed format that is size-compatible with, - the format used to create image. - */ - } - - /* - image must have been created with a usage value containing at least one of VK_IMAGE_USAGE_SAMPLED_BIT, - VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV, or VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT - if (imgParams.) + // TODO: multi-planar exceptions return false; - */ + } + + //! sanity checks + // we have some layers + if (subresourceRange.layerCount==0u) + return false; + + // mip level ranges if (subresourceRange.baseMipLevel>=imgParams.mipLevels) return false; if (subresourceRange.levelCount!=remaining_mip_levels && (subresourceRange.levelCount==0u || subresourceRange.baseMipLevel+subresourceRange.levelCount>imgParams.mipLevels)) return false; + auto mipExtent = _params.image->getMipSize(subresourceRange.baseMipLevel); - - if (subresourceRange.layerCount==0u) - return false; + auto actualLayerCount = subresourceRange.layerCount; - bool sourceIs3D = imgParams.type==IImage::ET_3D; - bool sourceIs2DCompat = imgParams.flags.hasFlags(IImage::ECF_2D_ARRAY_COMPATIBLE_BIT) && (_params.viewType==ET_2D||_params.viewType==ET_2D_ARRAY); - auto actualLayerCount = subresourceRange.layerCount!=remaining_array_layers ? subresourceRange.layerCount: - ((sourceIs3D&&sourceIs2DCompat ? mipExtent.z:imgParams.arrayLayers)-subresourceRange.baseArrayLayer); - bool checkLayers = true; - auto hasCubemapProporties = [&](bool isItACubemapArray = false) + // the fact that source is 3D is implied by IImage::validateCreationParams + const bool sourceIs2DCompat = imgParams.flags.hasFlags(IImage::ECF_2D_ARRAY_COMPATIBLE_BIT); + if (subresourceRange.layerCount==remaining_array_layers) { - if (!imgParams.flags.hasFlags(IImage::ECF_CUBE_COMPATIBLE_BIT)) - return false; - if (imgParams.samples > 1u) - return false; - if (imgParams.extent.height != imgParams.extent.width) - return false; - if (imgParams.extent.depth > 1u) - return false; - if (actualLayerCount % 6u) - return false; + if (sourceIs2DCompat && _params.viewType!=ET_3D) + actualLayerCount = mipExtent.z; else - if (isItACubemapArray) - { - if (imgParams.arrayLayers < 6u) - return false; - } - else - if (imgParams.arrayLayers != 6u) - return false; - - if (subresourceRange.baseArrayLayer + actualLayerCount > imgParams.arrayLayers) - return false; - return true; - }; + actualLayerCount = imgParams.arrayLayers; + actualLayerCount -= subresourceRange.baseArrayLayer; + } + + // If image was created with the VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT flag, ... or must be an uncompressed format + if (blockTexelViewCompatible && !asset::isBlockCompressionFormat(_params.format)) + { + // In this case, the resulting image view’s texel dimensions equal the dimensions of the selected mip level divided by the compressed texel block size and rounded up. + mipExtent = _params.image->getTexelBlockInfo().convertTexelsToBlocks(mipExtent); + if (subresourceRange.layerCount==remaining_array_layers) + actualLayerCount = 1; + } + const auto endLayer = actualLayerCount+subresourceRange.baseArrayLayer; + bool checkLayers = true; switch (_params.viewType) { case ET_1D: @@ -203,8 +203,6 @@ class IImageView : public IDescriptor return false; [[fallthrough]]; case ET_1D_ARRAY: - if (imgParams.extent.height>1u || imgParams.extent.depth>1u) - return false; break; case ET_2D: if (imgParams.type==IImage::ET_1D) @@ -213,7 +211,7 @@ class IImageView : public IDescriptor return false; [[fallthrough]]; case ET_2D_ARRAY: - if (sourceIs3D) + if (imgParams.type==IImage::ET_3D) { if (!sourceIs2DCompat) return false; @@ -226,16 +224,22 @@ class IImageView : public IDescriptor return false; if (subresourceRange.baseArrayLayer>=mipExtent.z) return false; - if (subresourceRange.baseArrayLayer+actualLayerCount>mipExtent.z) + if (endLayer>mipExtent.z) return false; } break; + case ET_CUBE_MAP: + // https://registry.khronos.org/vulkan/specs/1.2/html/vkspec.html#VUID-VkImageViewCreateInfo-viewType-02960 + // https://registry.khronos.org/vulkan/specs/1.2/html/vkspec.html#VUID-VkImageViewCreateInfo-viewType-02962 + if (actualLayerCount!=6u) + return false; + [[fallthrough]]; case ET_CUBE_MAP_ARRAY: - if (!hasCubemapProporties(true)) + // https://registry.khronos.org/vulkan/specs/1.2/html/vkspec.html#VUID-VkImageViewCreateInfo-viewType-02961 + // https://registry.khronos.org/vulkan/specs/1.2/html/vkspec.html#VUID-VkImageViewCreateInfo-viewType-02963 + if (actualLayerCount%6u) return false; - break; - case ET_CUBE_MAP: - if (!hasCubemapProporties(false)) + if (!imgParams.flags.hasFlags(IImage::ECF_CUBE_COMPATIBLE_BIT)) return false; break; case ET_3D: @@ -245,15 +249,14 @@ class IImageView : public IDescriptor return false; break; } + if (checkLayers) { if (subresourceRange.baseArrayLayer>=imgParams.arrayLayers) return false; - if (subresourceRange.layerCount!=remaining_array_layers && - (subresourceRange.baseArrayLayer+subresourceRange.layerCount>imgParams.arrayLayers)) + if (endLayer>imgParams.arrayLayers) return false; } - return true; } diff --git a/include/nbl/asset/filters/CBlitImageFilter.h b/include/nbl/asset/filters/CBlitImageFilter.h index 12904f333f..15aab5a076 100644 --- a/include/nbl/asset/filters/CBlitImageFilter.h +++ b/include/nbl/asset/filters/CBlitImageFilter.h @@ -87,8 +87,9 @@ class CBlitImageFilter : public CImageFilter; + //using this_t = CBlitImageFilter; - _NBL_STATIC_INLINE_CONSTEXPR auto MaxChannels = blit_utils_t::MaxChannels; + static inline constexpr auto MaxChannels = blit_utils_t::MaxChannels; public: // we'll probably never remove this requirement @@ -96,6 +97,19 @@ class CBlitImageFilter : public CImageFiltergetCreationParameters().type; + const size_t size = blit_utils_t::template getScaledKernelPhasedLUTSize(inExtentLayerCount,outExtentLayerCount,inType,kernelX,kernelY,kernelZ); + auto* lut = base_t::CStateBase::scratchMemory+offset; + return blit_utils_t::template computeScaledKernelPhasedLUT(lut,inExtentLayerCount,outExtentLayerCount,inType,kernelX,kernelY,kernelZ); + } + union { core::vectorSIMDu32 inOffsetBaseLayer; @@ -169,20 +194,6 @@ class CBlitImageFilter : public CImageFilternormalization.finalize(); storeToImage(core::rational(cvg_num,cvg_den),axis,outOffsetLayer); + } }; // filter in X-axis filterAxis(IImage::ET_1D,scaledKernelX); diff --git a/include/nbl/asset/filters/CCopyImageFilter.h b/include/nbl/asset/filters/CCopyImageFilter.h index 496bae08d4..2100bf5777 100644 --- a/include/nbl/asset/filters/CCopyImageFilter.h +++ b/include/nbl/asset/filters/CCopyImageFilter.h @@ -49,7 +49,6 @@ class CCopyImageFilter : public CImageFilter, public CMatchedS return false; return getFormatClass(state->inImage->getCreationParameters().format)==getFormatClass(state->outImage->getCreationParameters().format); - return true; } template diff --git a/include/nbl/asset/filters/CMipMapGenerationImageFilter.h b/include/nbl/asset/filters/CMipMapGenerationImageFilter.h index 5521cf01b1..df75a40551 100644 --- a/include/nbl/asset/filters/CMipMapGenerationImageFilter.h +++ b/include/nbl/asset/filters/CMipMapGenerationImageFilter.h @@ -123,7 +123,7 @@ class CMipMapGenerationImageFilter : public CImageFilter(blit) = *static_cast(state); - pseudo_base_t::blit_utils_t::computeScaledKernelPhasedLUT(blit.scratchMemory + pseudo_base_t::getScratchOffset(&blit, pseudo_base_t::ESU_SCALED_KERNEL_PHASED_LUT), blit.inExtentLayerCount, blit.outExtentLayerCount, blit.inImage->getCreationParameters().type, blit.kernelX, blit.kernelY, blit.kernelZ); + blit.recomputeScaledKernelPhasedLUT(); return blit; } }; diff --git a/include/nbl/asset/filters/CNormalMapToDerivativeFilter.h b/include/nbl/asset/filters/CNormalMapToDerivativeFilter.h index 564bd7dba7..c4d9c75262 100644 --- a/include/nbl/asset/filters/CNormalMapToDerivativeFilter.h +++ b/include/nbl/asset/filters/CNormalMapToDerivativeFilter.h @@ -22,6 +22,9 @@ namespace nbl::asset */ struct NormalMapToDerivativeMapSwizzle { + // since most normalmaps are supplied in RG8_UNORM + double zeroEpsilon = 1.0/255.0; + template void operator()(const InT* in, OutT* out) const { @@ -29,10 +32,12 @@ struct NormalMapToDerivativeMapSwizzle auto* _out = reinterpret_cast,uint64_t,OutT>*>(out); const auto xDecode = _in[0]*2.f-1.f; const auto yDecode = _in[1]*2.f-1.f; + // TODO: a template parameter to decide if Z is in [0,1] or [-1,1] const auto zDecode = _in[2]*2.f-1.f; - _out[0] = -xDecode/zDecode; + // because normalmaps are supplied in UNORM formats, there's no true zero + _out[0] = core::abs(xDecode)>zeroEpsilon ? (-xDecode/zDecode):0.f; // scanlines go from top down, so Y component is in reverse - _out[1] = yDecode/zDecode; + _out[1] = core::abs(yDecode)>zeroEpsilon ? (yDecode/zDecode):0.f; } }; diff --git a/include/nbl/asset/filters/CSwizzleAndConvertImageFilter.h b/include/nbl/asset/filters/CSwizzleAndConvertImageFilter.h index 5938600700..be3ab3a2cc 100644 --- a/include/nbl/asset/filters/CSwizzleAndConvertImageFilter.h +++ b/include/nbl/asset/filters/CSwizzleAndConvertImageFilter.h @@ -1,9 +1,8 @@ // Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h - -#ifndef __NBL_ASSET_C_SWIZZLE_AND_CONVERT_IMAGE_FILTER_H_INCLUDED__ -#define __NBL_ASSET_C_SWIZZLE_AND_CONVERT_IMAGE_FILTER_H_INCLUDED__ +#ifndef _NBL_ASSET_C_SWIZZLE_AND_CONVERT_IMAGE_FILTER_H_INCLUDED_ +#define _NBL_ASSET_C_SWIZZLE_AND_CONVERT_IMAGE_FILTER_H_INCLUDED_ #include "nbl/core/declarations.h" @@ -18,7 +17,6 @@ namespace nbl::asset { - namespace impl { @@ -58,7 +56,7 @@ class CSwizzleAndConvertImageFilterBase : public CSwizzleableAndDitherableFilter if constexpr (!std::is_void_v) { assert(kInFormat==EF_UNKNOWN || rInFormat==EF_UNKNOWN); - state->normalization.template initialize(); + state->normalization.template initialize(); auto perOutputRegion = [policy,&blockDims,&state,rInFormat](const CMatchedSizeInOutImageFilterCommon::CommonExecuteData& commonExecuteData, CBasicImageFilterCommon::clip_region_functor_t& clip) -> bool { auto normalizePrepass = [&commonExecuteData,&blockDims,&state,rInFormat](uint32_t readBlockArrayOffset, core::vectorSIMDu32 readBlockPos) @@ -84,6 +82,7 @@ class CSwizzleAndConvertImageFilterBase : public CSwizzleableAndDitherableFilter return true; }; CMatchedSizeInOutImageFilterCommon::commonExecute(state,perOutputRegion); + state->normalization.finalize(); } } }; diff --git a/include/nbl/asset/filters/NormalizationStates.h b/include/nbl/asset/filters/NormalizationStates.h index 6df361ca70..59e4b4d163 100644 --- a/include/nbl/asset/filters/NormalizationStates.h +++ b/include/nbl/asset/filters/NormalizationStates.h @@ -1,7 +1,6 @@ -// Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O. +// Copyright (C) 2018-2023 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h - #ifndef _NBL_ASSET_NORMALIZATION_STATES_H_INCLUDED_ #define _NBL_ASSET_NORMALIZATION_STATES_H_INCLUDED_ @@ -40,7 +39,7 @@ class CGlobalNormalizationState void prepass(Tenc* encodeBuffer, const core::vectorSIMDu32& position, uint32_t blockX, uint32_t blockY, uint8_t channels) { static_assert(std::is_floating_point_v, "Integer decode not supported yet!"); - for (uint8_t channel=0u; channel<4u; ++channel) + for (uint8_t channel=0u; channel) @@ -112,6 +111,23 @@ namespace impl class CDerivativeMapNormalizationStateBase { + protected: + // we only care about R and G + static inline constexpr uint32_t kChannels = 2; + + template + void impl(Tenc* encodeBuffer, const core::vectorSIMDu32& position, uint32_t blockX, uint32_t blockY, uint8_t channels) const + { + static_assert(std::is_floating_point_v, "Encode types must be double or float!"); + + if constexpr (isSignedFormat) + for (uint8_t channel = 0; channel < kChannels; ++channel) + encodeBuffer[channel] = encodeBuffer[channel]/maxAbsPerChannel[channel]; + else + for (uint8_t channel = 0; channel < kChannels; ++channel) + encodeBuffer[channel] = encodeBuffer[channel]*0.5f/maxAbsPerChannel[channel]+0.5f; + } + public: inline bool validate() const {return true;} @@ -120,7 +136,7 @@ class CDerivativeMapNormalizationStateBase inline void initialize() { static_assert(std::is_floating_point_v, "Integer encode not supported yet!"); - std::fill_n(maxAbsPerChannel,4,0.f); + std::fill_n(maxAbsPerChannel,kChannels,0.f); } // @@ -128,7 +144,7 @@ class CDerivativeMapNormalizationStateBase void prepass(Tenc* encodeBuffer, const core::vectorSIMDu32& position, uint32_t blockX, uint32_t blockY, uint8_t channels) { static_assert(std::is_floating_point_v, "Integer encode not supported yet!"); - for (uint8_t channel=0u; channel<4u; ++channel) + for (uint8_t channel=0u; channel void operator()(E_FORMAT format, Tenc* encodeBuffer, const core::vectorSIMDu32& position, uint32_t blockX, uint32_t blockY, uint8_t channels) const { + assert(channels>=kChannels); #ifdef _NBL_DEBUG bool status = isFloatingPointFormat(format)||isNormalizedFormat(format); assert(status); @@ -155,20 +172,7 @@ class CDerivativeMapNormalizationStateBase impl(encodeBuffer,position,blockX,blockY,channels); } - core::atomic maxAbsPerChannel[4]; - protected: - template - void impl(Tenc* encodeBuffer, const core::vectorSIMDu32& position, uint32_t blockX, uint32_t blockY, uint8_t channels) const - { - static_assert(std::is_floating_point_v, "Encode types must be double or float!"); - - if constexpr (isSignedFormat) - for (uint8_t channel = 0; channel < channels; ++channel) - encodeBuffer[channel] = encodeBuffer[channel]/maxAbsPerChannel[channel]; - else - for (uint8_t channel = 0; channel < channels; ++channel) - encodeBuffer[channel] = encodeBuffer[channel]*0.5f/maxAbsPerChannel[channel]+0.5f; - } + core::atomic maxAbsPerChannel[kChannels]; }; } @@ -183,8 +187,8 @@ class CDerivativeMapNormalizationState : public impl::CDerivativeMapNormalizatio static_assert(std::is_floating_point_v, "Integer encode types not supported yet!"); if constexpr (isotropic) { - const float isotropicMax = core::max(core::max(maxAbsPerChannel[0],maxAbsPerChannel[1]),core::max(maxAbsPerChannel[2],maxAbsPerChannel[3])); - for (auto i=0u; i<4u; i++) + const float isotropicMax = core::max(maxAbsPerChannel[0],maxAbsPerChannel[1]); + for (auto i=0u; i(_NBL_ALIGNED_MALLOC(blit.scratchMemoryByteSize, _NBL_SIMD_ALIGNMENT)); - const core::vectorSIMDu32 inExtent(blit.inExtent.width, blit.inExtent.height, blit.inExtent.depth, 1); - const core::vectorSIMDu32 outExtent(blit.outExtent.width, blit.outExtent.height, blit.outExtent.depth, 1); - if (!blit_filter_t::blit_utils_t::computeScaledKernelPhasedLUT(blit.scratchMemory + blit_filter_t::getScratchOffset(&blit, blit_filter_t::ESU_SCALED_KERNEL_PHASED_LUT), inExtent, outExtent, blit.inImage->getCreationParameters().type, blit.kernelX, blit.kernelY, blit.kernelZ)) + if (!blit.recomputeScaledKernelPhasedLUT()) return nullptr; const bool blit_succeeded = blit_filter_t::execute(&blit); diff --git a/include/nbl/asset/utils/IVirtualTexture.h b/include/nbl/asset/utils/IVirtualTexture.h index 2e7cd894a8..653620aaef 100644 --- a/include/nbl/asset/utils/IVirtualTexture.h +++ b/include/nbl/asset/utils/IVirtualTexture.h @@ -514,9 +514,10 @@ class IVirtualTexture : public core::IReferenceCounted, public IVirtualTextureBa } - virtual void deferredInitialization(uint32_t tileExtent, uint32_t _layers = 0u) + // TODO: refactor into the `_impl` pattern, and always add the MUTABLE FORMAT creation flag + virtual void deferredInitialization(uint32_t tileExtent, uint32_t _layers = 0u/*, TODO: const IImage::E_USAGE_FLAGS usages=IImage::EUF_SAMPLED_BIT, const bool extendedUsage=false*/) { - assert(_layers != 0u); + assert(_layers != 0u); // Why the F have the default be 0 then!? const bool uninitialized = (tileAlctr.get_align_offset() == phys_pg_addr_alctr_t::invalid_address); if (uninitialized) @@ -543,14 +544,16 @@ class IVirtualTexture : public core::IReferenceCounted, public IVirtualTextureBa return x | (y< createView(E_FORMAT _format) const + // last parameter default means to inherit all usages for a view from the main image + core::smart_refctd_ptr createView(E_FORMAT _format, const IImage::E_USAGE_FLAGS usages=IImage::EUF_NONE) const { auto found = m_viewsCache.find(_format); if (found!=m_viewsCache.end()) return found->second; - typename image_view_t::SCreationParams params; + typename image_view_t::SCreationParams params = {}; params.flags = static_cast::E_CREATE_FLAGS>(0); + params.subUsages = usages; params.format = _format; params.subresourceRange.aspectMask = static_cast(0); params.subresourceRange.baseArrayLayer = 0u; diff --git a/include/nbl/builtin/shader/loader/mtl/fragment_impl.glsl b/include/nbl/builtin/shader/loader/mtl/fragment_impl.glsl index e8a25bcdf5..f8886647e8 100644 --- a/include/nbl/builtin/shader/loader/mtl/fragment_impl.glsl +++ b/include/nbl/builtin/shader/loader/mtl/fragment_impl.glsl @@ -74,7 +74,7 @@ vec4 nbl_sample_Ns(in vec2 uv, in mat2 dUV) { return texture(map_Ns, uv); } vec4 nbl_sample_d(in vec2 uv, in mat2 dUV) { return texture(map_d, uv); } #endif #ifndef _NBL_bump_SAMPLE_FUNCTION_DEFINED_ -vec2 nbl_sample_bump(in vec2 uv, in mat2 dUV) { return texture(map_bump, uv).xy * 2.f - vec2(1.f); } +vec2 nbl_sample_bump(in vec2 uv, in mat2 dUV) { return texture(map_bump, uv).xy; } #endif #endif //_NBL_TEXTURE_SAMPLE_FUNCTIONS_DEFINED_ diff --git a/include/nbl/ext/OIT/OIT.h b/include/nbl/ext/OIT/OIT.h index eaf5800c3c..88d1da21a2 100644 --- a/include/nbl/ext/OIT/OIT.h +++ b/include/nbl/ext/OIT/OIT.h @@ -61,7 +61,7 @@ class COIT params.queueFamilyIndexCount = 0; params.queueFamilyIndices = nullptr; params.samples = asset::IImage::ESCF_1_BIT; - params.tiling = asset::IImage::ET_OPTIMAL; + params.tiling = video::IGPUImage::ET_OPTIMAL; params.type = asset::IImage::ET_2D; params.usage = asset::IImage::EUF_STORAGE_BIT; @@ -74,9 +74,10 @@ class COIT if (!img || !imgMem.isValid()) return nullptr; - video::IGPUImageView::SCreationParams vparams; + video::IGPUImageView::SCreationParams vparams = {}; vparams.format = params.format; vparams.flags = static_cast(0); + //vparams.subUsages = ? ? ? ; TODO vparams.viewType = decltype(vparams.viewType)::ET_2D; vparams.subresourceRange.baseArrayLayer = 0u; vparams.subresourceRange.layerCount = 1u; diff --git a/include/nbl/ext/ScreenShot/ScreenShot.h b/include/nbl/ext/ScreenShot/ScreenShot.h index 0e20625760..45216ef893 100644 --- a/include/nbl/ext/ScreenShot/ScreenShot.h +++ b/include/nbl/ext/ScreenShot/ScreenShot.h @@ -155,7 +155,7 @@ inline core::smart_refctd_ptr createScreenShot( { auto newCreationParams = cpuNewImage->getCreationParameters(); - asset::ICPUImageView::SCreationParams viewParams; + asset::ICPUImageView::SCreationParams viewParams = {}; viewParams.flags = static_cast(0u); viewParams.image = cpuNewImage; viewParams.format = newCreationParams.format; diff --git a/include/nbl/ext/ToneMapper/CToneMapper.h b/include/nbl/ext/ToneMapper/CToneMapper.h index 8a4ef86289..90c5dc4570 100644 --- a/include/nbl/ext/ToneMapper/CToneMapper.h +++ b/include/nbl/ext/ToneMapper/CToneMapper.h @@ -198,8 +198,9 @@ class CToneMapper : public core::IReferenceCounted, public core::InterfaceUnmova auto nativeFormat = image->getCreationParameters().format; - video::IGPUImageView::SCreationParams params; + video::IGPUImageView::SCreationParams params = {}; params.flags = static_cast(0u); + //params.subUsages = ? ? ? ; TODO params.image = std::move(image); params.viewType = video::IGPUImageView::ET_2D_ARRAY; params.format = usedAsInput ? getInputViewFormat(nativeFormat):getOutputViewFormat(nativeFormat); diff --git a/include/nbl/video/IGPUImage.h b/include/nbl/video/IGPUImage.h index ff94cdb0b8..4743c133f3 100644 --- a/include/nbl/video/IGPUImage.h +++ b/include/nbl/video/IGPUImage.h @@ -28,7 +28,6 @@ class IGPUImage : public asset::IImage, public IDeviceMemoryBacked, public IBack }; struct SCreationParams : asset::IImage::SCreationParams, IDeviceMemoryBacked::SCreationParams { - // stuff below is irrelevant in OpenGL backend E_TILING tiling = ET_OPTIMAL; E_LAYOUT initialLayout = EL_UNDEFINED; @@ -39,6 +38,12 @@ class IGPUImage : public asset::IImage, public IDeviceMemoryBacked, public IBack } }; + //! + inline E_TILING getTiling() const {return m_tiling;} + + //! + inline E_LAYOUT getInitialLayout() const { return m_initialLayout; } + //! E_OBJECT_TYPE getObjectType() const override { return EOT_IMAGE; } @@ -143,6 +148,8 @@ class IGPUImage : public asset::IImage, public IDeviceMemoryBacked, public IBack virtual const void* getNativeHandle() const = 0; protected: + const E_TILING m_tiling; + const E_LAYOUT m_initialLayout; _NBL_INTERFACE_CHILD(IGPUImage) {} @@ -150,7 +157,7 @@ class IGPUImage : public asset::IImage, public IDeviceMemoryBacked, public IBack IGPUImage(core::smart_refctd_ptr&& dev, const IDeviceMemoryBacked::SDeviceMemoryRequirements& reqs, SCreationParams&& _params - ) : IImage(_params), IDeviceMemoryBacked(std::move(_params),reqs), IBackendObject(std::move(dev)) {} + ) : IImage(_params), IDeviceMemoryBacked(std::move(_params),reqs), IBackendObject(std::move(dev)), m_tiling(_params.tiling), m_initialLayout(_params.initialLayout) {} }; diff --git a/include/nbl/video/utilities/IGPUObjectFromAssetConverter.h b/include/nbl/video/utilities/IGPUObjectFromAssetConverter.h index 2ab6c86b86..c23c233b1d 100644 --- a/include/nbl/video/utilities/IGPUObjectFromAssetConverter.h +++ b/include/nbl/video/utilities/IGPUObjectFromAssetConverter.h @@ -785,16 +785,13 @@ auto IGPUObjectFromAssetConverter::create(const asset::ICPUImage** const _begin, const auto assetCount = std::distance(_begin, _end); auto res = core::make_refctd_dynamic_array >(assetCount); - // This should be the other way round because if a queue supports either compute or graphics - // but not the other way round + // TODO: This should be the other way round because if a queue supports either compute or graphics but not the other way round const uint32_t transferFamIx = _params.perQueue[EQU_TRANSFER].queue->getFamilyIndex(); const uint32_t computeFamIx = _params.perQueue[EQU_COMPUTE].queue ? _params.perQueue[EQU_COMPUTE].queue->getFamilyIndex() : transferFamIx; bool oneQueue = _params.perQueue[EQU_TRANSFER].queue == _params.perQueue[EQU_COMPUTE].queue; bool needToGenMips = false; - core::vector imgMemBarriers; - imgMemBarriers.reserve(assetCount); core::unordered_map> img2gpubuf; for (ptrdiff_t i = 0u; i < assetCount; ++i) @@ -847,12 +844,17 @@ auto IGPUObjectFromAssetConverter::create(const asset::ICPUImage** const _begin, } } - auto needToCompMipsForThisImg = [](const asset::ICPUImage* img) -> bool { - if (img->getRegions().size() == 0u) + auto needToCompMipsForThisImg = [](const asset::ICPUImage* img) -> bool + { + if (img->getRegions().empty()) return false; auto format = img->getCreationParameters().format; if (asset::isIntegerFormat(format) || asset::isBlockCompressionFormat(format)) return false; + // its enough to define a single mipmap region above the base level to prevent automatic computation + for (auto& region : img->getRegions()) + if (region.imageSubresource.mipLevel) + return false; return true; }; @@ -1025,36 +1027,59 @@ auto IGPUObjectFromAssetConverter::create(const asset::ICPUImage** const _begin, promotionRequest.originalFormat = params.format; promotionRequest.usages = {}; - const bool integerFmt = asset::isIntegerFormat(params.format); - if (!integerFmt) + // override the mip-count if its not an integer format and there was no mip-pyramid specified + if (params.mipLevels==1u && !asset::isIntegerFormat(params.format)) params.mipLevels = 1u + static_cast(std::log2(static_cast(core::max(core::max(params.extent.width, params.extent.height), params.extent.depth)))); if (cpuimg->getRegions().size()) - { params.usage |= asset::IImage::EUF_TRANSFER_DST_BIT; - } - - if (needToCompMipsForThisImg(cpuimg)) + + const bool computeMips = needToCompMipsForThisImg(cpuimg); + if (computeMips) { - params.usage |= asset::IImage::EUF_TRANSFER_SRC_BIT; + params.usage |= asset::IImage::EUF_TRANSFER_SRC_BIT; // this is for blit + // I'm already adding usage flags for mip-mapping compute shader + params.usage |= asset::IImage::EUF_SAMPLED_BIT; // to read source mips + // but we don't add the STORAGE USAGE // TODO: will change when we do the blit on compute shader. promotionRequest.usages.blitDst = true; promotionRequest.usages.blitSrc = true; } + auto physDev = _params.device->getPhysicalDevice(); promotionRequest.usages = promotionRequest.usages | params.usage; - auto newFormat = _params.utilities->getLogicalDevice()->getPhysicalDevice()->promoteImageFormat(promotionRequest, video::IGPUImage::ET_OPTIMAL); + auto newFormat = physDev->promoteImageFormat(promotionRequest, video::IGPUImage::ET_OPTIMAL); + auto newFormatIsStorable = physDev->getImageFormatUsagesOptimalTiling()[newFormat].storageImage; // If Format Promotion failed try the same usages but with linear tiling. - if (params.format == asset::EF_UNKNOWN) - newFormat = _params.utilities->getLogicalDevice()->getPhysicalDevice()->promoteImageFormat(promotionRequest, video::IGPUImage::ET_LINEAR); + if (newFormat == asset::EF_UNKNOWN) + { + newFormat = physDev->promoteImageFormat(promotionRequest, video::IGPUImage::ET_LINEAR); + newFormatIsStorable = physDev->getImageFormatUsagesLinearTiling()[newFormat].storageImage; + params.tiling = video::IGPUImage::ET_LINEAR; + } - assert(params.format != asset::EF_UNKNOWN); // No feasible supported format found for creating this image + assert(newFormat != asset::EF_UNKNOWN); // No feasible supported format found for creating this image params.format = newFormat; + // now add the STORAGE USAGE + if (computeMips) + { + // formats like SRGB etc. can't be stored to + params.usage |= asset::IImage::EUF_STORAGE_BIT; + // but image views with formats that are store-able can be created + if (!newFormatIsStorable) + { + params.flags |= asset::IImage::ECF_MUTABLE_FORMAT_BIT; + params.flags |= asset::IImage::ECF_EXTENDED_USAGE_BIT; + if (asset::isBlockCompressionFormat(newFormat)) + params.flags |= asset::IImage::ECF_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT; + } + } + auto gpuimg = _params.device->createImage(std::move(params)); auto gpuimgMemReqs = gpuimg->getMemoryReqs(); - gpuimgMemReqs.memoryTypeBits &= _params.device->getPhysicalDevice()->getDeviceLocalMemoryTypeBits(); + gpuimgMemReqs.memoryTypeBits &= physDev->getDeviceLocalMemoryTypeBits(); auto gpuimgMem = _params.device->allocate(gpuimgMemReqs, gpuimg.get()); res->operator[](i) = std::move(gpuimg); @@ -1095,12 +1120,8 @@ auto IGPUObjectFromAssetConverter::create(const asset::ICPUImage** const _begin, if (needToCompMipsForThisImg(cpuimg)) { - // Todo(achal): Remove this API check once OpenGL(ES) does its format usage reporting correctly - if (_params.device->getAPIType() == EAT_VULKAN) - { - assert(_params.device->getPhysicalDevice()->getImageFormatUsagesOptimalTiling()[gpuimg->getCreationParameters().format].sampledImage); - assert(asset::isFloatingPointFormat(gpuimg->getCreationParameters().format) || asset::isNormalizedFormat(gpuimg->getCreationParameters().format)); // // for blits, can lift are polyphase compute - } + assert(_params.device->getPhysicalDevice()->getImageFormatUsagesOptimalTiling()[gpuimg->getCreationParameters().format].sampledImage); + assert(asset::isFloatingPointFormat(gpuimg->getCreationParameters().format) || asset::isNormalizedFormat(gpuimg->getCreationParameters().format)); cmdComputeMip(cpuimg, gpuimg, newLayout); } else @@ -1525,20 +1546,55 @@ inline created_gpu_object_array IGPUObjectFromAssetConvert core::vector redirs = eliminateDuplicatesAndGenRedirs(cpuDeps); auto gpuDeps = getGPUObjectsFromAssets(cpuDeps.data(), cpuDeps.data() + cpuDeps.size(), _params); - + const auto physDev = _params.device->getPhysicalDevice(); + const auto& optimalUsages = physDev->getImageFormatUsagesOptimalTiling(); + const auto& linearUsages = physDev->getImageFormatUsagesLinearTiling(); for (ptrdiff_t i = 0; i < assetCount; ++i) { if (gpuDeps->begin()[redirs[i]]) { - const asset::ICPUImageView::SCreationParams& cpuparams = _begin[i]->getCreationParameters(); + const auto& cpuParams = _begin[i]->getCreationParameters(); + IGPUImageView::SCreationParams params = {}; - params.flags = static_cast(cpuparams.flags); + params.flags = static_cast(cpuParams.flags); + params.viewType = static_cast(cpuParams.viewType); params.image = (*gpuDeps)[redirs[i]]; - params.viewType = static_cast(cpuparams.viewType); - params.format = params.image->getCreationParameters().format; - memcpy(¶ms.components, &cpuparams.components, sizeof(params.components)); - params.subresourceRange = cpuparams.subresourceRange; - params.subresourceRange.levelCount = (*gpuDeps)[redirs[i]]->getCreationParameters().mipLevels - params.subresourceRange.baseMipLevel; + const auto& gpuImgParams = params.image->getCreationParameters(); + // override the view's format if the source image got promoted, a bit crude, but don't want to scratch my head about how to promote the views and guess semantics + const bool formatGotPromoted = asset::getFormatClass(cpuParams.format)!=asset::getFormatClass(gpuImgParams.format); + params.format = formatGotPromoted ? gpuImgParams.format:cpuParams.format; + params.subUsages = cpuParams.subUsages; + // TODO: In Asset Converter 2.0 we'd pass through all descriptor sets etc and propagate the adding usages backwards to views, but here we need to trim the image's usages instead + { + IPhysicalDevice::SFormatImageUsages::SUsage validUsages(gpuImgParams.usage); + if (params.image->getTiling()!=IGPUImage::ET_LINEAR) + validUsages = validUsages & optimalUsages[params.format]; + else + validUsages = validUsages & linearUsages[params.format]; + // add them after trimming + if (validUsages.sampledImage) + params.subUsages |= IGPUImage::EUF_SAMPLED_BIT; + if (validUsages.storageImage) + params.subUsages |= IGPUImage::EUF_STORAGE_BIT; + if (validUsages.attachment) + { + if (asset::isDepthOrStencilFormat(params.format)) + params.subUsages |= IGPUImage::EUF_DEPTH_STENCIL_ATTACHMENT_BIT; + else + params.subUsages |= IGPUImage::EUF_COLOR_ATTACHMENT_BIT; + } + if (validUsages.transferSrc) + params.subUsages |= IGPUImage::EUF_TRANSFER_SRC_BIT; + if (validUsages.transferDst) + params.subUsages |= IGPUImage::EUF_TRANSFER_DST_BIT; + // stuff thats not dependent on device caps + const auto uncappedUsages = IGPUImage::EUF_TRANSIENT_ATTACHMENT_BIT|IGPUImage::EUF_INPUT_ATTACHMENT_BIT|IGPUImage::EUF_SHADING_RATE_IMAGE_BIT_NV|IGPUImage::EUF_FRAGMENT_DENSITY_MAP_BIT_EXT; + params.subUsages |= gpuImgParams.usage&uncappedUsages; + } + memcpy(¶ms.components, &cpuParams.components, sizeof(params.components)); + params.subresourceRange = cpuParams.subresourceRange; + // TODO: Undo this, make all loaders set the level and layer counts on image views to `ICPUImageView::remaining_...` + params.subresourceRange.levelCount = gpuImgParams.mipLevels-params.subresourceRange.baseMipLevel; (*res)[i] = _params.device->createImageView(std::move(params)); } } diff --git a/include/nbl/video/utilities/IGPUVirtualTexture.h b/include/nbl/video/utilities/IGPUVirtualTexture.h index 9a7e8d3efa..d0138a3fee 100644 --- a/include/nbl/video/utilities/IGPUVirtualTexture.h +++ b/include/nbl/video/utilities/IGPUVirtualTexture.h @@ -157,7 +157,7 @@ class IGPUVirtualTexture final : public asset::IVirtualTexture(0); - // TODO: final layout should be readonly (if there's transfer necessary, then we start in transfer dst) and usage is shader sampled texture + // TODO: final layout should be readonly (if there's transfer necessary, then we start in transfer dst) image = m_logicalDevice->createImage(std::move(params)); m_logicalDevice->allocate(image->getMemoryReqs(), image.get()); diff --git a/src/nbl/asset/IAssetManager.cpp b/src/nbl/asset/IAssetManager.cpp index 19614addd5..ba6fd4814a 100644 --- a/src/nbl/asset/IAssetManager.cpp +++ b/src/nbl/asset/IAssetManager.cpp @@ -363,7 +363,7 @@ void IAssetManager::insertBuiltinAssets() info.arrayLayers = 1u; info.samples = asset::ICPUImage::ESCF_1_BIT; info.flags = static_cast(0u); - info.usage = static_cast(asset::IImage::EUF_COLOR_ATTACHMENT_BIT | asset::IImage::EUF_INPUT_ATTACHMENT_BIT | asset::IImage::EUF_SAMPLED_BIT | asset::IImage::EUF_STORAGE_BIT); + info.usage = static_cast(asset::IImage::EUF_INPUT_ATTACHMENT_BIT | asset::IImage::EUF_SAMPLED_BIT); auto buf = core::make_smart_refctd_ptr(info.extent.width*info.extent.height*asset::getTexelOrBlockBytesize(info.format)); memcpy(buf->getPointer(), //magenta-grey 2x2 chessboard @@ -389,11 +389,11 @@ void IAssetManager::insertBuiltinAssets() //image views { - asset::ICPUImageView::SCreationParams info; + asset::ICPUImageView::SCreationParams info = {}; + info.flags = static_cast(0u); info.format = dummy2dImage->getCreationParameters().format; info.image = dummy2dImage; info.viewType = asset::IImageView::ET_2D; - info.flags = static_cast(0u); info.subresourceRange.aspectMask = asset::IImage::EAF_COLOR_BIT; info.subresourceRange.baseArrayLayer = 0u; info.subresourceRange.layerCount = 1u; diff --git a/src/nbl/asset/interchange/CGLILoader.cpp b/src/nbl/asset/interchange/CGLILoader.cpp index 51a25e4981..f30cc44710 100644 --- a/src/nbl/asset/interchange/CGLILoader.cpp +++ b/src/nbl/asset/interchange/CGLILoader.cpp @@ -118,20 +118,20 @@ namespace nbl auto texelBuffer = core::make_smart_refctd_ptr(texture.size()); auto data = reinterpret_cast(texelBuffer->getPointer()); - ICPUImage::SCreationParams imageInfo; - imageInfo.format = format.first; + ICPUImage::SCreationParams imageInfo = {}; imageInfo.type = imageType; - imageInfo.flags = isItACubemap ? ICPUImage::E_CREATE_FLAGS::ECF_CUBE_COMPATIBLE_BIT : static_cast(0u); imageInfo.samples = ICPUImage::ESCF_1_BIT; + imageInfo.format = format.first; imageInfo.extent.width = texture.extent().x; imageInfo.extent.height = texture.extent().y; imageInfo.extent.depth = texture.extent().z; imageInfo.mipLevels = texture.levels(); imageInfo.arrayLayers = texture.faces() * texture.layers(); - - auto image = ICPUImage::create(std::move(imageInfo)); + imageInfo.flags = isItACubemap ? ICPUImage::E_CREATE_FLAGS::ECF_CUBE_COMPATIBLE_BIT : static_cast(0u); + imageInfo.usage = IImage::EUF_SAMPLED_BIT; auto regions = core::make_refctd_dynamic_array>(imageInfo.mipLevels); + auto image = ICPUImage::create(std::move(imageInfo)); auto getFullSizeOfRegion = [&](const uint16_t mipLevel) -> uint64_t { @@ -203,7 +203,7 @@ namespace nbl image->setBufferAndRegions(std::move(texelBuffer), regions); - ICPUImageView::SCreationParams imageViewInfo; + ICPUImageView::SCreationParams imageViewInfo = {}; imageViewInfo.image = std::move(image); imageViewInfo.format = imageViewInfo.image->getCreationParameters().format; imageViewInfo.viewType = imageViewType; diff --git a/src/nbl/asset/interchange/CGraphicsPipelineLoaderMTL.cpp b/src/nbl/asset/interchange/CGraphicsPipelineLoaderMTL.cpp index be47d53c11..95bff80978 100644 --- a/src/nbl/asset/interchange/CGraphicsPipelineLoaderMTL.cpp +++ b/src/nbl/asset/interchange/CGraphicsPipelineLoaderMTL.cpp @@ -680,7 +680,7 @@ CGraphicsPipelineLoaderMTL::image_views_set_t CGraphicsPipelineLoaderMTL::loadIm const bool isCubemap = (i == CMTLMetadata::CRenderpassIndependentPipeline::EMP_REFL_POSX); - ICPUImageView::SCreationParams viewParams; + ICPUImageView::SCreationParams viewParams = {}; viewParams.flags = static_cast(0u); viewParams.format = image->getCreationParameters().format; viewParams.viewType = viewType[isCubemap]; diff --git a/src/nbl/asset/utils/CDerivativeMapCreator.cpp b/src/nbl/asset/utils/CDerivativeMapCreator.cpp index 957cd640b6..d0516bb7ee 100644 --- a/src/nbl/asset/utils/CDerivativeMapCreator.cpp +++ b/src/nbl/asset/utils/CDerivativeMapCreator.cpp @@ -187,6 +187,7 @@ core::smart_refctd_ptr CDerivativeMapCreator::createDerivativeMapFrom state.scratchMemoryByteSize = DerivativeMapFilter::getRequiredScratchByteSize(&state); state.scratchMemory = reinterpret_cast(_NBL_ALIGNED_MALLOC(state.scratchMemoryByteSize, _NBL_SIMD_ALIGNMENT)); + state.recomputeScaledKernelPhasedLUT(); const bool result = DerivativeMapFilter::execute(core::execution::par_unseq,&state); if (result) { @@ -206,7 +207,7 @@ core::smart_refctd_ptr CDerivativeMapCreator::createDerivativeMap auto img = createDerivativeMapFromHeightMap(_inImg, _uwrap, _vwrap, _borderColor, out_normalizationFactor); const auto& iparams = img->getCreationParameters(); - ICPUImageView::SCreationParams params; + ICPUImageView::SCreationParams params = {}; params.format = iparams.format; params.subresourceRange.baseArrayLayer = 0u; params.subresourceRange.layerCount = iparams.arrayLayers; @@ -306,7 +307,7 @@ core::smart_refctd_ptr CDerivativeMapCreator::createDerivativeMap { auto cpuDerivativeImage = createDerivativeMapFromNormalMap(_inImg,out_normalizationFactor); - ICPUImageView::SCreationParams imageViewInfo; + ICPUImageView::SCreationParams imageViewInfo = {}; imageViewInfo.image = core::smart_refctd_ptr(cpuDerivativeImage); imageViewInfo.format = imageViewInfo.image->getCreationParameters().format; imageViewInfo.viewType = decltype(imageViewInfo.viewType)::ET_2D; diff --git a/src/nbl/video/CVulkanCommandBuffer.cpp b/src/nbl/video/CVulkanCommandBuffer.cpp index e86f8fb305..1c68c438e1 100644 --- a/src/nbl/video/CVulkanCommandBuffer.cpp +++ b/src/nbl/video/CVulkanCommandBuffer.cpp @@ -85,14 +85,14 @@ bool CVulkanCommandBuffer::copyImage_impl(const image_t* srcImage, asset::IImage VkImageCopy vk_regions[MAX_COUNT]; for (uint32_t i = 0u; i < regionCount; ++i) { - vk_regions[i].srcSubresource.aspectMask = static_cast(pRegions[i].srcSubresource.aspectMask); + vk_regions[i].srcSubresource.aspectMask = static_cast(pRegions[i].srcSubresource.aspectMask.value); vk_regions[i].srcSubresource.baseArrayLayer = pRegions[i].srcSubresource.baseArrayLayer; vk_regions[i].srcSubresource.layerCount = pRegions[i].srcSubresource.layerCount; vk_regions[i].srcSubresource.mipLevel = pRegions[i].srcSubresource.mipLevel; vk_regions[i].srcOffset = { static_cast(pRegions[i].srcOffset.x), static_cast(pRegions[i].srcOffset.y), static_cast(pRegions[i].srcOffset.z) }; - vk_regions[i].dstSubresource.aspectMask = static_cast(pRegions[i].dstSubresource.aspectMask); + vk_regions[i].dstSubresource.aspectMask = static_cast(pRegions[i].dstSubresource.aspectMask.value); vk_regions[i].dstSubresource.baseArrayLayer = pRegions[i].dstSubresource.baseArrayLayer; vk_regions[i].dstSubresource.layerCount = pRegions[i].dstSubresource.layerCount; vk_regions[i].dstSubresource.mipLevel = pRegions[i].dstSubresource.mipLevel; @@ -126,7 +126,7 @@ bool CVulkanCommandBuffer::copyBufferToImage_impl(const buffer_t* srcBuffer, ima vk_regions[i].bufferOffset = pRegions[i].bufferOffset; vk_regions[i].bufferRowLength = pRegions[i].bufferRowLength; vk_regions[i].bufferImageHeight = pRegions[i].bufferImageHeight; - vk_regions[i].imageSubresource.aspectMask = static_cast(pRegions[i].imageSubresource.aspectMask); + vk_regions[i].imageSubresource.aspectMask = static_cast(pRegions[i].imageSubresource.aspectMask.value); vk_regions[i].imageSubresource.mipLevel = pRegions[i].imageSubresource.mipLevel; vk_regions[i].imageSubresource.baseArrayLayer = pRegions[i].imageSubresource.baseArrayLayer; vk_regions[i].imageSubresource.layerCount = pRegions[i].imageSubresource.layerCount; @@ -157,7 +157,7 @@ bool CVulkanCommandBuffer::copyImageToBuffer_impl(const image_t* srcImage, asset vk_copyRegions[i].bufferOffset = static_cast(pRegions[i].bufferOffset); vk_copyRegions[i].bufferRowLength = pRegions[i].bufferRowLength; vk_copyRegions[i].bufferImageHeight = pRegions[i].bufferImageHeight; - vk_copyRegions[i].imageSubresource.aspectMask = static_cast(pRegions[i].imageSubresource.aspectMask); + vk_copyRegions[i].imageSubresource.aspectMask = static_cast(pRegions[i].imageSubresource.aspectMask.value); vk_copyRegions[i].imageSubresource.baseArrayLayer = pRegions[i].imageSubresource.baseArrayLayer; vk_copyRegions[i].imageSubresource.layerCount = pRegions[i].imageSubresource.layerCount; vk_copyRegions[i].imageSubresource.mipLevel = pRegions[i].imageSubresource.mipLevel; @@ -188,7 +188,7 @@ bool CVulkanCommandBuffer::blitImage_impl(const image_t* srcImage, asset::IImage for (uint32_t i = 0u; i < regionCount; ++i) { - vk_blitRegions[i].srcSubresource.aspectMask = static_cast(pRegions[i].srcSubresource.aspectMask); + vk_blitRegions[i].srcSubresource.aspectMask = static_cast(pRegions[i].srcSubresource.aspectMask.value); vk_blitRegions[i].srcSubresource.mipLevel = pRegions[i].srcSubresource.mipLevel; vk_blitRegions[i].srcSubresource.baseArrayLayer = pRegions[i].srcSubresource.baseArrayLayer; vk_blitRegions[i].srcSubresource.layerCount = pRegions[i].srcSubresource.layerCount; @@ -197,7 +197,7 @@ bool CVulkanCommandBuffer::blitImage_impl(const image_t* srcImage, asset::IImage vk_blitRegions[i].srcOffsets[0] = { static_cast(pRegions[i].srcOffsets[0].x), static_cast(pRegions[i].srcOffsets[0].y), static_cast(pRegions[i].srcOffsets[0].z) }; vk_blitRegions[i].srcOffsets[1] = { static_cast(pRegions[i].srcOffsets[1].x), static_cast(pRegions[i].srcOffsets[1].y), static_cast(pRegions[i].srcOffsets[1].z) }; - vk_blitRegions[i].dstSubresource.aspectMask = static_cast(pRegions[i].dstSubresource.aspectMask); + vk_blitRegions[i].dstSubresource.aspectMask = static_cast(pRegions[i].dstSubresource.aspectMask.value); vk_blitRegions[i].dstSubresource.mipLevel = pRegions[i].dstSubresource.mipLevel; vk_blitRegions[i].dstSubresource.baseArrayLayer = pRegions[i].dstSubresource.baseArrayLayer; vk_blitRegions[i].dstSubresource.layerCount = pRegions[i].dstSubresource.layerCount; @@ -223,14 +223,14 @@ bool CVulkanCommandBuffer::resolveImage_impl(const image_t* srcImage, asset::IIm VkImageResolve vk_regions[MAX_COUNT]; for (uint32_t i = 0u; i < regionCount; ++i) { - vk_regions[i].srcSubresource.aspectMask = static_cast(pRegions[i].srcSubresource.aspectMask); + vk_regions[i].srcSubresource.aspectMask = static_cast(pRegions[i].srcSubresource.aspectMask.value); vk_regions[i].srcSubresource.baseArrayLayer = pRegions[i].srcSubresource.baseArrayLayer; vk_regions[i].srcSubresource.layerCount = pRegions[i].srcSubresource.layerCount; vk_regions[i].srcSubresource.mipLevel = pRegions[i].srcSubresource.mipLevel; vk_regions[i].srcOffset = { static_cast(pRegions[i].srcOffset.x), static_cast(pRegions[i].srcOffset.y), static_cast(pRegions[i].srcOffset.z) }; - vk_regions[i].dstSubresource.aspectMask = static_cast(pRegions[i].dstSubresource.aspectMask); + vk_regions[i].dstSubresource.aspectMask = static_cast(pRegions[i].dstSubresource.aspectMask.value); vk_regions[i].dstSubresource.baseArrayLayer = pRegions[i].dstSubresource.baseArrayLayer; vk_regions[i].dstSubresource.layerCount = pRegions[i].dstSubresource.layerCount; vk_regions[i].dstSubresource.mipLevel = pRegions[i].dstSubresource.mipLevel; @@ -343,7 +343,7 @@ bool CVulkanCommandBuffer::waitEvents_impl(uint32_t eventCount, event_t* const* vk_imageMemoryBarriers[i].srcQueueFamilyIndex = depInfo->imgBarriers[i].srcQueueFamilyIndex; vk_imageMemoryBarriers[i].dstQueueFamilyIndex = depInfo->imgBarriers[i].dstQueueFamilyIndex; vk_imageMemoryBarriers[i].image = IBackendObject::compatibility_cast(depInfo->imgBarriers[i].image.get(), this)->getInternalObject(); - vk_imageMemoryBarriers[i].subresourceRange.aspectMask = static_cast(depInfo->imgBarriers[i].subresourceRange.aspectMask); + vk_imageMemoryBarriers[i].subresourceRange.aspectMask = static_cast(depInfo->imgBarriers[i].subresourceRange.aspectMask.value); vk_imageMemoryBarriers[i].subresourceRange.baseMipLevel = depInfo->imgBarriers[i].subresourceRange.baseMipLevel; vk_imageMemoryBarriers[i].subresourceRange.levelCount = depInfo->imgBarriers[i].subresourceRange.levelCount; vk_imageMemoryBarriers[i].subresourceRange.baseArrayLayer = depInfo->imgBarriers[i].subresourceRange.baseArrayLayer; @@ -415,7 +415,7 @@ bool CVulkanCommandBuffer::pipelineBarrier_impl(core::bitflag(pImageMemoryBarriers[i].image.get(), this)->getInternalObject(); - vk_imageMemoryBarriers[i].subresourceRange.aspectMask = static_cast(pImageMemoryBarriers[i].subresourceRange.aspectMask); + vk_imageMemoryBarriers[i].subresourceRange.aspectMask = static_cast(pImageMemoryBarriers[i].subresourceRange.aspectMask.value); vk_imageMemoryBarriers[i].subresourceRange.baseMipLevel = pImageMemoryBarriers[i].subresourceRange.baseMipLevel; vk_imageMemoryBarriers[i].subresourceRange.levelCount = pImageMemoryBarriers[i].subresourceRange.levelCount; vk_imageMemoryBarriers[i].subresourceRange.baseArrayLayer = pImageMemoryBarriers[i].subresourceRange.baseArrayLayer; @@ -559,7 +559,7 @@ bool CVulkanCommandBuffer::clearColorImage_impl(image_t* image, asset::IImage::E for (uint32_t i = 0u; i < rangeCount; ++i) { - vk_ranges[i].aspectMask = static_cast(pRanges[i].aspectMask); + vk_ranges[i].aspectMask = static_cast(pRanges[i].aspectMask.value); vk_ranges[i].baseMipLevel = pRanges[i].baseMipLevel; vk_ranges[i].levelCount = pRanges[i].layerCount; vk_ranges[i].baseArrayLayer = pRanges[i].baseArrayLayer; @@ -588,7 +588,7 @@ bool CVulkanCommandBuffer::clearDepthStencilImage_impl(image_t* image, asset::II for (uint32_t i = 0u; i < rangeCount; ++i) { - vk_ranges[i].aspectMask = static_cast(pRanges[i].aspectMask); + vk_ranges[i].aspectMask = static_cast(pRanges[i].aspectMask.value); vk_ranges[i].baseMipLevel = pRanges[i].baseMipLevel; vk_ranges[i].levelCount = pRanges[i].layerCount; vk_ranges[i].baseArrayLayer = pRanges[i].baseArrayLayer; diff --git a/src/nbl/video/CVulkanImageView.h b/src/nbl/video/CVulkanImageView.h index 32eaceb471..e730eebe18 100644 --- a/src/nbl/video/CVulkanImageView.h +++ b/src/nbl/video/CVulkanImageView.h @@ -1,5 +1,5 @@ -#ifndef __NBL_C_VULKAN_IMAGE_VIEW_H_INCLUDED__ -#define __NBL_C_VULKAN_IMAGE_VIEW_H_INCLUDED__ +#ifndef _NBL_C_VULKAN_IMAGE_VIEW_H_INCLUDED_ +#define _NBL_C_VULKAN_IMAGE_VIEW_H_INCLUDED_ #include "nbl/video/IGPUImageView.h" @@ -13,21 +13,20 @@ class ILogicalDevice; class CVulkanImageView final : public IGPUImageView { -public: - CVulkanImageView(core::smart_refctd_ptr&& logicalDevice, - SCreationParams&& _params, VkImageView imageView) - : IGPUImageView(std::move(logicalDevice), std::move(_params)), m_vkImageView(imageView) - {} + public: + CVulkanImageView(core::smart_refctd_ptr&& logicalDevice, SCreationParams&& _params, VkImageView imageView) + : IGPUImageView(std::move(logicalDevice), std::move(_params)), m_vkImageView(imageView) + {} - ~CVulkanImageView(); + ~CVulkanImageView(); - inline const void* getNativeHandle() const override {return &m_vkImageView;} - inline VkImageView getInternalObject() const { return m_vkImageView; } + inline const void* getNativeHandle() const override {return &m_vkImageView;} + inline VkImageView getInternalObject() const { return m_vkImageView; } - void setObjectDebugName(const char* label) const override; + void setObjectDebugName(const char* label) const override; -private: - VkImageView m_vkImageView; + private: + VkImageView m_vkImageView; }; } diff --git a/src/nbl/video/CVulkanLogicalDevice.h b/src/nbl/video/CVulkanLogicalDevice.h index 99a194dbdd..ad2d4384a9 100644 --- a/src/nbl/video/CVulkanLogicalDevice.h +++ b/src/nbl/video/CVulkanLogicalDevice.h @@ -984,8 +984,12 @@ class CVulkanLogicalDevice final : public ILogicalDevice core::smart_refctd_ptr createImageView_impl(IGPUImageView::SCreationParams&& params) override { + // Each pNext member of any structure (including this one) in the pNext chain must be either NULL or a pointer to a valid instance of VkImageViewASTCDecodeModeEXT, VkSamplerYcbcrConversionInfo, VkVideoProfileKHR, or VkVideoProfilesKHR + VkImageViewUsageCreateInfo vk_imageViewUsageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,nullptr }; + vk_imageViewUsageInfo.usage = static_cast((params.subUsages.value ? params.subUsages:params.image->getCreationParameters().usage).value); + VkImageViewCreateInfo vk_createInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; - vk_createInfo.pNext = nullptr; // Each pNext member of any structure (including this one) in the pNext chain must be either NULL or a pointer to a valid instance of VkImageViewASTCDecodeModeEXT, VkImageViewUsageCreateInfo, VkSamplerYcbcrConversionInfo, VkVideoProfileKHR, or VkVideoProfilesKHR + vk_createInfo.pNext = &vk_imageViewUsageInfo; vk_createInfo.flags = static_cast(params.flags); if (params.image->getAPIType() != EAT_VULKAN) @@ -999,7 +1003,7 @@ class CVulkanLogicalDevice final : public ILogicalDevice vk_createInfo.components.g = static_cast(params.components.g); vk_createInfo.components.b = static_cast(params.components.b); vk_createInfo.components.a = static_cast(params.components.a); - vk_createInfo.subresourceRange.aspectMask = static_cast(params.subresourceRange.aspectMask); + vk_createInfo.subresourceRange.aspectMask = static_cast(params.subresourceRange.aspectMask.value); vk_createInfo.subresourceRange.baseMipLevel = params.subresourceRange.baseMipLevel; vk_createInfo.subresourceRange.levelCount = params.subresourceRange.levelCount; vk_createInfo.subresourceRange.baseArrayLayer = params.subresourceRange.baseArrayLayer; diff --git a/src/nbl/video/CVulkanPhysicalDevice.h b/src/nbl/video/CVulkanPhysicalDevice.h index e4540b1153..5b76a42e4d 100644 --- a/src/nbl/video/CVulkanPhysicalDevice.h +++ b/src/nbl/video/CVulkanPhysicalDevice.h @@ -28,70 +28,143 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_availableFeatureSet.insert(vk_extension.extensionName); } - // TODO: Query Properties/Features based on availability of extensions to avoid validation issues about "unknown VkStructureType" + // Basic stuff for constructing pNext chains + VkBaseInStructure* pNextTail; + auto setPNextChainTail = [&pNextTail](void* structure) -> void {pNextTail = reinterpret_cast(structure);}; + auto addToPNextChain = [&pNextTail](void* structure) -> void + { + auto toAdd = reinterpret_cast(structure); + pNextTail->pNext = toAdd; + pNextTail = toAdd; + }; + auto finalizePNextChain = [&pNextTail]() -> void + { + pNextTail->pNext = nullptr; + }; // Get physical device's limits/properties - - // !! Always check the API version is >= 1.3 before using `vulkan13Properties` - VkPhysicalDeviceVulkan13Properties vulkan13Properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES, nullptr }; - VkPhysicalDeviceMaintenance4Properties maintanance4Properties = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES, &vulkan13Properties}; - VkPhysicalDeviceInlineUniformBlockProperties inlineUniformBlockProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES, &maintanance4Properties }; - VkPhysicalDeviceSubgroupSizeControlProperties subgroupSizeControlProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES, &inlineUniformBlockProperties }; - VkPhysicalDeviceTexelBufferAlignmentProperties texelBufferAlignmentProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES, &subgroupSizeControlProperties }; - - // !! Always check the API version is >= 1.2 before using `vulkan12Properties` - VkPhysicalDeviceVulkan12Properties vulkan12Properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES, &texelBufferAlignmentProperties }; - VkPhysicalDeviceDriverProperties driverProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, &vulkan12Properties }; - VkPhysicalDeviceFloatControlsProperties floatControlsProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, &driverProperties }; - VkPhysicalDeviceDescriptorIndexingProperties descriptorIndexingProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES, &floatControlsProperties }; - VkPhysicalDeviceDepthStencilResolveProperties depthStencilResolveProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, &descriptorIndexingProperties }; - VkPhysicalDeviceSamplerFilterMinmaxProperties samplerFilterMinmaxProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, &depthStencilResolveProperties }; - VkPhysicalDeviceTimelineSemaphoreProperties timelineSemaphoreProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES, &samplerFilterMinmaxProperties }; - VkPhysicalDeviceLineRasterizationPropertiesEXT lineRasterizationPropertiesEXT = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT, &timelineSemaphoreProperties }; - VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vertexAttributeDivisorPropertiesEXT = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT, &lineRasterizationPropertiesEXT }; - VkPhysicalDeviceSubpassShadingPropertiesHUAWEI subpassShadingPropertiesHUAWEI = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI, &vertexAttributeDivisorPropertiesEXT }; - VkPhysicalDeviceShaderIntegerDotProductProperties shaderIntegerDotProductProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES, &subpassShadingPropertiesHUAWEI }; - - // !! Our minimum supported Vulkan version is 1.1, no need to check anything before using `vulkan11Properties` - VkPhysicalDeviceVulkan11Properties vulkan11Properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, &shaderIntegerDotProductProperties }; - - // Extensions - VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalMemoryHostPropertiesEXT = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT, &vulkan11Properties }; - VkPhysicalDeviceConservativeRasterizationPropertiesEXT conservativeRasterizationProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT, &externalMemoryHostPropertiesEXT }; - VkPhysicalDeviceShaderCoreProperties2AMD shaderCoreProperties2AMD = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD, &conservativeRasterizationProperties }; - VkPhysicalDeviceShaderSMBuiltinsPropertiesNV shaderSMBuiltinsProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV, &shaderCoreProperties2AMD }; - VkPhysicalDeviceCooperativeMatrixPropertiesNV cooperativeMatrixProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV, &shaderSMBuiltinsProperties }; - VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationsProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT, &cooperativeMatrixProperties }; - VkPhysicalDevicePCIBusInfoPropertiesEXT PCIBusInfoProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT, &sampleLocationsProperties }; - VkPhysicalDeviceDiscardRectanglePropertiesEXT discardRectangleProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT, &PCIBusInfoProperties }; - VkPhysicalDeviceRayTracingPipelinePropertiesKHR rayTracingPipelineProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR, &discardRectangleProperties }; - VkPhysicalDeviceAccelerationStructurePropertiesKHR accelerationStructureProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR, &rayTracingPipelineProperties }; - VkPhysicalDeviceFragmentDensityMapPropertiesEXT fragmentDensityMapProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT, &accelerationStructureProperties }; - VkPhysicalDeviceFragmentDensityMap2PropertiesEXT fragmentDensityMap2Properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT, &fragmentDensityMapProperties }; { - //! Basically remove a query struct from the chain if it's not supported by vulkan version: - //! We need to do these only for `vulkan12Properties` and `vulkan13Properties` since our minimum is Vulkan 1.1 and these two are only provided by VK_VESION_1_2/1_3 (not any extensions) - //! Other structures are provided by VK_XX_EXTENSION or VK_VERSION_XX so no need to check whether we need to remove them from query chain + VkPhysicalDeviceProperties2 deviceProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 }; + setPNextChainTail(&deviceProperties); + // !! Our minimum supported Vulkan version is 1.1, no need to check anything before using `vulkan11Properties` + VkPhysicalDeviceVulkan11Properties vulkan11Properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES }; + addToPNextChain(&vulkan11Properties); + //! Declare all the property structs before so they don't go out of scope + //! Provided by Vk 1.2 + VkPhysicalDeviceVulkan12Properties vulkan12Properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES }; + VkPhysicalDeviceDriverProperties driverProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES }; + VkPhysicalDeviceFloatControlsProperties floatControlsProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES }; + VkPhysicalDeviceDescriptorIndexingProperties descriptorIndexingProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES }; + VkPhysicalDeviceDepthStencilResolveProperties depthStencilResolveProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES }; + VkPhysicalDeviceSamplerFilterMinmaxProperties samplerFilterMinmaxProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES }; + VkPhysicalDeviceTimelineSemaphoreProperties timelineSemaphoreProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES }; + //! Provided by Vk 1.3 + VkPhysicalDeviceVulkan13Properties vulkan13Properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES }; + VkPhysicalDeviceMaintenance4Properties maintanance4Properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES }; + VkPhysicalDeviceInlineUniformBlockProperties inlineUniformBlockProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES }; + VkPhysicalDeviceSubgroupSizeControlProperties subgroupSizeControlProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES }; + VkPhysicalDeviceTexelBufferAlignmentProperties texelBufferAlignmentProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES }; + VkPhysicalDeviceShaderIntegerDotProductProperties shaderIntegerDotProductProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES }; + //! Extensions + VkPhysicalDeviceConservativeRasterizationPropertiesEXT conservativeRasterizationProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT }; + VkPhysicalDeviceDiscardRectanglePropertiesEXT discardRectangleProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT }; + VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalMemoryHostPropertiesEXT = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT }; + VkPhysicalDevicePCIBusInfoPropertiesEXT PCIBusInfoProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT }; + VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationsProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT }; + VkPhysicalDeviceCooperativeMatrixPropertiesNV cooperativeMatrixProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV }; + VkPhysicalDeviceAccelerationStructurePropertiesKHR accelerationStructureProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR }; + VkPhysicalDeviceRayTracingPipelinePropertiesKHR rayTracingPipelineProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR }; + VkPhysicalDeviceFragmentDensityMapPropertiesEXT fragmentDensityMapProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT }; + VkPhysicalDeviceFragmentDensityMap2PropertiesEXT fragmentDensityMap2Properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT }; + VkPhysicalDeviceLineRasterizationPropertiesEXT lineRasterizationPropertiesEXT = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT }; + VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vertexAttributeDivisorPropertiesEXT = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT }; + VkPhysicalDeviceSubpassShadingPropertiesHUAWEI subpassShadingPropertiesHUAWEI = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI }; + VkPhysicalDeviceShaderSMBuiltinsPropertiesNV shaderSMBuiltinsProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV }; + VkPhysicalDeviceShaderCoreProperties2AMD shaderCoreProperties2AMD = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD }; //! This is only written for convenience to avoid getting validation errors otherwise vulkan will just skip any strutctures it doesn't recognize - if(instanceApiVersion < VK_MAKE_API_VERSION(0, 1, 2, 0)) + if (instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)) { - assert(driverProperties.pNext == &vulkan12Properties); - driverProperties.pNext = vulkan12Properties.pNext; + addToPNextChain(&vulkan12Properties); + addToPNextChain(&driverProperties); + addToPNextChain(&floatControlsProperties); + addToPNextChain(&descriptorIndexingProperties); + addToPNextChain(&depthStencilResolveProperties); + addToPNextChain(&samplerFilterMinmaxProperties); + addToPNextChain(&timelineSemaphoreProperties); } - if(instanceApiVersion < VK_MAKE_API_VERSION(0, 1, 3, 0)) + else { - assert(maintanance4Properties.pNext == &vulkan13Properties); - maintanance4Properties.pNext = vulkan13Properties.pNext; + assert(isExtensionSupported(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)); + addToPNextChain(&driverProperties); + if (isExtensionSupported(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME)) + addToPNextChain(&floatControlsProperties); + if (isExtensionSupported(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) + addToPNextChain(&descriptorIndexingProperties); + if (isExtensionSupported(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME)) + addToPNextChain(&depthStencilResolveProperties); + if (isExtensionSupported(VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME)) + addToPNextChain(&samplerFilterMinmaxProperties); + if (isExtensionSupported(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)) + addToPNextChain(&timelineSemaphoreProperties); + } + if (instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)) + { + addToPNextChain(&vulkan13Properties); // old validation layers might complain about this struct in pNext, all is fine + addToPNextChain(&maintanance4Properties); // old validation layers might complain about this struct in pNext, all is fine + addToPNextChain(&inlineUniformBlockProperties); + addToPNextChain(&subgroupSizeControlProperties); + addToPNextChain(&texelBufferAlignmentProperties); + addToPNextChain(&shaderIntegerDotProductProperties); // old validation layers might complain about this struct in pNext, all is fine } - - - VkPhysicalDeviceProperties2 deviceProperties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 }; - deviceProperties.pNext = &fragmentDensityMap2Properties; + else + { + if (isExtensionSupported(VK_KHR_MAINTENANCE_4_EXTENSION_NAME)) + addToPNextChain(&maintanance4Properties); + if (isExtensionSupported(VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME)) + addToPNextChain(&inlineUniformBlockProperties); + if (isExtensionSupported(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME)) + addToPNextChain(&subgroupSizeControlProperties); + if (isExtensionSupported(VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME)) + addToPNextChain(&texelBufferAlignmentProperties); + if (isExtensionSupported(VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME)) + addToPNextChain(&shaderIntegerDotProductProperties); + } + if (isExtensionSupported(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) + addToPNextChain(&conservativeRasterizationProperties); + if (isExtensionSupported(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME)) + addToPNextChain(&discardRectangleProperties); + if (isExtensionSupported(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME)) + addToPNextChain(&externalMemoryHostPropertiesEXT); + if (isExtensionSupported(VK_EXT_PCI_BUS_INFO_EXTENSION_NAME)) + addToPNextChain(&PCIBusInfoProperties); + if (isExtensionSupported(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME)) + addToPNextChain(&sampleLocationsProperties); + if (isExtensionSupported(VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME)) + addToPNextChain(&cooperativeMatrixProperties); + if (isExtensionSupported(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME)) + addToPNextChain(&accelerationStructureProperties); + if (isExtensionSupported(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME)) + addToPNextChain(&rayTracingPipelineProperties); + if (isExtensionSupported(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME)) + addToPNextChain(&fragmentDensityMapProperties); + if (isExtensionSupported(VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME)) + addToPNextChain(&fragmentDensityMap2Properties); + if (isExtensionSupported(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME)) + addToPNextChain(&lineRasterizationPropertiesEXT); + if (isExtensionSupported(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) + addToPNextChain(&vertexAttributeDivisorPropertiesEXT); + if (isExtensionSupported(VK_HUAWEI_SUBPASS_SHADING_EXTENSION_NAME)) + addToPNextChain(&subpassShadingPropertiesHUAWEI); + if (isExtensionSupported(VK_NV_SHADER_SM_BUILTINS_EXTENSION_NAME)) + addToPNextChain(&shaderSMBuiltinsProperties); + if (isExtensionSupported(VK_AMD_SHADER_CORE_PROPERTIES_2_EXTENSION_NAME)) + addToPNextChain(&shaderCoreProperties2AMD); + // call + finalizePNextChain(); vkGetPhysicalDeviceProperties2(m_vkPhysicalDevice, &deviceProperties); - /* Vulkan 1.0 Core */ - - uint32_t apiVersion = std::min(instanceApiVersion, deviceProperties.properties.apiVersion); + //! Vulkan 1.0 Core + const uint32_t apiVersion = std::min(instanceApiVersion,deviceProperties.properties.apiVersion); assert(apiVersion >= MinimumVulkanApiVersion); m_properties.apiVersion.major = VK_API_VERSION_MAJOR(apiVersion); m_properties.apiVersion.minor = VK_API_VERSION_MINOR(apiVersion); @@ -102,20 +175,20 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_properties.deviceID = deviceProperties.properties.deviceID; switch(deviceProperties.properties.deviceType) { - case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: - m_properties.deviceType = E_TYPE::ET_INTEGRATED_GPU; - break; - case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: - m_properties.deviceType = E_TYPE::ET_DISCRETE_GPU; - break; - case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: - m_properties.deviceType = E_TYPE::ET_VIRTUAL_GPU; - break; - case VK_PHYSICAL_DEVICE_TYPE_CPU: - m_properties.deviceType = E_TYPE::ET_CPU; - break; - default: - m_properties.deviceType = E_TYPE::ET_UNKNOWN; + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: + m_properties.deviceType = E_TYPE::ET_INTEGRATED_GPU; + break; + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: + m_properties.deviceType = E_TYPE::ET_DISCRETE_GPU; + break; + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: + m_properties.deviceType = E_TYPE::ET_VIRTUAL_GPU; + break; + case VK_PHYSICAL_DEVICE_TYPE_CPU: + m_properties.deviceType = E_TYPE::ET_CPU; + break; + default: + m_properties.deviceType = E_TYPE::ET_UNKNOWN; } memcpy(m_properties.deviceName, deviceProperties.properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); memcpy(m_properties.pipelineCacheUUID, deviceProperties.properties.pipelineCacheUUID, VK_UUID_SIZE); @@ -264,7 +337,7 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice bool isAMDGPU = (m_properties.driverID == E_DRIVER_ID::EDI_AMD_OPEN_SOURCE || m_properties.driverID == E_DRIVER_ID::EDI_AMD_PROPRIETARY); bool isNVIDIAGPU = (m_properties.driverID == E_DRIVER_ID::EDI_NVIDIA_PROPRIETARY); - if(isExtensionSupported(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME)) + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME)) { m_properties.limits.shaderSignedZeroInfNanPreserveFloat16 = floatControlsProperties.shaderSignedZeroInfNanPreserveFloat16 ? SPhysicalDeviceLimits::ETB_TRUE : SPhysicalDeviceLimits::ETB_FALSE; m_properties.limits.shaderSignedZeroInfNanPreserveFloat32 = floatControlsProperties.shaderSignedZeroInfNanPreserveFloat32 ? SPhysicalDeviceLimits::ETB_TRUE : SPhysicalDeviceLimits::ETB_FALSE; @@ -283,7 +356,7 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_properties.limits.shaderRoundingModeRTZFloat64 = floatControlsProperties.shaderRoundingModeRTZFloat64 ? SPhysicalDeviceLimits::ETB_TRUE : SPhysicalDeviceLimits::ETB_FALSE; } - if(isExtensionSupported(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) { m_properties.limits.maxUpdateAfterBindDescriptorsInAllPools = descriptorIndexingProperties.maxUpdateAfterBindDescriptorsInAllPools; m_properties.limits.shaderUniformBufferArrayNonUniformIndexingNative = descriptorIndexingProperties.shaderUniformBufferArrayNonUniformIndexingNative; @@ -310,19 +383,19 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_properties.limits.maxDescriptorSetUpdateAfterBindInputAttachments = descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindInputAttachments; } - if(isExtensionSupported(VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME)) + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME)) { m_properties.limits.filterMinmaxSingleComponentFormats = samplerFilterMinmaxProperties.filterMinmaxSingleComponentFormats; m_properties.limits.filterMinmaxImageComponentMapping = samplerFilterMinmaxProperties.filterMinmaxImageComponentMapping; } /* Vulkan 1.3 Core */ - if(isExtensionSupported(VK_KHR_MAINTENANCE_4_EXTENSION_NAME)) + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)||isExtensionSupported(VK_KHR_MAINTENANCE_4_EXTENSION_NAME)) m_properties.limits.maxBufferSize = maintanance4Properties.maxBufferSize; else m_properties.limits.maxBufferSize = vulkan11Properties.maxMemoryAllocationSize; - if(isExtensionSupported(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME)) + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)||isExtensionSupported(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME)) { m_properties.limits.minSubgroupSize = subgroupSizeControlProperties.minSubgroupSize; m_properties.limits.maxSubgroupSize = subgroupSizeControlProperties.maxSubgroupSize; @@ -334,7 +407,7 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice getMinMaxSubgroupSizeFromDriverID(m_properties.driverID, m_properties.limits.minSubgroupSize, m_properties.limits.maxSubgroupSize); } - if (isExtensionSupported(VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME)) + if (instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)||isExtensionSupported(VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME)) { m_properties.limits.storageTexelBufferOffsetAlignmentBytes = texelBufferAlignmentProperties.storageTexelBufferOffsetAlignmentBytes; m_properties.limits.uniformTexelBufferOffsetAlignmentBytes = texelBufferAlignmentProperties.uniformTexelBufferOffsetAlignmentBytes; @@ -345,7 +418,42 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_properties.limits.uniformTexelBufferOffsetAlignmentBytes = deviceProperties.properties.limits.minTexelBufferOffsetAlignment; } - /* Extensions */ + if (instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)||isExtensionSupported(VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME)) + { + m_properties.limits.integerDotProduct8BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct8BitUnsignedAccelerated; + m_properties.limits.integerDotProduct8BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct8BitSignedAccelerated; + m_properties.limits.integerDotProduct8BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProduct8BitMixedSignednessAccelerated; + m_properties.limits.integerDotProduct4x8BitPackedUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct4x8BitPackedUnsignedAccelerated; + m_properties.limits.integerDotProduct4x8BitPackedSignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct4x8BitPackedSignedAccelerated; + m_properties.limits.integerDotProduct4x8BitPackedMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProduct4x8BitPackedMixedSignednessAccelerated; + m_properties.limits.integerDotProduct16BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct16BitUnsignedAccelerated; + m_properties.limits.integerDotProduct16BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct16BitSignedAccelerated; + m_properties.limits.integerDotProduct16BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProduct16BitMixedSignednessAccelerated; + m_properties.limits.integerDotProduct32BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct32BitUnsignedAccelerated; + m_properties.limits.integerDotProduct32BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct32BitSignedAccelerated; + m_properties.limits.integerDotProduct32BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProduct32BitMixedSignednessAccelerated; + m_properties.limits.integerDotProduct64BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct64BitUnsignedAccelerated; + m_properties.limits.integerDotProduct64BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct64BitSignedAccelerated; + m_properties.limits.integerDotProduct64BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProduct64BitMixedSignednessAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating8BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating8BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating8BitSignedAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating16BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating16BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating16BitSignedAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating32BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating32BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating32BitSignedAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating64BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating64BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating64BitSignedAccelerated; + m_properties.limits.integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; + } + + + //! Extensions /* ConservativeRasterizationPropertiesEXT */ if (isExtensionSupported(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) @@ -454,43 +562,7 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_properties.limits.maxSubpassShadingWorkgroupSizeAspectRatio = subpassShadingPropertiesHUAWEI.maxSubpassShadingWorkgroupSizeAspectRatio; } - /* VkPhysicalDeviceShaderIntegerDotProductProperties */ - if (isExtensionSupported(VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME)) - { - m_properties.limits.integerDotProduct8BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct8BitUnsignedAccelerated; - m_properties.limits.integerDotProduct8BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct8BitSignedAccelerated; - m_properties.limits.integerDotProduct8BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProduct8BitMixedSignednessAccelerated; - m_properties.limits.integerDotProduct4x8BitPackedUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct4x8BitPackedUnsignedAccelerated; - m_properties.limits.integerDotProduct4x8BitPackedSignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct4x8BitPackedSignedAccelerated; - m_properties.limits.integerDotProduct4x8BitPackedMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProduct4x8BitPackedMixedSignednessAccelerated; - m_properties.limits.integerDotProduct16BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct16BitUnsignedAccelerated; - m_properties.limits.integerDotProduct16BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct16BitSignedAccelerated; - m_properties.limits.integerDotProduct16BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProduct16BitMixedSignednessAccelerated; - m_properties.limits.integerDotProduct32BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct32BitUnsignedAccelerated; - m_properties.limits.integerDotProduct32BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct32BitSignedAccelerated; - m_properties.limits.integerDotProduct32BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProduct32BitMixedSignednessAccelerated; - m_properties.limits.integerDotProduct64BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct64BitUnsignedAccelerated; - m_properties.limits.integerDotProduct64BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProduct64BitSignedAccelerated; - m_properties.limits.integerDotProduct64BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProduct64BitMixedSignednessAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating8BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating8BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating8BitSignedAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating16BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating16BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating16BitSignedAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating32BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating32BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating32BitSignedAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating64BitUnsignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating64BitSignedAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating64BitSignedAccelerated; - m_properties.limits.integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated = shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; - } - - /* Nabla */ - + //! Nabla if (isExtensionSupported(VK_NV_SHADER_SM_BUILTINS_EXTENSION_NAME)) m_properties.limits.computeUnits = shaderSMBuiltinsProperties.shaderSMCount; else if(isExtensionSupported(VK_AMD_SHADER_CORE_PROPERTIES_2_EXTENSION_NAME)) @@ -554,85 +626,226 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice // VK_EXT_descriptor_indexing descriptorIndexing // VK_EXT_sampler_filter_minmax samplerFilterMinmax // VK_EXT_shader_viewport_index_layer shaderOutputViewportIndex, shaderOutputLayer - - - // !! Our minimum supported Vulkan version is 1.1, no need to check anything before using `vulkan11Features` - VkPhysicalDeviceVulkan12Features vulkan12Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, nullptr }; - VkPhysicalDeviceVulkan11Features vulkan11Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, &vulkan12Features }; // Extensions - VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT texelBufferAlignmentFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT, &vulkan11Features }; - VkPhysicalDeviceHostQueryResetFeatures hostQueryResetFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, &texelBufferAlignmentFeatures }; - VkPhysicalDeviceImageRobustnessFeatures imageRobustnessFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, &hostQueryResetFeatures }; - VkPhysicalDevicePipelineCreationCacheControlFeatures pipelineCreationCacheControlFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, &imageRobustnessFeatures }; - VkPhysicalDeviceColorWriteEnableFeaturesEXT colorWriteEnableFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT, &pipelineCreationCacheControlFeatures }; - VkPhysicalDeviceConditionalRenderingFeaturesEXT conditionalRenderingFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, &colorWriteEnableFeatures }; - VkPhysicalDeviceDeviceMemoryReportFeaturesEXT deviceMemoryReportFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT, &conditionalRenderingFeatures }; - VkPhysicalDeviceFragmentDensityMapFeaturesEXT fragmentDensityMapFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT, &deviceMemoryReportFeatures }; - VkPhysicalDeviceFragmentDensityMap2FeaturesEXT fragmentDensityMap2Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT, &fragmentDensityMapFeatures }; - VkPhysicalDeviceInlineUniformBlockFeatures inlineUniformBlockFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, &fragmentDensityMap2Features }; - VkPhysicalDeviceLineRasterizationFeaturesEXT lineRasterizationFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT, &inlineUniformBlockFeatures }; - VkPhysicalDeviceMemoryPriorityFeaturesEXT memoryPriorityFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT, &lineRasterizationFeatures }; - VkPhysicalDeviceRobustness2FeaturesEXT robustness2Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT, &memoryPriorityFeatures }; - VkPhysicalDevicePerformanceQueryFeaturesKHR performanceQueryFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR, &robustness2Features }; - VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR pipelineExecutablePropertiesFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR, &performanceQueryFeatures }; - VkPhysicalDeviceMaintenance4Features maintenance4Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, &pipelineExecutablePropertiesFeatures }; - VkPhysicalDeviceCoherentMemoryFeaturesAMD coherentMemoryFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD, &maintenance4Features }; - VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR globalPriorityFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, &coherentMemoryFeatures }; - VkPhysicalDeviceCoverageReductionModeFeaturesNV coverageReductionModeFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV, &globalPriorityFeatures }; - VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV deviceGeneratedCommandsFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV, &coverageReductionModeFeatures }; - VkPhysicalDeviceMeshShaderFeaturesNV meshShaderFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV, &deviceGeneratedCommandsFeatures }; - VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV representativeFragmentTestFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV, &meshShaderFeatures }; - VkPhysicalDeviceShaderImageFootprintFeaturesNV shaderImageFootprintFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV, &representativeFragmentTestFeatures }; - VkPhysicalDeviceComputeShaderDerivativesFeaturesNV computeShaderDerivativesFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV, &shaderImageFootprintFeatures }; - VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR workgroupMemoryExplicitLayout = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR, &computeShaderDerivativesFeatures }; - VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR subgroupUniformControlFlowFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR, &workgroupMemoryExplicitLayout }; - VkPhysicalDeviceShaderClockFeaturesKHR shaderClockFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR, &subgroupUniformControlFlowFeatures }; - VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL intelShaderIntegerFunctions2 = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL, &shaderClockFeatures }; - VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT shaderImageAtomicInt64Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT, &intelShaderIntegerFunctions2 }; - VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT shaderAtomicFloat2Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT, &shaderImageAtomicInt64Features }; - VkPhysicalDeviceShaderAtomicFloatFeaturesEXT shaderAtomicFloatFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT, &shaderAtomicFloat2Features }; - VkPhysicalDeviceIndexTypeUint8FeaturesEXT indexTypeUint8Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT, &shaderAtomicFloatFeatures }; - VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM rasterizationOrderAttachmentAccessFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM, &indexTypeUint8Features }; - VkPhysicalDeviceShaderIntegerDotProductFeatures shaderIntegerDotProductFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, &rasterizationOrderAttachmentAccessFeatures }; - VkPhysicalDeviceShaderTerminateInvocationFeatures shaderTerminateInvocationFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, &shaderIntegerDotProductFeatures }; - VkPhysicalDeviceScalarBlockLayoutFeatures scalarBlockLayoutFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, &shaderTerminateInvocationFeatures }; - VkPhysicalDeviceVulkanMemoryModelFeatures vulkanMemoryModelFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, &scalarBlockLayoutFeatures }; - VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures separateDepthStencilLayoutsFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, &vulkanMemoryModelFeatures }; - VkPhysicalDeviceUniformBufferStandardLayoutFeatures uniformBufferStandardLayoutFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, &separateDepthStencilLayoutsFeatures }; - VkPhysicalDeviceRayTracingMotionBlurFeaturesNV rayTracingMotionBlurFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV, &uniformBufferStandardLayoutFeatures }; - VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroupSizeControlFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT, &rayTracingMotionBlurFeatures }; - VkPhysicalDeviceShaderFloat16Int8Features shaderFloat16Int8Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR, &subgroupSizeControlFeatures }; - VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptorIndexingFeaturesEXT = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT, &shaderFloat16Int8Features }; - VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR shaderSubgroupExtendedTypesFeaturesKHR = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR, &descriptorIndexingFeaturesEXT }; - VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT shaderDemoteToHelperInvocationFeaturesEXT = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT, &shaderSubgroupExtendedTypesFeaturesKHR }; - VkPhysicalDeviceASTCDecodeFeaturesEXT astcDecodeFeaturesEXT = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT, &shaderDemoteToHelperInvocationFeaturesEXT }; - VkPhysicalDeviceShaderAtomicInt64FeaturesKHR shaderAtomicInt64FeaturesKHR = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR, &astcDecodeFeaturesEXT }; - VkPhysicalDevice8BitStorageFeaturesKHR _8BitStorageFeaturesKHR = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR, &shaderAtomicInt64FeaturesKHR }; - VkPhysicalDeviceShaderSMBuiltinsFeaturesNV shaderSMBuiltinsFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV, &_8BitStorageFeaturesKHR }; - VkPhysicalDeviceCooperativeMatrixFeaturesNV cooperativeMatrixFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV, &shaderSMBuiltinsFeatures }; - VkPhysicalDeviceRayTracingPipelineFeaturesKHR rayTracingPipelineFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR, &cooperativeMatrixFeatures }; - VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR, &rayTracingPipelineFeatures }; - VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR, &accelerationFeatures }; - VkPhysicalDeviceBufferDeviceAddressFeaturesKHR bufferDeviceAddressFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR, &rayQueryFeatures }; - VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT fragmentShaderInterlockFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, &bufferDeviceAddressFeatures }; { - //! Basically remove a query struct from the chain if it's not supported by vulkan version: - //! We need to do these only for `vulkan12Features` since our minimum is Vulkan 1.1 and this is only provided by VK_VESION_1_2 (not any extensions) - //! Other structures are provided by VK_XX_EXTENSION or VK_VERSION_XX so no need to check whether we need to remove them from query chain + VkPhysicalDeviceFeatures2 deviceFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 }; + setPNextChainTail(&deviceFeatures); + // !! Our minimum supported Vulkan version is 1.1, no need to check anything before using `vulkan11Features` + VkPhysicalDeviceVulkan11Features vulkan11Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES }; + addToPNextChain(&vulkan11Features); + //! Declare all the property structs before so they don't go out of scope + //! Provided by Vk 1.2 + VkPhysicalDeviceVulkan12Features vulkan12Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES }; + VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptorIndexingFeaturesEXT = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT }; + VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR shaderSubgroupExtendedTypesFeaturesKHR = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR }; + VkPhysicalDeviceHostQueryResetFeatures hostQueryResetFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES }; + VkPhysicalDeviceScalarBlockLayoutFeatures scalarBlockLayoutFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES }; + VkPhysicalDeviceVulkanMemoryModelFeatures vulkanMemoryModelFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES }; + VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures separateDepthStencilLayoutsFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES }; + VkPhysicalDeviceUniformBufferStandardLayoutFeatures uniformBufferStandardLayoutFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES }; // 922 + VkPhysicalDevice8BitStorageFeaturesKHR _8BitStorageFeaturesKHR = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR }; // 1232 + VkPhysicalDeviceShaderAtomicInt64FeaturesKHR shaderAtomicInt64FeaturesKHR = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR }; + VkPhysicalDeviceShaderFloat16Int8Features shaderFloat16Int8Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR }; + //! Provided by Vk 1.3 + VkPhysicalDeviceVulkan13Features vulkan13Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES }; + VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroupSizeControlFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT }; + VkPhysicalDeviceShaderTerminateInvocationFeatures shaderTerminateInvocationFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES }; + VkPhysicalDeviceShaderIntegerDotProductFeatures shaderIntegerDotProductFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES }; + VkPhysicalDeviceBufferDeviceAddressFeaturesKHR bufferDeviceAddressFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR }; + VkPhysicalDeviceImageRobustnessFeatures imageRobustnessFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES }; + VkPhysicalDevicePipelineCreationCacheControlFeatures pipelineCreationCacheControlFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES }; + VkPhysicalDeviceInlineUniformBlockFeatures inlineUniformBlockFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES }; + VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT shaderDemoteToHelperInvocationFeaturesEXT = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT }; + VkPhysicalDeviceMaintenance4Features maintenance4Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES }; + //! Extensions + VkPhysicalDeviceCooperativeMatrixFeaturesNV cooperativeMatrixFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV }; + VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR }; + VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR }; + VkPhysicalDeviceRayTracingPipelineFeaturesKHR rayTracingPipelineFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR }; + VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT fragmentShaderInterlockFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT }; + VkPhysicalDeviceRayTracingMotionBlurFeaturesNV rayTracingMotionBlurFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV }; + VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM rasterizationOrderAttachmentAccessFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM }; + VkPhysicalDeviceShaderAtomicFloatFeaturesEXT shaderAtomicFloatFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT }; + VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT shaderAtomicFloat2Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT }; + VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT shaderImageAtomicInt64Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT }; + VkPhysicalDeviceIndexTypeUint8FeaturesEXT indexTypeUint8Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT }; + VkPhysicalDeviceShaderClockFeaturesKHR shaderClockFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR }; + VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR subgroupUniformControlFlowFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR }; + VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR workgroupMemoryExplicitLayout = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR }; + VkPhysicalDeviceComputeShaderDerivativesFeaturesNV computeShaderDerivativesFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV }; + VkPhysicalDeviceCoverageReductionModeFeaturesNV coverageReductionModeFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV }; + + VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV deviceGeneratedCommandsFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV }; + VkPhysicalDeviceMeshShaderFeaturesNV meshShaderFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV }; + VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV representativeFragmentTestFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV }; + VkPhysicalDeviceColorWriteEnableFeaturesEXT colorWriteEnableFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT }; + VkPhysicalDeviceConditionalRenderingFeaturesEXT conditionalRenderingFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT }; + VkPhysicalDeviceDeviceMemoryReportFeaturesEXT deviceMemoryReportFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT }; + VkPhysicalDeviceFragmentDensityMapFeaturesEXT fragmentDensityMapFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT }; + VkPhysicalDeviceFragmentDensityMap2FeaturesEXT fragmentDensityMap2Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT }; + VkPhysicalDeviceLineRasterizationFeaturesEXT lineRasterizationFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT }; + VkPhysicalDeviceMemoryPriorityFeaturesEXT memoryPriorityFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT }; + VkPhysicalDeviceRobustness2FeaturesEXT robustness2Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT }; + VkPhysicalDevicePerformanceQueryFeaturesKHR performanceQueryFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR }; + VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR pipelineExecutablePropertiesFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR }; + VkPhysicalDeviceCoherentMemoryFeaturesAMD coherentMemoryFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD }; + VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL intelShaderIntegerFunctions2 = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL }; + VkPhysicalDeviceShaderImageFootprintFeaturesNV shaderImageFootprintFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV }; + VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT texelBufferAlignmentFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT }; + VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR globalPriorityFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR }; + VkPhysicalDeviceASTCDecodeFeaturesEXT astcDecodeFeaturesEXT = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT }; + VkPhysicalDeviceShaderSMBuiltinsFeaturesNV shaderSMBuiltinsFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV }; //! This is only written for convenience to avoid getting validation errors otherwise vulkan will just skip any strutctures it doesn't recognize - if(instanceApiVersion < VK_MAKE_API_VERSION(0, 1, 2, 0)) + if (instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)) + { + addToPNextChain(&vulkan12Features); + addToPNextChain(&descriptorIndexingFeaturesEXT); + addToPNextChain(&shaderSubgroupExtendedTypesFeaturesKHR); + addToPNextChain(&hostQueryResetFeatures); + addToPNextChain(&scalarBlockLayoutFeatures); + addToPNextChain(&vulkanMemoryModelFeatures); + addToPNextChain(&separateDepthStencilLayoutsFeatures); + addToPNextChain(&uniformBufferStandardLayoutFeatures); + addToPNextChain(&_8BitStorageFeaturesKHR); + addToPNextChain(&shaderAtomicInt64FeaturesKHR); + addToPNextChain(&shaderFloat16Int8Features); + } + else { - assert(vulkan11Features.pNext == &vulkan12Features); - vulkan11Features.pNext = vulkan12Features.pNext; + if (isExtensionSupported(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) + addToPNextChain(&descriptorIndexingFeaturesEXT); + if (isExtensionSupported(VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME)) + addToPNextChain(&shaderSubgroupExtendedTypesFeaturesKHR); + if (isExtensionSupported(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) + addToPNextChain(&hostQueryResetFeatures); + if (isExtensionSupported(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME)) + addToPNextChain(&scalarBlockLayoutFeatures); + if (isExtensionSupported(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME)) + addToPNextChain(&vulkanMemoryModelFeatures); + if (isExtensionSupported(VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME)) + addToPNextChain(&separateDepthStencilLayoutsFeatures); + if (isExtensionSupported(VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME)) + addToPNextChain(&uniformBufferStandardLayoutFeatures); + if (isExtensionSupported(VK_KHR_8BIT_STORAGE_EXTENSION_NAME)) + addToPNextChain(&_8BitStorageFeaturesKHR); + if (isExtensionSupported(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME)) + addToPNextChain(&shaderAtomicInt64FeaturesKHR); + if (isExtensionSupported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) + addToPNextChain(&shaderFloat16Int8Features); + } + if (instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)) + { + addToPNextChain(&vulkan13Features); + addToPNextChain(&subgroupSizeControlFeatures); + addToPNextChain(&shaderTerminateInvocationFeatures); + addToPNextChain(&shaderIntegerDotProductFeatures); + addToPNextChain(&bufferDeviceAddressFeatures); + addToPNextChain(&imageRobustnessFeatures); + addToPNextChain(&pipelineCreationCacheControlFeatures); + addToPNextChain(&inlineUniformBlockFeatures); + addToPNextChain(&shaderDemoteToHelperInvocationFeaturesEXT); + addToPNextChain(&maintenance4Features); } - - VkPhysicalDeviceFeatures2 deviceFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 }; - deviceFeatures.pNext = &fragmentShaderInterlockFeatures; - vkGetPhysicalDeviceFeatures2(m_vkPhysicalDevice, &deviceFeatures); - const auto& features = deviceFeatures.features; + else + { + if (isExtensionSupported(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME)) + addToPNextChain(&subgroupSizeControlFeatures); + if (isExtensionSupported(VK_KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME)) + addToPNextChain(&shaderTerminateInvocationFeatures); + if (isExtensionSupported(VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME)) + addToPNextChain(&shaderIntegerDotProductFeatures); + if (isExtensionSupported(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) + addToPNextChain(&bufferDeviceAddressFeatures); + if (isExtensionSupported(VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME)) + addToPNextChain(&imageRobustnessFeatures); + if (isExtensionSupported(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME)) + addToPNextChain(&pipelineCreationCacheControlFeatures); + if (isExtensionSupported(VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME)) + addToPNextChain(&inlineUniformBlockFeatures); + if (isExtensionSupported(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME)) + addToPNextChain(&shaderDemoteToHelperInvocationFeaturesEXT); + if (isExtensionSupported(VK_KHR_MAINTENANCE_4_EXTENSION_NAME)) + addToPNextChain(&maintenance4Features); + } + if (isExtensionSupported(VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME)) + addToPNextChain(&cooperativeMatrixFeatures); + if (isExtensionSupported(VK_KHR_RAY_QUERY_EXTENSION_NAME)) + addToPNextChain(&rayQueryFeatures); + if (isExtensionSupported(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME)) + addToPNextChain(&accelerationFeatures); + if (isExtensionSupported(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME)) + addToPNextChain(&rayTracingPipelineFeatures); + if (isExtensionSupported(VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME)) + addToPNextChain(&fragmentShaderInterlockFeatures); + if (isExtensionSupported(VK_NV_RAY_TRACING_MOTION_BLUR_EXTENSION_NAME)) + addToPNextChain(&rayTracingMotionBlurFeatures); + if (isExtensionSupported(VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME)) + addToPNextChain(&rasterizationOrderAttachmentAccessFeatures); + if (isExtensionSupported(VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME)) + addToPNextChain(&shaderAtomicFloatFeatures); + if (isExtensionSupported(VK_EXT_SHADER_ATOMIC_FLOAT_2_EXTENSION_NAME)) + addToPNextChain(&shaderAtomicFloat2Features); + if (isExtensionSupported(VK_EXT_SHADER_IMAGE_ATOMIC_INT64_EXTENSION_NAME)) + addToPNextChain(&shaderImageAtomicInt64Features); + if (isExtensionSupported(VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME)) + addToPNextChain(&indexTypeUint8Features); + if (isExtensionSupported(VK_KHR_SHADER_CLOCK_EXTENSION_NAME)) + addToPNextChain(&shaderClockFeatures); + if (isExtensionSupported(VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_EXTENSION_NAME)) + addToPNextChain(&subgroupUniformControlFlowFeatures); + if (isExtensionSupported(VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME)) + addToPNextChain(&workgroupMemoryExplicitLayout); + if (isExtensionSupported(VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME)) + addToPNextChain(&computeShaderDerivativesFeatures); + if (isExtensionSupported(VK_NV_COVERAGE_REDUCTION_MODE_EXTENSION_NAME)) + addToPNextChain(&coverageReductionModeFeatures); + if (isExtensionSupported(VK_NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME)) + addToPNextChain(&deviceGeneratedCommandsFeatures); + if (isExtensionSupported(VK_NV_MESH_SHADER_EXTENSION_NAME)) + addToPNextChain(&meshShaderFeatures); + if (isExtensionSupported(VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME)) + addToPNextChain(&representativeFragmentTestFeatures); + if (isExtensionSupported(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME)) + addToPNextChain(&colorWriteEnableFeatures); + if (isExtensionSupported(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME)) + addToPNextChain(&conditionalRenderingFeatures); + if (isExtensionSupported(VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME)) + addToPNextChain(&deviceMemoryReportFeatures); + if (isExtensionSupported(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME)) + addToPNextChain(&fragmentDensityMapFeatures); + if (isExtensionSupported(VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME)) + addToPNextChain(&fragmentDensityMap2Features); + if (isExtensionSupported(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME)) + addToPNextChain(&lineRasterizationFeatures); + if (isExtensionSupported(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME)) + addToPNextChain(&memoryPriorityFeatures); + if (isExtensionSupported(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME)) + addToPNextChain(&robustness2Features); + if (isExtensionSupported(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME)) + addToPNextChain(&performanceQueryFeatures); + if (isExtensionSupported(VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME)) + addToPNextChain(&pipelineExecutablePropertiesFeatures); + if (isExtensionSupported(VK_AMD_DEVICE_COHERENT_MEMORY_EXTENSION_NAME)) + addToPNextChain(&coherentMemoryFeatures); + if (isExtensionSupported(VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_EXTENSION_NAME)) + addToPNextChain(&intelShaderIntegerFunctions2); + if (isExtensionSupported(VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME)) + addToPNextChain(&shaderImageFootprintFeatures); + if (isExtensionSupported(VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME)) + addToPNextChain(&texelBufferAlignmentFeatures); + if (isExtensionSupported(VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME)) + addToPNextChain(&globalPriorityFeatures); + if (isExtensionSupported(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME)) + addToPNextChain(&astcDecodeFeaturesEXT); + if (isExtensionSupported(VK_NV_SHADER_SM_BUILTINS_EXTENSION_NAME)) + addToPNextChain(&shaderSMBuiltinsFeatures); + // call + finalizePNextChain(); + vkGetPhysicalDeviceFeatures2(m_vkPhysicalDevice,&deviceFeatures); /* Vulkan 1.0 Core */ + const auto& features = deviceFeatures.features; m_features.robustBufferAccess = features.robustBufferAccess; m_features.fullDrawIndexUint32 = features.fullDrawIndexUint32; m_features.imageCubeArray = features.imageCubeArray; @@ -674,13 +887,12 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_features.shaderDrawParameters = vulkan11Features.shaderDrawParameters; /* Vulkan 1.2 Core */ - - if (instanceApiVersion >= VK_MAKE_API_VERSION(0, 1, 2, 0)) + if (instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)) { m_features.subgroupBroadcastDynamicId = vulkan12Features.subgroupBroadcastDynamicId; } - if (isExtensionSupported(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) + if (instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) { m_features.descriptorIndexing = true; m_features.shaderInputAttachmentArrayDynamicIndexing = descriptorIndexingFeaturesEXT.shaderInputAttachmentArrayDynamicIndexing; @@ -709,20 +921,105 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_features.drawIndirectCount = isExtensionSupported(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME); m_features.samplerFilterMinmax = isExtensionSupported(VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME); - if(isExtensionSupported(VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME)) + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME)) { m_features.shaderSubgroupExtendedTypes = shaderSubgroupExtendedTypesFeaturesKHR.shaderSubgroupExtendedTypes; } - - m_features.shaderDemoteToHelperInvocation = isExtensionSupported(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME); + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) + { + m_features.hostQueryReset = hostQueryResetFeatures.hostQueryReset; + } + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME)) + { + m_features.scalarBlockLayout = scalarBlockLayoutFeatures.scalarBlockLayout; + } + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME)) + { + m_features.vulkanMemoryModel = vulkanMemoryModelFeatures.vulkanMemoryModel; + m_features.vulkanMemoryModelDeviceScope = vulkanMemoryModelFeatures.vulkanMemoryModelDeviceScope; + m_features.vulkanMemoryModelAvailabilityVisibilityChains = vulkanMemoryModelFeatures.vulkanMemoryModelAvailabilityVisibilityChains; + } + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME)) + { + m_features.separateDepthStencilLayouts = separateDepthStencilLayoutsFeatures.separateDepthStencilLayouts; + } + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME)) + { + m_features.uniformBufferStandardLayout = uniformBufferStandardLayoutFeatures.uniformBufferStandardLayout; + } + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_KHR_8BIT_STORAGE_EXTENSION_NAME)) + { + m_properties.limits.storageBuffer8BitAccess = _8BitStorageFeaturesKHR.storageBuffer8BitAccess; + m_properties.limits.uniformAndStorageBuffer8BitAccess = _8BitStorageFeaturesKHR.uniformAndStorageBuffer8BitAccess; + m_properties.limits.storagePushConstant8 = _8BitStorageFeaturesKHR.storagePushConstant8; + } + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME)) + { + m_properties.limits.shaderBufferInt64Atomics = shaderAtomicInt64FeaturesKHR.shaderBufferInt64Atomics; + m_properties.limits.shaderSharedInt64Atomics = shaderAtomicInt64FeaturesKHR.shaderSharedInt64Atomics; + } + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,2,0)||isExtensionSupported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) + { + m_properties.limits.shaderFloat16 = shaderFloat16Int8Features.shaderFloat16; + m_properties.limits.shaderInt8 = shaderFloat16Int8Features.shaderInt8; + } /* Vulkan 1.3 Core */ - if(isExtensionSupported(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME)) + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)||isExtensionSupported(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME)) { m_features.subgroupSizeControl = subgroupSizeControlFeatures.subgroupSizeControl; m_features.computeFullSubgroups = subgroupSizeControlFeatures.computeFullSubgroups; } + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)||isExtensionSupported(VK_KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME)) + { + m_features.shaderTerminateInvocation = shaderTerminateInvocationFeatures.shaderTerminateInvocation; + } + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)||isExtensionSupported(VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME)) + { + m_features.shaderIntegerDotProduct = shaderIntegerDotProductFeatures.shaderIntegerDotProduct; + // [TODO] there's a bunch of fields! https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR.html + // RESPONSE FROM ERFAN: That's not features, that's properties + } + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)||isExtensionSupported(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) + { + m_features.bufferDeviceAddress = bufferDeviceAddressFeatures.bufferDeviceAddress; + m_features.bufferDeviceAddressMultiDevice = bufferDeviceAddressFeatures.bufferDeviceAddressMultiDevice; + } + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)||isExtensionSupported(VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME)) + { + m_features.robustImageAccess = imageRobustnessFeatures.robustImageAccess; + } + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)||isExtensionSupported(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME)) + { + m_features.pipelineCreationCacheControl = pipelineCreationCacheControlFeatures.pipelineCreationCacheControl; + } + + if(instanceApiVersion>=VK_MAKE_API_VERSION(0,1,3,0)||isExtensionSupported(VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME)) + { + m_features.inlineUniformBlock = inlineUniformBlockFeatures.inlineUniformBlock; + m_features.descriptorBindingInlineUniformBlockUpdateAfterBind = inlineUniformBlockFeatures.descriptorBindingInlineUniformBlockUpdateAfterBind; + } + + m_features.shaderDemoteToHelperInvocation = isExtensionSupported(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME); + + if (isExtensionSupported(VK_KHR_MAINTENANCE_4_EXTENSION_NAME)) + { + m_properties.limits.workgroupSizeFromSpecConstant = maintenance4Features.maintenance4; + } + /* Vulkan Extensions */ if (isExtensionSupported(VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME)) @@ -760,13 +1057,6 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_features.fragmentShaderShadingRateInterlock = fragmentShaderInterlockFeatures.fragmentShaderShadingRateInterlock; } - /* BufferDeviceAddressFeaturesKHR */ - if (isExtensionSupported(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) - { - m_features.bufferDeviceAddress = bufferDeviceAddressFeatures.bufferDeviceAddress; - m_features.bufferDeviceAddressMultiDevice = bufferDeviceAddressFeatures.bufferDeviceAddressMultiDevice; - } - /* RayTracingMotionBlurFeaturesNV */ if (isExtensionSupported(VK_NV_RAY_TRACING_MOTION_BLUR_EXTENSION_NAME)) { @@ -774,46 +1064,6 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_features.rayTracingMotionBlurPipelineTraceRaysIndirect = rayTracingMotionBlurFeatures.rayTracingMotionBlurPipelineTraceRaysIndirect; } - /* VkPhysicalDeviceUniformBufferStandardLayoutFeatures */ - if (isExtensionSupported(VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME)) - { - m_features.uniformBufferStandardLayout = uniformBufferStandardLayoutFeatures.uniformBufferStandardLayout; - } - - /* VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures */ - if (isExtensionSupported(VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME)) - { - m_features.separateDepthStencilLayouts = separateDepthStencilLayoutsFeatures.separateDepthStencilLayouts; - } - - /* VkPhysicalDeviceVulkanMemoryModelFeatures */ - if (isExtensionSupported(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME)) - { - m_features.vulkanMemoryModel = vulkanMemoryModelFeatures.vulkanMemoryModel; - m_features.vulkanMemoryModelDeviceScope = vulkanMemoryModelFeatures.vulkanMemoryModelDeviceScope; - m_features.vulkanMemoryModelAvailabilityVisibilityChains = vulkanMemoryModelFeatures.vulkanMemoryModelAvailabilityVisibilityChains; - } - - /* VkPhysicalDeviceScalarBlockLayoutFeatures */ - if (isExtensionSupported(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME)) - { - m_features.scalarBlockLayout = scalarBlockLayoutFeatures.scalarBlockLayout; - } - - /* VkPhysicalDeviceShaderTerminateInvocationFeatures */ - if (isExtensionSupported(VK_KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME)) - { - m_features.shaderTerminateInvocation = shaderTerminateInvocationFeatures.shaderTerminateInvocation; - } - - /* VkPhysicalDeviceShaderTerminateInvocationFeatures */ - if (isExtensionSupported(VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME)) - { - m_features.shaderIntegerDotProduct = shaderIntegerDotProductFeatures.shaderIntegerDotProduct; - // [TODO] there's a bunch of fields! https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR.html - // RESPONSE FROM ERFAN: That's not features, that's properties - } - /* VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM */ if (isExtensionSupported(VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME)) { @@ -957,24 +1207,6 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_features.bufferMarkerAMD = true; } - /* VkPhysicalDeviceHostQueryResetFeatures */ - if (isExtensionSupported(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) - { - m_features.hostQueryReset = hostQueryResetFeatures.hostQueryReset; - } - - /* VkPhysicalDeviceImageRobustnessFeatures */ - if (isExtensionSupported(VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME)) - { - m_features.robustImageAccess = imageRobustnessFeatures.robustImageAccess; - } - - /* VkPhysicalDevicePipelineCreationCacheControlFeatures */ - if (isExtensionSupported(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME)) - { - m_features.pipelineCreationCacheControl = pipelineCreationCacheControlFeatures.pipelineCreationCacheControl; - } - /* VkPhysicalDeviceColorWriteEnableFeaturesEXT */ if (isExtensionSupported(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME)) { @@ -1008,13 +1240,6 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_features.fragmentDensityMapDeferred = fragmentDensityMap2Features.fragmentDensityMapDeferred; } - /* VkPhysicalDeviceInlineUniformBlockFeatures */ - if (isExtensionSupported(VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME)) - { - m_features.inlineUniformBlock = inlineUniformBlockFeatures.inlineUniformBlock; - m_features.descriptorBindingInlineUniformBlockUpdateAfterBind = inlineUniformBlockFeatures.descriptorBindingInlineUniformBlockUpdateAfterBind; - } - /* VkPhysicalDeviceLineRasterizationFeaturesEXT */ if (isExtensionSupported(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME)) { @@ -1081,25 +1306,6 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_properties.limits.uniformAndStorageBuffer16BitAccess = vulkan11Features.uniformAndStorageBuffer16BitAccess; m_properties.limits.storagePushConstant16 = vulkan11Features.storagePushConstant16; m_properties.limits.storageInputOutput16 = vulkan11Features.storageInputOutput16; - - if (isExtensionSupported(VK_KHR_8BIT_STORAGE_EXTENSION_NAME)) - { - m_properties.limits.storageBuffer8BitAccess = _8BitStorageFeaturesKHR.storageBuffer8BitAccess; - m_properties.limits.uniformAndStorageBuffer8BitAccess = _8BitStorageFeaturesKHR.uniformAndStorageBuffer8BitAccess; - m_properties.limits.storagePushConstant8 = _8BitStorageFeaturesKHR.storagePushConstant8; - } - - if (isExtensionSupported(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME)) - { - m_properties.limits.shaderBufferInt64Atomics = shaderAtomicInt64FeaturesKHR.shaderBufferInt64Atomics; - m_properties.limits.shaderSharedInt64Atomics = shaderAtomicInt64FeaturesKHR.shaderSharedInt64Atomics; - } - - if (isExtensionSupported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) - { - m_properties.limits.shaderFloat16 = shaderFloat16Int8Features.shaderFloat16; - m_properties.limits.shaderInt8 = shaderFloat16Int8Features.shaderInt8; - } if (isExtensionSupported(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME)) { @@ -1137,11 +1343,6 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice m_properties.limits.shaderSMBuiltins = shaderSMBuiltinsFeatures.shaderSMBuiltins; } - if (isExtensionSupported(VK_KHR_MAINTENANCE_4_EXTENSION_NAME)) - { - m_properties.limits.workgroupSizeFromSpecConstant = maintenance4Features.maintenance4; - } - m_properties.limits.shaderSubgroupPartitioned = isExtensionSupported(VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME); m_properties.limits.gcnShader = isExtensionSupported(VK_AMD_GCN_SHADER_EXTENSION_NAME); m_properties.limits.gpuShaderHalfFloat = isExtensionSupported(VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME); @@ -1214,6 +1415,33 @@ class CVulkanPhysicalDevice final : public IPhysicalDevice for(uint32_t i = 0; i < asset::EF_COUNT; ++i) { const asset::E_FORMAT format = static_cast(i); + bool skip = false; + switch (format) + { + case asset::EF_B4G4R4A4_UNORM_PACK16: + case asset::EF_R4G4B4A4_UNORM_PACK16: + if (instanceApiVersion