From 93fa55bd2909eeba535cf917dee27f541f368a37 Mon Sep 17 00:00:00 2001 From: Powei Feng Date: Mon, 3 Feb 2025 11:10:19 -0800 Subject: [PATCH] vk: refactor utils into its own namespace (#8280) We move the code that was contained within two "utils" files into separate utils sources in the vulkan/utils directory. --- filament/backend/CMakeLists.txt | 15 +- filament/backend/src/vulkan/VulkanBlitter.cpp | 9 +- filament/backend/src/vulkan/VulkanCommands.h | 6 +- filament/backend/src/vulkan/VulkanContext.cpp | 1 - filament/backend/src/vulkan/VulkanContext.h | 14 +- filament/backend/src/vulkan/VulkanDriver.cpp | 47 ++-- filament/backend/src/vulkan/VulkanDriver.h | 16 +- .../backend/src/vulkan/VulkanFboCache.cpp | 26 +-- filament/backend/src/vulkan/VulkanHandles.cpp | 18 +- filament/backend/src/vulkan/VulkanHandles.h | 25 +-- .../src/vulkan/VulkanPipelineCache.cpp | 4 +- .../backend/src/vulkan/VulkanPipelineCache.h | 1 - .../backend/src/vulkan/VulkanReadPixels.cpp | 13 +- .../backend/src/vulkan/VulkanSamplerCache.cpp | 3 +- .../backend/src/vulkan/VulkanSamplerCache.h | 1 - .../backend/src/vulkan/VulkanStagePool.cpp | 10 +- filament/backend/src/vulkan/VulkanTexture.cpp | 42 ++-- filament/backend/src/vulkan/VulkanTexture.h | 2 +- .../caching/VulkanDescriptorSetManager.cpp | 22 +- .../caching/VulkanDescriptorSetManager.h | 7 +- .../src/vulkan/platform/VulkanPlatform.cpp | 24 +-- .../vulkan/platform/VulkanPlatformAndroid.cpp | 1 - .../platform/VulkanPlatformSwapChainImpl.cpp | 23 +- .../Conversion.cpp} | 68 +----- .../backend/src/vulkan/utils/Conversion.h | 76 +++++++ .../{VulkanUtility.h => utils/Definitions.h} | 204 +----------------- filament/backend/src/vulkan/utils/Helper.h | 84 ++++++++ .../Image.cpp} | 42 +++- .../{VulkanImageUtility.h => utils/Image.h} | 34 ++- .../VulkanSpirvUtils.cpp => utils/Spirv.cpp} | 70 +----- .../VulkanSpirvUtils.h => utils/Spirv.h} | 15 +- .../backend/src/vulkan/utils/StaticVector.h | 134 ++++++++++++ 32 files changed, 541 insertions(+), 516 deletions(-) rename filament/backend/src/vulkan/{VulkanUtility.cpp => utils/Conversion.cpp} (92%) create mode 100644 filament/backend/src/vulkan/utils/Conversion.h rename filament/backend/src/vulkan/{VulkanUtility.h => utils/Definitions.h} (70%) create mode 100644 filament/backend/src/vulkan/utils/Helper.h rename filament/backend/src/vulkan/{VulkanImageUtility.cpp => utils/Image.cpp} (87%) rename filament/backend/src/vulkan/{VulkanImageUtility.h => utils/Image.h} (84%) rename filament/backend/src/vulkan/{spirv/VulkanSpirvUtils.cpp => utils/Spirv.cpp} (72%) rename filament/backend/src/vulkan/{spirv/VulkanSpirvUtils.h => utils/Spirv.h} (77%) create mode 100644 filament/backend/src/vulkan/utils/StaticVector.h diff --git a/filament/backend/CMakeLists.txt b/filament/backend/CMakeLists.txt index 208aec0ee0..9fc673990b 100644 --- a/filament/backend/CMakeLists.txt +++ b/filament/backend/CMakeLists.txt @@ -185,8 +185,15 @@ if (FILAMENT_SUPPORTS_VULKAN) src/vulkan/platform/VulkanPlatform.cpp src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp src/vulkan/platform/VulkanPlatformSwapChainImpl.h - src/vulkan/spirv/VulkanSpirvUtils.cpp - src/vulkan/spirv/VulkanSpirvUtils.h + src/vulkan/utils/Conversion.cpp + src/vulkan/utils/Conversion.h + src/vulkan/utils/Definitions.h + src/vulkan/utils/Helper.h + src/vulkan/utils/Image.h + src/vulkan/utils/Image.cpp + src/vulkan/utils/Spirv.h + src/vulkan/utils/Spirv.cpp + src/vulkan/utils/StaticVector.h src/vulkan/VulkanAsyncHandles.cpp src/vulkan/VulkanAsyncHandles.h src/vulkan/VulkanBlitter.cpp @@ -205,8 +212,6 @@ if (FILAMENT_SUPPORTS_VULKAN) src/vulkan/VulkanFboCache.h src/vulkan/VulkanHandles.cpp src/vulkan/VulkanHandles.h - src/vulkan/VulkanImageUtility.cpp - src/vulkan/VulkanImageUtility.h src/vulkan/VulkanMemory.h src/vulkan/VulkanMemory.cpp src/vulkan/VulkanPipelineCache.cpp @@ -221,8 +226,6 @@ if (FILAMENT_SUPPORTS_VULKAN) src/vulkan/VulkanReadPixels.h src/vulkan/VulkanTexture.cpp src/vulkan/VulkanTexture.h - src/vulkan/VulkanUtility.cpp - src/vulkan/VulkanUtility.h ) if (LINUX OR WIN32) list(APPEND SRCS src/vulkan/platform/VulkanPlatformLinuxWindows.cpp) diff --git a/filament/backend/src/vulkan/VulkanBlitter.cpp b/filament/backend/src/vulkan/VulkanBlitter.cpp index bcb786e63a..c88bc27f46 100644 --- a/filament/backend/src/vulkan/VulkanBlitter.cpp +++ b/filament/backend/src/vulkan/VulkanBlitter.cpp @@ -21,6 +21,7 @@ #include "VulkanHandles.h" #include "VulkanSamplerCache.h" #include "VulkanTexture.h" +#include "vulkan/utils/Image.h" #include #include @@ -61,8 +62,8 @@ inline void blitFast(VulkanCommandBuffer* commands, VkImageAspectFlags aspect, V .dstOffsets = { dstRect[0], dstRect[1] }, }}; vkCmdBlitImage(cmdbuf, - src.getImage(), imgutil::getVkLayout(VulkanLayout::TRANSFER_SRC), - dst.getImage(), imgutil::getVkLayout(VulkanLayout::TRANSFER_DST), + src.getImage(), fvkutils::getVkLayout(VulkanLayout::TRANSFER_SRC), + dst.getImage(), fvkutils::getVkLayout(VulkanLayout::TRANSFER_DST), 1, blitRegions, filter); if (oldSrcLayout == VulkanLayout::UNDEFINED) { @@ -104,8 +105,8 @@ inline void resolveFast(VulkanCommandBuffer* commands, VkImageAspectFlags aspect .extent = { src.getExtent2D().width, src.getExtent2D().height, 1 }, }}; vkCmdResolveImage(cmdbuffer, - src.getImage(), imgutil::getVkLayout(VulkanLayout::TRANSFER_SRC), - dst.getImage(), imgutil::getVkLayout(VulkanLayout::TRANSFER_DST), + src.getImage(), fvkutils::getVkLayout(VulkanLayout::TRANSFER_SRC), + dst.getImage(), fvkutils::getVkLayout(VulkanLayout::TRANSFER_DST), 1, resolveRegions); if (oldSrcLayout == VulkanLayout::UNDEFINED) { diff --git a/filament/backend/src/vulkan/VulkanCommands.h b/filament/backend/src/vulkan/VulkanCommands.h index 2e331dfa4a..0afd4b4b46 100644 --- a/filament/backend/src/vulkan/VulkanCommands.h +++ b/filament/backend/src/vulkan/VulkanCommands.h @@ -23,8 +23,8 @@ #include "VulkanAsyncHandles.h" #include "VulkanConstants.h" -#include "VulkanUtility.h" #include "vulkan/memory/ResourcePointer.h" +#include "vulkan/utils/StaticVector.h" #include #include @@ -79,7 +79,7 @@ struct VulkanCommandBuffer { void reset() noexcept; inline void insertWait(VkSemaphore sem) { - mWaitSemaphores.insert(sem); + mWaitSemaphores.push_back(sem); } void pushMarker(char const* marker) noexcept; @@ -115,7 +115,7 @@ private: bool const isProtected; VkDevice mDevice; VkQueue mQueue; - CappedArray mWaitSemaphores; + fvkutils::StaticVector mWaitSemaphores; VkCommandBuffer mBuffer; VkSemaphore mSubmission; VkFence mFence; diff --git a/filament/backend/src/vulkan/VulkanContext.cpp b/filament/backend/src/vulkan/VulkanContext.cpp index 95d860d618..0345e69cf9 100644 --- a/filament/backend/src/vulkan/VulkanContext.cpp +++ b/filament/backend/src/vulkan/VulkanContext.cpp @@ -20,7 +20,6 @@ #include "VulkanHandles.h" #include "VulkanMemory.h" #include "VulkanTexture.h" -#include "VulkanUtility.h" #include diff --git a/filament/backend/src/vulkan/VulkanContext.h b/filament/backend/src/vulkan/VulkanContext.h index 67c4e52a9b..aebc355050 100644 --- a/filament/backend/src/vulkan/VulkanContext.h +++ b/filament/backend/src/vulkan/VulkanContext.h @@ -18,8 +18,8 @@ #define TNT_FILAMENT_BACKEND_VULKANCONTEXT_H #include "VulkanConstants.h" -#include "VulkanImageUtility.h" -#include "VulkanUtility.h" +#include "vulkan/utils/Image.h" +#include "vulkan/utils/Definitions.h" #include "vulkan/memory/ResourcePointer.h" @@ -28,6 +28,8 @@ #include #include +#include + #include VK_DEFINE_HANDLE(VmaAllocator) @@ -113,11 +115,11 @@ public: return (uint32_t) VK_MAX_MEMORY_TYPES; } - inline VkFormatList const& getAttachmentDepthStencilFormats() const { + inline fvkutils::VkFormatList const& getAttachmentDepthStencilFormats() const { return mDepthStencilFormats; } - inline VkFormatList const& getBlittableDepthStencilFormats() const { + inline fvkutils::VkFormatList const& getBlittableDepthStencilFormats() const { return mBlittableDepthStencilFormats; } @@ -175,8 +177,8 @@ private: bool mLazilyAllocatedMemorySupported = false; bool mProtectedMemorySupported = false; - VkFormatList mDepthStencilFormats; - VkFormatList mBlittableDepthStencilFormats; + fvkutils::VkFormatList mDepthStencilFormats; + fvkutils::VkFormatList mBlittableDepthStencilFormats; // For convenience so that VulkanPlatform can initialize the private fields. friend class VulkanPlatform; diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 38db05cbcc..9df949d685 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -26,10 +26,12 @@ #include "VulkanHandles.h" #include "VulkanMemory.h" #include "VulkanTexture.h" -#include "backend/DriverEnums.h" -#include "memory/ResourceManager.h" -#include "memory/ResourcePointer.h" +#include "vulkan/memory/ResourceManager.h" +#include "vulkan/memory/ResourcePointer.h" +#include "vulkan/utils/Conversion.h" +#include "vulkan/utils/Definitions.h" +#include #include #include @@ -543,16 +545,16 @@ void VulkanDriver::createTextureViewSwizzleR(Handle th, Handle::cast(&mResourceManager, srch); auto texture = resource_ptr::make(&mResourceManager, th, mPlatform->getDevice(), mPlatform->getPhysicalDevice(), mContext, mAllocator, &mCommands, src, swizzle); texture.inc(); } -void VulkanDriver::createTextureExternalImageR(Handle th, - backend::SamplerType target, backend::TextureFormat format, - uint32_t width, uint32_t height, backend::TextureUsage usage, void* externalImage) { +void VulkanDriver::createTextureExternalImageR(Handle th, backend::SamplerType target, + backend::TextureFormat format, uint32_t width, uint32_t height, backend::TextureUsage usage, + void* externalImage) { FVK_SYSTRACE_SCOPE(); const auto& metadata = mPlatform->getExternalImageMetadata(externalImage); @@ -562,7 +564,7 @@ void VulkanDriver::createTextureExternalImageR(Handle th, assert_invariant(width == metadata.width); assert_invariant(height == metadata.height); - assert_invariant(getVkFormat(format) == metadata.format); + assert_invariant(fvkutils::getVkFormat(format) == metadata.format); const auto& data = mPlatform->createExternalImage(externalImage, metadata); @@ -937,7 +939,7 @@ FenceStatus VulkanDriver::getFenceStatus(Handle fh) { // We create all textures using VK_IMAGE_TILING_OPTIMAL, so our definition of "supported" is that // the GPU supports the given texture format with non-zero optimal tiling features. bool VulkanDriver::isTextureFormatSupported(TextureFormat format) { - VkFormat vkformat = getVkFormat(format); + VkFormat vkformat = fvkutils::getVkFormat(format); if (vkformat == VK_FORMAT_UNDEFINED) { return false; } @@ -964,7 +966,7 @@ bool VulkanDriver::isTextureFormatMipmappable(TextureFormat format) { } bool VulkanDriver::isRenderTargetFormatSupported(TextureFormat format) { - VkFormat vkformat = getVkFormat(format); + VkFormat vkformat = fvkutils::getVkFormat(format); if (vkformat == VK_FORMAT_UNDEFINED) { return false; } @@ -1022,12 +1024,11 @@ bool VulkanDriver::isDepthStencilResolveSupported() { bool VulkanDriver::isDepthStencilBlitSupported(TextureFormat format) { auto const& formats = mContext.getBlittableDepthStencilFormats(); - return std::find(formats.begin(), formats.end(), getVkFormat(format)) != formats.end(); + return std::find(formats.begin(), formats.end(), fvkutils::getVkFormat(format)) != + formats.end(); } -bool VulkanDriver::isProtectedTexturesSupported() { - return false; -} +bool VulkanDriver::isProtectedTexturesSupported() { return false; } bool VulkanDriver::isDepthClampSupported() { return mContext.isDepthClampSupported(); @@ -1680,25 +1681,25 @@ void VulkanDriver::bindPipeline(PipelineState const& pipelineState) { auto rt = mCurrentRenderPass.renderTarget; VulkanPipelineCache::RasterState const vulkanRasterState{ - .cullMode = getCullMode(rasterState.culling), - .frontFace = getFrontFace(rasterState.inverseFrontFaces), + .cullMode = fvkutils::getCullMode(rasterState.culling), + .frontFace = fvkutils::getFrontFace(rasterState.inverseFrontFaces), .depthBiasEnable = (depthOffset.constant || depthOffset.slope) ? true : false, .blendEnable = rasterState.hasBlending(), .depthWriteEnable = rasterState.depthWrite, .alphaToCoverageEnable = rasterState.alphaToCoverage, - .srcColorBlendFactor = getBlendFactor(rasterState.blendFunctionSrcRGB), - .dstColorBlendFactor = getBlendFactor(rasterState.blendFunctionDstRGB), - .srcAlphaBlendFactor = getBlendFactor(rasterState.blendFunctionSrcAlpha), - .dstAlphaBlendFactor = getBlendFactor(rasterState.blendFunctionDstAlpha), + .srcColorBlendFactor = fvkutils::getBlendFactor(rasterState.blendFunctionSrcRGB), + .dstColorBlendFactor = fvkutils::getBlendFactor(rasterState.blendFunctionDstRGB), + .srcAlphaBlendFactor = fvkutils::getBlendFactor(rasterState.blendFunctionSrcAlpha), + .dstAlphaBlendFactor = fvkutils::getBlendFactor(rasterState.blendFunctionDstAlpha), .colorWriteMask = (VkColorComponentFlags) (rasterState.colorWrite ? 0xf : 0x0), .rasterizationSamples = rt->getSamples(), .depthClamp = rasterState.depthClamp, .colorTargetCount = rt->getColorTargetCount(mCurrentRenderPass), .colorBlendOp = rasterState.blendEquationRGB, - .alphaBlendOp = rasterState.blendEquationAlpha, + .alphaBlendOp = rasterState.blendEquationAlpha, .depthCompareOp = rasterState.depthFunc, .depthBiasConstantFactor = depthOffset.constant, - .depthBiasSlopeFactor = depthOffset.slope + .depthBiasSlopeFactor = depthOffset.slope, }; // unfortunately in Vulkan the topology is per pipeline @@ -1735,7 +1736,7 @@ void VulkanDriver::bindPipeline(PipelineState const& pipelineState) { mBoundPipeline = { .program = program, .pipelineLayout = pipelineLayout, - .descriptorSetMask = DescriptorSetMask(descriptorSetMaskTable[layoutCount]), + .descriptorSetMask = fvkutils::DescriptorSetMask(descriptorSetMaskTable[layoutCount]), }; mPipelineCache.bindLayout(pipelineLayout); diff --git a/filament/backend/src/vulkan/VulkanDriver.h b/filament/backend/src/vulkan/VulkanDriver.h index 0d826fca48..1621dc1106 100644 --- a/filament/backend/src/vulkan/VulkanDriver.h +++ b/filament/backend/src/vulkan/VulkanDriver.h @@ -26,12 +26,13 @@ #include "VulkanReadPixels.h" #include "VulkanSamplerCache.h" #include "VulkanStagePool.h" -#include "VulkanUtility.h" +#include "vulkan/caching/VulkanDescriptorSetManager.h" +#include "vulkan/caching/VulkanPipelineLayoutCache.h" +#include "vulkan/memory/ResourceManager.h" +#include "vulkan/memory/ResourcePointer.h" +#include "vulkan/utils/Definitions.h" + #include "backend/DriverEnums.h" -#include "caching/VulkanDescriptorSetManager.h" -#include "caching/VulkanPipelineLayoutCache.h" -#include "memory/ResourceManager.h" -#include "memory/ResourcePointer.h" #include "DriverBase.h" #include "private/backend/Driver.h" @@ -142,13 +143,14 @@ private: struct { resource_ptr program; VkPipelineLayout pipelineLayout; - DescriptorSetMask descriptorSetMask; + fvkutils::DescriptorSetMask descriptorSetMask; } mBoundPipeline = {}; // We need to store information about a render pass to enable better barriers at the end of a // renderpass. struct { - using AttachmentArray = CappedArray; + using AttachmentArray = + fvkutils::StaticVector; AttachmentArray attachments; } mRenderPassFboInfo = {}; diff --git a/filament/backend/src/vulkan/VulkanFboCache.cpp b/filament/backend/src/vulkan/VulkanFboCache.cpp index 3d76424e36..936b6672c2 100644 --- a/filament/backend/src/vulkan/VulkanFboCache.cpp +++ b/filament/backend/src/vulkan/VulkanFboCache.cpp @@ -14,12 +14,12 @@ * limitations under the License. */ -#include "vulkan/VulkanFboCache.h" - -#include +#include "VulkanFboCache.h" #include "VulkanConstants.h" -#include "VulkanUtility.h" +#include "vulkan/utils/Image.h" + +#include // If any VkRenderPass or VkFramebuffer is unused for more than TIME_BEFORE_EVICTION frames, it // is evicted from the cache. @@ -214,7 +214,7 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey const& config) noexcept if (config.colorFormat[i] == VK_FORMAT_UNDEFINED) { continue; } - const VkImageLayout subpassLayout = imgutil::getVkLayout(VulkanLayout::COLOR_ATTACHMENT); + const VkImageLayout subpassLayout = fvkutils::getVkLayout(VulkanLayout::COLOR_ATTACHMENT); uint32_t index; if (!hasSubpasses) { @@ -259,8 +259,8 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey const& config) noexcept .storeOp = (config.usesLazilyAllocatedMemory & (1 << i)) ? kDisableStore : kEnableStore, .stencilLoadOp = kDontCare, .stencilStoreOp = kDisableStore, - .initialLayout = imgutil::getVkLayout(VulkanLayout::COLOR_ATTACHMENT), - .finalLayout = imgutil::getVkLayout(FINAL_COLOR_ATTACHMENT_LAYOUT), + .initialLayout = fvkutils::getVkLayout(VulkanLayout::COLOR_ATTACHMENT), + .finalLayout = fvkutils::getVkLayout(FINAL_COLOR_ATTACHMENT_LAYOUT), }; } @@ -287,7 +287,7 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey const& config) noexcept pResolveAttachment->attachment = attachmentIndex; pResolveAttachment->layout - = imgutil::getVkLayout(VulkanLayout::COLOR_ATTACHMENT_RESOLVE); + = fvkutils::getVkLayout(VulkanLayout::COLOR_ATTACHMENT_RESOLVE); ++pResolveAttachment; attachments[attachmentIndex++] = { @@ -297,8 +297,8 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey const& config) noexcept .storeOp = kEnableStore, .stencilLoadOp = kDontCare, .stencilStoreOp = kDisableStore, - .initialLayout = imgutil::getVkLayout(VulkanLayout::COLOR_ATTACHMENT), - .finalLayout = imgutil::getVkLayout(FINAL_COLOR_ATTACHMENT_LAYOUT), + .initialLayout = fvkutils::getVkLayout(VulkanLayout::COLOR_ATTACHMENT), + .finalLayout = fvkutils::getVkLayout(FINAL_COLOR_ATTACHMENT_LAYOUT), }; } @@ -307,7 +307,7 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey const& config) noexcept const bool clear = any(config.clear & TargetBufferFlags::DEPTH); const bool discardStart = any(config.discardStart & TargetBufferFlags::DEPTH); const bool discardEnd = any(config.discardEnd & TargetBufferFlags::DEPTH); - depthAttachmentRef.layout = imgutil::getVkLayout(VulkanLayout::DEPTH_ATTACHMENT); + depthAttachmentRef.layout = fvkutils::getVkLayout(VulkanLayout::DEPTH_ATTACHMENT); depthAttachmentRef.attachment = attachmentIndex; attachments[attachmentIndex++] = { .format = config.depthFormat, @@ -316,8 +316,8 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey const& config) noexcept .storeOp = discardEnd ? kDisableStore : kEnableStore, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = imgutil::getVkLayout(config.initialDepthLayout), - .finalLayout = imgutil::getVkLayout(FINAL_DEPTH_ATTACHMENT_LAYOUT), + .initialLayout = fvkutils::getVkLayout(config.initialDepthLayout), + .finalLayout = fvkutils::getVkLayout(FINAL_DEPTH_ATTACHMENT_LAYOUT), }; } renderPassInfo.attachmentCount = attachmentIndex; diff --git a/filament/backend/src/vulkan/VulkanHandles.cpp b/filament/backend/src/vulkan/VulkanHandles.cpp index 29c33a82b1..3a7ac6b134 100644 --- a/filament/backend/src/vulkan/VulkanHandles.cpp +++ b/filament/backend/src/vulkan/VulkanHandles.cpp @@ -22,9 +22,11 @@ #include "VulkanDriver.h" #include "VulkanMemory.h" -#include "VulkanUtility.h" #include "vulkan/memory/ResourcePointer.h" -#include "spirv/VulkanSpirvUtils.h" +#include "vulkan/utils/Conversion.h" +#include "vulkan/utils/Definitions.h" +#include "vulkan/utils/Image.h" +#include "vulkan/utils/Spirv.h" #include @@ -56,10 +58,10 @@ template inline void fromStageFlags(backend::ShaderStageFlags stage, descriptor_binding_t binding, Bitmask& mask) { if ((bool) (stage & ShaderStageFlags::VERTEX)) { - mask.set(binding + getVertexStageShift()); + mask.set(binding + fvkutils::getVertexStageShift()); } if ((bool) (stage & ShaderStageFlags::FRAGMENT)) { - mask.set(binding + getFragmentStageShift()); + mask.set(binding + fvkutils::getFragmentStageShift()); } } @@ -206,7 +208,7 @@ VulkanProgram::VulkanProgram(VkDevice device, Program const& builder) noexcept size_t dataSize = blob.size(); if (!specializationConstants.empty()) { - workaroundSpecConstant(blob, specializationConstants, shader); + fvkutils::workaroundSpecConstant(blob, specializationConstants, shader); data = (uint32_t*) shader.data(); dataSize = shader.size() * 4; } @@ -314,8 +316,8 @@ VulkanRenderTarget::VulkanRenderTarget(VkDevice device, VkPhysicalDevice physica // Constrain the sample count according to both kinds of sample count masks obtained from // VkPhysicalDeviceProperties. This is consistent with the VulkanTexture constructor. auto const& limits = context.getPhysicalDeviceLimits(); - samples = reduceSampleCount(samples, limits.framebufferDepthSampleCounts & - limits.framebufferColorSampleCounts); + samples = samples = fvkutils::reduceSampleCount(samples, + limits.framebufferDepthSampleCounts & limits.framebufferColorSampleCounts); auto& rpkey = mInfo->rpkey; rpkey.samples = samples; @@ -498,7 +500,7 @@ VulkanVertexBufferInfo::VulkanVertexBufferInfo( Attribute attrib = attributes[attribIndex]; bool const isInteger = attrib.flags & Attribute::FLAG_INTEGER_TARGET; bool const isNormalized = attrib.flags & Attribute::FLAG_NORMALIZED; - VkFormat vkformat = getVkFormat(attrib.type, isNormalized, isInteger); + VkFormat vkformat = fvkutils::getVkFormat(attrib.type, isNormalized, isInteger); // HACK: Re-use the positions buffer as a dummy buffer for disabled attributes. Filament's // vertex shaders declare all attributes as either vec4 or uvec4 (the latter for bone diff --git a/filament/backend/src/vulkan/VulkanHandles.h b/filament/backend/src/vulkan/VulkanHandles.h index 3250985228..f3656ee6de 100644 --- a/filament/backend/src/vulkan/VulkanHandles.h +++ b/filament/backend/src/vulkan/VulkanHandles.h @@ -25,8 +25,9 @@ #include "VulkanFboCache.h" #include "VulkanSwapChain.h" #include "VulkanTexture.h" -#include "VulkanUtility.h" #include "vulkan/memory/Resource.h" +#include "vulkan/utils/StaticVector.h" +#include "vulkan/utils/Definitions.h" #include @@ -44,11 +45,11 @@ namespace { template inline uint8_t collapsedCount(Bitmask const& mask) { static_assert(sizeof(mask) <= 64); - constexpr uint64_t VERTEX_MASK = (1ULL << getFragmentStageShift()) - 1ULL; - constexpr uint64_t FRAGMENT_MASK = (VERTEX_MASK << getFragmentStageShift()); + constexpr uint64_t VERTEX_MASK = (1ULL << fvkutils::getFragmentStageShift()) - 1ULL; + constexpr uint64_t FRAGMENT_MASK = (VERTEX_MASK << fvkutils::getFragmentStageShift()); uint64_t val = mask.getValue(); - val = ((val & VERTEX_MASK) >> getVertexStageShift()) | - ((val & FRAGMENT_MASK) >> getFragmentStageShift()); + val = ((val & VERTEX_MASK) >> fvkutils::getVertexStageShift()) | + ((val & FRAGMENT_MASK) >> fvkutils::getFragmentStageShift()); return (uint8_t) Bitmask(val).count(); } @@ -67,10 +68,10 @@ struct VulkanDescriptorSetLayout : public HwDescriptorSetLayout, fvkmemory::Reso // The bitmask representation of a set layout. struct Bitmask { // TODO: better utiltize the space below and use bitset instead. - UniformBufferBitmask ubo; // 8 bytes - UniformBufferBitmask dynamicUbo; // 8 bytes - SamplerBitmask sampler; // 8 bytes - InputAttachmentBitmask inputAttachment; // 8 bytes + fvkutils::UniformBufferBitmask ubo; // 8 bytes + fvkutils::UniformBufferBitmask dynamicUbo; // 8 bytes + fvkutils::SamplerBitmask sampler; // 8 bytes + fvkutils::InputAttachmentBitmask inputAttachment; // 8 bytes bool operator==(Bitmask const& right) const { return ubo == right.ubo && dynamicUbo == right.dynamicUbo && sampler == right.sampler && @@ -138,7 +139,7 @@ public: using OnRecycle = std::function; VulkanDescriptorSet(VkDescriptorSet rawSet, - UniformBufferBitmask const& dynamicUboMask, + fvkutils::UniformBufferBitmask const& dynamicUboMask, uint8_t uniqueDynamicUboCount, OnRecycle&& onRecycleFn) : vkSet(rawSet), @@ -164,7 +165,7 @@ public: void acquire(fvkmemory::resource_ptr buffer); VkDescriptorSet const vkSet; - UniformBufferBitmask const dynamicUboMask; + fvkutils::UniformBufferBitmask const dynamicUboMask; uint8_t const uniqueDynamicUboCount; private: @@ -193,7 +194,7 @@ private: }; struct VulkanProgram : public HwProgram, fvkmemory::Resource { - using BindingList = CappedArray; + using BindingList = fvkutils::StaticVector; VulkanProgram(VkDevice device, Program const& builder) noexcept; ~VulkanProgram(); diff --git a/filament/backend/src/vulkan/VulkanPipelineCache.cpp b/filament/backend/src/vulkan/VulkanPipelineCache.cpp index 8f6e5df8de..e7fc0431c7 100644 --- a/filament/backend/src/vulkan/VulkanPipelineCache.cpp +++ b/filament/backend/src/vulkan/VulkanPipelineCache.cpp @@ -24,7 +24,7 @@ #include "VulkanConstants.h" #include "VulkanHandles.h" #include "VulkanTexture.h" -#include "VulkanUtility.h" +#include "vulkan/utils/Conversion.h" #if defined(__clang__) // Vulkan functions often immediately dereference pointers, so it's fine to pass in a pointer @@ -196,7 +196,7 @@ VulkanPipelineCache::PipelineCacheEntry* VulkanPipelineCache::createPipeline() n vkDs.depthTestEnable = VK_TRUE; vkDs.depthWriteEnable = raster.depthWriteEnable; - vkDs.depthCompareOp = getCompareOp(raster.depthCompareOp); + vkDs.depthCompareOp = fvkutils::getCompareOp(raster.depthCompareOp); vkDs.depthBoundsTestEnable = VK_FALSE; vkDs.stencilTestEnable = VK_FALSE; vkDs.minDepthBounds = 0.0f; diff --git a/filament/backend/src/vulkan/VulkanPipelineCache.h b/filament/backend/src/vulkan/VulkanPipelineCache.h index a4a6e28c38..a3f372fb25 100644 --- a/filament/backend/src/vulkan/VulkanPipelineCache.h +++ b/filament/backend/src/vulkan/VulkanPipelineCache.h @@ -19,7 +19,6 @@ #include "VulkanCommands.h" #include "VulkanMemory.h" -#include "VulkanUtility.h" #include #include diff --git a/filament/backend/src/vulkan/VulkanReadPixels.cpp b/filament/backend/src/vulkan/VulkanReadPixels.cpp index 48df6c7222..7e7008ab14 100644 --- a/filament/backend/src/vulkan/VulkanReadPixels.cpp +++ b/filament/backend/src/vulkan/VulkanReadPixels.cpp @@ -19,8 +19,9 @@ #include "DataReshaper.h" #include "VulkanCommands.h" #include "VulkanHandles.h" -#include "VulkanImageUtility.h" #include "VulkanTexture.h" +#include "vulkan/utils/Conversion.h" // getComponentType() +#include "vulkan/utils/Image.h" #include @@ -218,7 +219,7 @@ void VulkanReadPixels::run(fvkmemory::resource_ptr srcTarget }; vkBeginCommandBuffer(cmdbuffer, &binfo); - imgutil::transitionLayout(cmdbuffer, { + fvkutils::transitionLayout(cmdbuffer, { .image = stagingImage, .oldLayout = VulkanLayout::UNDEFINED, .newLayout = VulkanLayout::TRANSFER_DST, @@ -265,8 +266,8 @@ void VulkanReadPixels::run(fvkmemory::resource_ptr srcTarget imageCopyRegion.srcOffset.y + imageCopyRegion.extent.height <= srcExtent.height); vkCmdCopyImage(cmdbuffer, srcAttachment.getImage(), - imgutil::getVkLayout(VulkanLayout::TRANSFER_SRC), stagingImage, - imgutil::getVkLayout(VulkanLayout::TRANSFER_DST), 1, &imageCopyRegion); + fvkutils::getVkLayout(VulkanLayout::TRANSFER_SRC), stagingImage, + fvkutils::getVkLayout(VulkanLayout::TRANSFER_DST), 1, &imageCopyRegion); // Restore the source image layout. srcTexture->transitionLayout(cmdbuffer, srcRange, srcTexture->getDefaultLayout()); @@ -318,8 +319,8 @@ void VulkanReadPixels::run(fvkmemory::resource_ptr srcTarget vkMapMemory(device, stagingMemory, 0, VK_WHOLE_SIZE, 0, (void**) &srcPixels); srcPixels += subResourceLayout.offset; - if (!DataReshaper::reshapeImage(&p, getComponentType(srcFormat), - getComponentCount(srcFormat), srcPixels, + if (!DataReshaper::reshapeImage(&p, fvkutils::getComponentType(srcFormat), + fvkutils::getComponentCount(srcFormat), srcPixels, static_cast(subResourceLayout.rowPitch), static_cast(width), static_cast(height), swizzle)) { FVK_LOGE << "Unsupported PixelDataFormat or PixelDataType" << utils::io::endl; diff --git a/filament/backend/src/vulkan/VulkanSamplerCache.cpp b/filament/backend/src/vulkan/VulkanSamplerCache.cpp index 75a2578e75..005c16c525 100644 --- a/filament/backend/src/vulkan/VulkanSamplerCache.cpp +++ b/filament/backend/src/vulkan/VulkanSamplerCache.cpp @@ -15,6 +15,7 @@ */ #include "vulkan/VulkanSamplerCache.h" +#include "vulkan/utils/Conversion.h" #include @@ -114,7 +115,7 @@ VkSampler VulkanSamplerCache::getSampler(SamplerParams params) noexcept { .anisotropyEnable = params.anisotropyLog2 == 0 ? 0u : 1u, .maxAnisotropy = (float)(1u << params.anisotropyLog2), .compareEnable = getCompareEnable(params.compareMode), - .compareOp = getCompareOp(params.compareFunc), + .compareOp = fvkutils::getCompareOp(params.compareFunc), .minLod = 0.0f, .maxLod = getMaxLod(params.filterMin), .borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK, diff --git a/filament/backend/src/vulkan/VulkanSamplerCache.h b/filament/backend/src/vulkan/VulkanSamplerCache.h index cb5fe43ce4..31e902c582 100644 --- a/filament/backend/src/vulkan/VulkanSamplerCache.h +++ b/filament/backend/src/vulkan/VulkanSamplerCache.h @@ -18,7 +18,6 @@ #define TNT_FILAMENT_BACKEND_VULKANSAMPLERCACHE_H #include "VulkanContext.h" -#include "VulkanUtility.h" #include diff --git a/filament/backend/src/vulkan/VulkanStagePool.cpp b/filament/backend/src/vulkan/VulkanStagePool.cpp index cae1e85d25..02e0f0eab1 100644 --- a/filament/backend/src/vulkan/VulkanStagePool.cpp +++ b/filament/backend/src/vulkan/VulkanStagePool.cpp @@ -18,9 +18,9 @@ #include "VulkanCommands.h" #include "VulkanConstants.h" -#include "VulkanImageUtility.h" #include "VulkanMemory.h" -#include "VulkanUtility.h" +#include "vulkan/utils/Conversion.h" +#include "vulkan/utils/Image.h" #include @@ -72,7 +72,7 @@ VulkanStage const* VulkanStagePool::acquireStage(uint32_t numBytes) { VulkanStageImage const* VulkanStagePool::acquireImage(PixelDataFormat format, PixelDataType type, uint32_t width, uint32_t height) { - const VkFormat vkformat = getVkFormat(format, type); + const VkFormat vkformat = fvkutils::getVkFormat(format, type); for (auto image : mFreeImages) { if (image->format == vkformat && image->width == width && image->height == height) { mFreeImages.erase(image); @@ -113,7 +113,7 @@ VulkanStageImage const* VulkanStagePool::acquireImage(PixelDataFormat format, Pi assert_invariant(result == VK_SUCCESS); - VkImageAspectFlags const aspectFlags = getImageAspect(vkformat); + VkImageAspectFlags const aspectFlags = fvkutils::getImageAspect(vkformat); VkCommandBuffer const cmdbuffer = mCommands->get().buffer(); // We use VK_IMAGE_LAYOUT_GENERAL here because the spec says: @@ -122,7 +122,7 @@ VulkanStageImage const* VulkanStagePool::acquireImage(PixelDataFormat format, Pi // VK_IMAGE_LAYOUT_PREINITIALIZED or VK_IMAGE_LAYOUT_GENERAL layout. Calling // vkGetImageSubresourceLayout for a linear image returns a subresource layout mapping that is // valid for either of those image layouts." - imgutil::transitionLayout(cmdbuffer, { + fvkutils::transitionLayout(cmdbuffer, { .image = image->image, .oldLayout = VulkanLayout::UNDEFINED, .newLayout = VulkanLayout::READ_WRITE, // (= VK_IMAGE_LAYOUT_GENERAL) diff --git a/filament/backend/src/vulkan/VulkanTexture.cpp b/filament/backend/src/vulkan/VulkanTexture.cpp index 2f30ee20c9..ff3f4f9a2b 100644 --- a/filament/backend/src/vulkan/VulkanTexture.cpp +++ b/filament/backend/src/vulkan/VulkanTexture.cpp @@ -17,8 +17,8 @@ #include "VulkanCommands.h" #include "VulkanMemory.h" #include "VulkanTexture.h" -#include "VulkanUtility.h" #include "vulkan/memory/ResourcePointer.h" +#include "vulkan/utils/Conversion.h" #include #include @@ -152,7 +152,7 @@ VulkanTextureState::VulkanTextureState(VkDevice device, VmaAllocator allocator, bool isProtected) : mVkFormat(format), mViewType(viewType), - mFullViewRange{filament::backend::getImageAspect(format), 0, levels, 0, layerCount}, + mFullViewRange{fvkutils::getImageAspect(format), 0, levels, 0, layerCount}, mDefaultLayout(defaultLayout), mIsProtected(isProtected), mStagePool(stagePool), @@ -169,7 +169,7 @@ VulkanTexture::VulkanTexture(VkDevice device, VmaAllocator allocator, : HwTexture(SamplerType::SAMPLER_2D, 1, samples, width, height, 1, TextureFormat::UNUSED, tusage), mState(fvkmemory::resource_ptr::construct(resourceManager, device, - allocator, commands, stagePool, format, imgutil::getViewType(SamplerType::SAMPLER_2D), + allocator, commands, stagePool, format, fvkutils::getViewType(SamplerType::SAMPLER_2D), 1, 1, getDefaultLayoutImpl(tusage), any(usage & TextureUsage::PROTECTED))) { mState->mTextureImage = image; mState->mTextureImageMemory = memory; @@ -183,9 +183,10 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice, uint8_t levels, TextureFormat tformat, uint8_t samples, uint32_t w, uint32_t h, uint32_t depth, TextureUsage tusage, VulkanStagePool& stagePool) : HwTexture(target, levels, samples, w, h, depth, tformat, tusage), + mState(fvkmemory::resource_ptr::construct(resourceManager, device, - allocator, commands, stagePool, backend::getVkFormat(tformat), - imgutil::getViewType(target), levels, getLayerCount(target, depth), + allocator, commands, stagePool, fvkutils::getVkFormat(tformat), + fvkutils::getViewType(target), levels, getLayerCount(target, depth), VulkanLayout::UNDEFINED, any(usage & TextureUsage::PROTECTED))) { // Create an appropriately-sized device-only VkImage, but do not fill it yet. VkImageCreateInfo imageInfo{ @@ -281,16 +282,17 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice, // any kind of attachment (color or depth). const auto& limits = context.getPhysicalDeviceLimits(); if (imageInfo.usage & VK_IMAGE_USAGE_SAMPLED_BIT) { - samples = reduceSampleCount(samples, isVkDepthFormat(mState->mVkFormat) - ? limits.sampledImageDepthSampleCounts - : limits.sampledImageColorSampleCounts); + samples = fvkutils::reduceSampleCount(samples, + fvkutils::isVkDepthFormat(mState->mVkFormat) + ? limits.sampledImageDepthSampleCounts + : limits.sampledImageColorSampleCounts); } if (imageInfo.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { - samples = reduceSampleCount(samples, limits.framebufferColorSampleCounts); + samples = fvkutils::reduceSampleCount(samples, limits.framebufferColorSampleCounts); } if (imageInfo.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - samples = reduceSampleCount(samples, limits.sampledImageDepthSampleCounts); + samples = fvkutils::reduceSampleCount(samples, limits.sampledImageDepthSampleCounts); } this->samples = samples; imageInfo.samples = (VkSampleCountFlagBits) samples; @@ -401,8 +403,8 @@ void VulkanTexture::updateImage(const PixelBufferDescriptor& data, uint32_t widt } // If format conversion is both required and supported, use vkCmdBlitImage. - const VkFormat hostFormat = backend::getVkFormat(hostData->format, hostData->type); - const VkFormat deviceFormat = getVkFormatLinear(mState->mVkFormat); + const VkFormat hostFormat = fvkutils::getVkFormat(hostData->format, hostData->type); + const VkFormat deviceFormat = fvkutils::getVkFormatLinear(mState->mVkFormat); if (hostFormat != deviceFormat && hostFormat != VK_FORMAT_UNDEFINED) { assert_invariant(xoffset == 0 && yoffset == 0 && zoffset == 0 && "Offsets not yet supported when format conversion is required."); @@ -461,7 +463,7 @@ void VulkanTexture::updateImage(const PixelBufferDescriptor& data, uint32_t widt VulkanLayout const newLayout = VulkanLayout::TRANSFER_DST; VulkanLayout nextLayout = getLayout(transitionRange.baseArrayLayer, miplevel); - VkImageLayout const newVkLayout = imgutil::getVkLayout(newLayout); + VkImageLayout const newVkLayout = fvkutils::getVkLayout(newLayout); if (nextLayout == VulkanLayout::UNDEFINED) { nextLayout = getDefaultLayout(); @@ -508,8 +510,8 @@ void VulkanTexture::updateImageWithBlit(const PixelBufferDescriptor& hostData, u VulkanLayout const oldLayout = getLayout(layer, miplevel); transitionLayout(&commands, range, newLayout); - vkCmdBlitImage(cmdbuf, stage->image, imgutil::getVkLayout(VulkanLayout::TRANSFER_SRC), - mState->mTextureImage, imgutil::getVkLayout(newLayout), 1, blitRegions, VK_FILTER_NEAREST); + vkCmdBlitImage(cmdbuf, stage->image, fvkutils::getVkLayout(VulkanLayout::TRANSFER_SRC), + mState->mTextureImage, fvkutils::getVkLayout(newLayout), 1, blitRegions, VK_FILTER_NEAREST); transitionLayout(&commands, range, oldLayout); } @@ -557,7 +559,7 @@ VkImageView VulkanTexture::getImageView(VkImageSubresourceRange range, VkImageVi VkImageAspectFlags VulkanTexture::getImageAspect() const { // Helper function in VulkanUtility - return filament::backend::getImageAspect(mState->mVkFormat); + return fvkutils::getImageAspect(mState->mVkFormat); } bool VulkanTexture::transitionLayout(VulkanCommandBuffer* commands, @@ -600,7 +602,7 @@ bool VulkanTexture::transitionLayout(VkCommandBuffer cmdbuf, VkImageSubresourceR if (layout == newLayout) { continue; } - hasTransitions = hasTransitions || imgutil::transitionLayout(cmdbuf, { + hasTransitions = hasTransitions || fvkutils::transitionLayout(cmdbuf, { .image = mState->mTextureImage, .oldLayout = layout, .newLayout = newLayout, @@ -615,7 +617,7 @@ bool VulkanTexture::transitionLayout(VkCommandBuffer cmdbuf, VkImageSubresourceR } } } else if (newLayout != oldLayout) { - hasTransitions = imgutil::transitionLayout(cmdbuf, { + hasTransitions = fvkutils::transitionLayout(cmdbuf, { .image = mState->mTextureImage, .oldLayout = oldLayout, .newLayout = newLayout, @@ -650,7 +652,7 @@ void VulkanTexture::samplerToAttachmentBarrier(VulkanCommandBuffer* commands, VkImageSubresourceRange const& range) { VkCommandBuffer const cmdbuf = commands->buffer(); VkImageLayout const layout = - imgutil::getVkLayout(getLayout(range.baseArrayLayer, range.baseMipLevel)); + fvkutils::getVkLayout(getLayout(range.baseArrayLayer, range.baseMipLevel)); VkImageMemoryBarrier barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .srcAccessMask = VK_ACCESS_SHADER_READ_BIT, @@ -673,7 +675,7 @@ void VulkanTexture::attachmentToSamplerBarrier(VulkanCommandBuffer* commands, VkImageSubresourceRange const& range) { VkCommandBuffer const cmdbuf = commands->buffer(); VkImageLayout const layout - = imgutil::getVkLayout(getLayout(range.baseArrayLayer, range.baseMipLevel)); + = fvkutils::getVkLayout(getLayout(range.baseArrayLayer, range.baseMipLevel)); VkImageMemoryBarrier barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, diff --git a/filament/backend/src/vulkan/VulkanTexture.h b/filament/backend/src/vulkan/VulkanTexture.h index 1889adf121..7f1cfe4e42 100644 --- a/filament/backend/src/vulkan/VulkanTexture.h +++ b/filament/backend/src/vulkan/VulkanTexture.h @@ -20,9 +20,9 @@ #include "DriverBase.h" #include "VulkanBuffer.h" -#include "VulkanImageUtility.h" #include "vulkan/memory/Resource.h" #include "vulkan/memory/ResourcePointer.h" +#include "vulkan/utils/Image.h" #include #include diff --git a/filament/backend/src/vulkan/caching/VulkanDescriptorSetManager.cpp b/filament/backend/src/vulkan/caching/VulkanDescriptorSetManager.cpp index 19aa989b8c..570dcc5df2 100644 --- a/filament/backend/src/vulkan/caching/VulkanDescriptorSetManager.cpp +++ b/filament/backend/src/vulkan/caching/VulkanDescriptorSetManager.cpp @@ -16,11 +16,10 @@ #include "VulkanDescriptorSetManager.h" -#include -#include -#include -#include -#include +#include "vulkan/VulkanCommands.h" +#include "vulkan/VulkanHandles.h" +#include "vulkan/VulkanConstants.h" + #include #include @@ -207,17 +206,17 @@ uint32_t createBindings(VkDescriptorSetLayoutBinding* toBind, uint32_t count, Vk mask.forEachSetBit([&](size_t index) { VkShaderStageFlags stages = 0; uint32_t binding = 0; - if (index < getFragmentStageShift()) { + if (index < fvkutils::getFragmentStageShift()) { binding = (uint32_t) index; stages |= VK_SHADER_STAGE_VERTEX_BIT; - auto fragIndex = index + getFragmentStageShift(); + auto fragIndex = index + fvkutils::getFragmentStageShift(); if (mask.test(fragIndex)) { stages |= VK_SHADER_STAGE_FRAGMENT_BIT; alreadySeen.set(fragIndex); } } else if (!alreadySeen.test(index)) { // We are in fragment stage bits - binding = (uint32_t) (index - getFragmentStageShift()); + binding = (uint32_t) (index - fvkutils::getFragmentStageShift()); stages |= VK_SHADER_STAGE_FRAGMENT_BIT; } @@ -346,7 +345,6 @@ private: mVkLayouts; }; - VulkanDescriptorSetManager::VulkanDescriptorSetManager(VkDevice device, fvkmemory::ResourceManager* resourceManager) : mDevice(device), @@ -376,10 +374,10 @@ void VulkanDescriptorSetManager::unbind(uint8_t setIndex) { } void VulkanDescriptorSetManager::commit(VulkanCommandBuffer* commands, - VkPipelineLayout pipelineLayout, DescriptorSetMask const& setMask) { + VkPipelineLayout pipelineLayout, fvkutils::DescriptorSetMask const& setMask) { // setMask indicates the set of descriptor sets the driver wants to bind, curMask is the // actual set of sets that *needs* to be bound. - DescriptorSetMask curMask = setMask; + fvkutils::DescriptorSetMask curMask = setMask; auto& updateSets = mStashedSets; auto& lastBoundSets = mLastBoundInfo.boundSets; @@ -458,7 +456,7 @@ void VulkanDescriptorSetManager::updateSampler(fvkmemory::resource_ptrgetViewForType(range, expectedType); } - info.imageLayout = imgutil::getVkLayout(texture->getDefaultLayout()); + info.imageLayout = fvkutils::getVkLayout(texture->getDefaultLayout()); VkWriteDescriptorSet const descriptorWrite = { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .pNext = nullptr, diff --git a/filament/backend/src/vulkan/caching/VulkanDescriptorSetManager.h b/filament/backend/src/vulkan/caching/VulkanDescriptorSetManager.h index faeeb14420..87aa076213 100644 --- a/filament/backend/src/vulkan/caching/VulkanDescriptorSetManager.h +++ b/filament/backend/src/vulkan/caching/VulkanDescriptorSetManager.h @@ -18,9 +18,8 @@ #define TNT_FILAMENT_BACKEND_CACHING_VULKANDESCRIPTORSETMANAGER_H #include "vulkan/VulkanHandles.h" -#include "vulkan/VulkanTexture.h" -#include "vulkan/VulkanUtility.h" #include "vulkan/memory/ResourcePointer.h" +#include "vulkan/utils/Definitions.h" // For DescriptorSetMask #include #include @@ -68,7 +67,7 @@ public: void unbind(uint8_t setIndex); void commit(VulkanCommandBuffer* commands, VkPipelineLayout pipelineLayout, - DescriptorSetMask const& setMask); + fvkutils::DescriptorSetMask const& setMask); fvkmemory::resource_ptr createSet(Handle handle, fvkmemory::resource_ptr layout); @@ -93,7 +92,7 @@ private: struct { VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; - DescriptorSetMask setMask; + fvkutils::DescriptorSetMask setMask; DescriptorSetArray boundSets = {}; } mLastBoundInfo; }; diff --git a/filament/backend/src/vulkan/platform/VulkanPlatform.cpp b/filament/backend/src/vulkan/platform/VulkanPlatform.cpp index e20ae0270c..c76a1a08dd 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatform.cpp +++ b/filament/backend/src/vulkan/platform/VulkanPlatform.cpp @@ -21,7 +21,7 @@ #include "vulkan/platform/VulkanPlatformSwapChainImpl.h" #include "vulkan/VulkanConstants.h" #include "vulkan/VulkanDriver.h" -#include "vulkan/VulkanUtility.h" +#include "vulkan/utils/Helper.h" #include #include @@ -126,7 +126,7 @@ void printDeviceInfo(VkInstance instance, VkPhysicalDevice device) { const int minor = VK_VERSION_MINOR(deviceProperties.apiVersion); const FixedCapacityVector physicalDevices - = filament::backend::enumerate(vkEnumeratePhysicalDevices, instance); + = fvkutils::enumerate(vkEnumeratePhysicalDevices, instance); FVK_LOGI << "Selected physical device '" << deviceProperties.deviceName << "' from " << physicalDevices.size() << " physical devices. " @@ -172,7 +172,7 @@ ExtensionSet getInstanceExtensions(ExtensionSet const& externallyRequiredExts = }; ExtensionSet exts; FixedCapacityVector const availableExts = - filament::backend::enumerate(vkEnumerateInstanceExtensionProperties, + fvkutils::enumerate(vkEnumerateInstanceExtensionProperties, static_cast(nullptr) /* pLayerName */); for (auto const& extProps: availableExts) { utils::CString name { extProps.extensionName }; @@ -212,7 +212,7 @@ ExtensionSet getDeviceExtensions(VkPhysicalDevice device) { ExtensionSet exts; // Identify supported physical device extensions FixedCapacityVector const extensions - = filament::backend::enumerate(vkEnumerateDeviceExtensionProperties, device, + = fvkutils::enumerate(vkEnumerateDeviceExtensionProperties, device, static_cast(nullptr) /* pLayerName */); for (auto const& extension: extensions) { utils::CString name { extension.extensionName }; @@ -473,7 +473,7 @@ inline int deviceTypeOrder(VkPhysicalDeviceType deviceType) { VkPhysicalDevice selectPhysicalDevice(VkInstance instance, VulkanPlatform::Customization::GPUPreference const& gpuPreference) { FixedCapacityVector const physicalDevices = - filament::backend::enumerate(vkEnumeratePhysicalDevices, instance); + fvkutils::enumerate(vkEnumeratePhysicalDevices, instance); struct DeviceInfo { VkPhysicalDevice device = VK_NULL_HANDLE; VkPhysicalDeviceType deviceType = VK_PHYSICAL_DEVICE_TYPE_OTHER; @@ -508,7 +508,7 @@ VkPhysicalDevice selectPhysicalDevice(VkInstance instance, // Does the device support the VK_KHR_swapchain extension? FixedCapacityVector const extensions - = filament::backend::enumerate(vkEnumerateDeviceExtensionProperties, + = fvkutils::enumerate(vkEnumerateDeviceExtensionProperties, candidateDevice, static_cast(nullptr) /* pLayerName */); bool supportsSwapchain = false; for (auto const& extension: extensions) { @@ -560,7 +560,7 @@ VkPhysicalDevice selectPhysicalDevice(VkInstance instance, return device; } -VkFormatList findAttachmentDepthStencilFormats(VkPhysicalDevice device) { +fvkutils::VkFormatList findAttachmentDepthStencilFormats(VkPhysicalDevice device) { VkFormatFeatureFlags const features = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; // The ordering here indicates the preference of choosing depth+stencil format. @@ -579,17 +579,17 @@ VkFormatList findAttachmentDepthStencilFormats(VkPhysicalDevice device) { selectedFormats.push_back(format); } } - VkFormatList ret(selectedFormats.size()); + fvkutils::VkFormatList ret(selectedFormats.size()); std::copy(selectedFormats.begin(), selectedFormats.end(), ret.begin()); return ret; } -VkFormatList findBlittableDepthStencilFormats(VkPhysicalDevice device) { +fvkutils::VkFormatList findBlittableDepthStencilFormats(VkPhysicalDevice device) { std::vector selectedFormats; VkFormatFeatureFlags const required = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; - for (VkFormat format : ALL_VK_FORMATS) { - if (isVkDepthFormat(format)) { + for (VkFormat format : fvkutils::ALL_VK_FORMATS) { + if (fvkutils::isVkDepthFormat(format)) { VkFormatProperties props; vkGetPhysicalDeviceFormatProperties(device, format, &props); if ((props.optimalTilingFeatures & required) == required) { @@ -597,7 +597,7 @@ VkFormatList findBlittableDepthStencilFormats(VkPhysicalDevice device) { } } } - VkFormatList ret(selectedFormats.size()); + fvkutils::VkFormatList ret(selectedFormats.size()); std::copy(selectedFormats.begin(), selectedFormats.end(), ret.begin()); return ret; } diff --git a/filament/backend/src/vulkan/platform/VulkanPlatformAndroid.cpp b/filament/backend/src/vulkan/platform/VulkanPlatformAndroid.cpp index 0ea9df5fa4..268f2a4d02 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatformAndroid.cpp +++ b/filament/backend/src/vulkan/platform/VulkanPlatformAndroid.cpp @@ -199,7 +199,6 @@ VulkanPlatform::ExternalImageMetadata VulkanPlatform::getExternalImageMetadataIm FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "vkGetAndroidHardwareBufferProperties failed with error=" << static_cast(result); - FILAMENT_CHECK_POSTCONDITION(metadata.format == formatInfo.format) << "mismatched image format for external image (AHB)"; metadata.externalFormat = formatInfo.externalFormat; diff --git a/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp b/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp index cb80e48985..921b8c56eb 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp +++ b/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp @@ -17,7 +17,9 @@ #include "VulkanPlatformSwapChainImpl.h" #include "vulkan/VulkanConstants.h" -#include "vulkan/VulkanUtility.h" +#include "vulkan/utils/Definitions.h" +#include "vulkan/utils/Helper.h" +#include "vulkan/utils/Image.h" #include @@ -29,9 +31,8 @@ namespace filament::backend { namespace { std::tuple createImageAndMemory(VulkanContext const& context, - VkDevice device, VkExtent2D extent, VkFormat format, - bool isProtected) { - bool const isDepth = isVkDepthFormat(format); + VkDevice device, VkExtent2D extent, VkFormat format, bool isProtected) { + bool const isDepth = fvkutils::isVkDepthFormat(format); // Filament expects blit() to work with any texture, so we almost always set these usage flags // (see copyFrame() and readPixels()). VkImageUsageFlags const blittable = @@ -83,9 +84,9 @@ std::tuple createImageAndMemory(VulkanContext const& co return std::tuple(image, imageMemory); } -VkFormat selectDepthFormat(VkFormatList const& depthFormats, bool hasStencil) { +VkFormat selectDepthFormat(fvkutils::VkFormatList const& depthFormats, bool hasStencil) { auto const formatItr = std::find_if(depthFormats.begin(), depthFormats.end(), - hasStencil ? isVkStencilFormat : isVkDepthFormat); + hasStencil ? fvkutils::isVkStencilFormat : fvkutils::isVkDepthFormat); assert_invariant( formatItr != depthFormats.end() && "Cannot find suitable swapchain depth format"); return *formatItr; @@ -169,7 +170,7 @@ VkResult VulkanPlatformSurfaceSwapChain::create() { // Find a suitable surface format. FixedCapacityVector const surfaceFormats - = enumerate(vkGetPhysicalDeviceSurfaceFormatsKHR, mPhysicalDevice, mSurface); + = fvkutils::enumerate(vkGetPhysicalDeviceSurfaceFormatsKHR, mPhysicalDevice, mSurface); std::array expectedFormats = { VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM, @@ -193,8 +194,8 @@ VkResult VulkanPlatformSurfaceSwapChain::create() { // Verify that our chosen present mode is supported. In practice all devices support the FIFO // mode, but we check for it anyway for completeness. (and to avoid validation warnings) VkPresentModeKHR const desiredPresentMode = VK_PRESENT_MODE_FIFO_KHR; - FixedCapacityVector presentModes - = enumerate(vkGetPhysicalDeviceSurfacePresentModesKHR, mPhysicalDevice, mSurface); + FixedCapacityVector presentModes = fvkutils::enumerate( + vkGetPhysicalDeviceSurfacePresentModesKHR, mPhysicalDevice, mSurface); bool foundSuitablePresentMode = false; for (VkPresentModeKHR mode: presentModes) { if (mode == desiredPresentMode) { @@ -251,7 +252,7 @@ VkResult VulkanPlatformSurfaceSwapChain::create() { FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "vkCreateSwapchainKHR failed." << " error=" << static_cast(result); - mSwapChainBundle.colors = enumerate(vkGetSwapchainImagesKHR, mDevice, mSwapchain); + mSwapChainBundle.colors = fvkutils::enumerate(vkGetSwapchainImagesKHR, mDevice, mSwapchain); mSwapChainBundle.colorFormat = surfaceFormat.format; mSwapChainBundle.depthFormat = selectDepthFormat(mContext.getAttachmentDepthStencilFormats(), mHasStencil); @@ -329,7 +330,7 @@ bool VulkanPlatformSurfaceSwapChain::hasResized() { || perceivedExtent.height == VULKAN_UNDEFINED_EXTENT) { perceivedExtent = mFallbackExtent; } - return !equivalent(mSwapChainBundle.extent, perceivedExtent); + return !fvkutils::equivalent(mSwapChainBundle.extent, perceivedExtent); } bool VulkanPlatformSurfaceSwapChain::isProtected() { diff --git a/filament/backend/src/vulkan/VulkanUtility.cpp b/filament/backend/src/vulkan/utils/Conversion.cpp similarity index 92% rename from filament/backend/src/vulkan/VulkanUtility.cpp rename to filament/backend/src/vulkan/utils/Conversion.cpp index 889e2bdd2f..1d1f9d1c0f 100644 --- a/filament/backend/src/vulkan/VulkanUtility.cpp +++ b/filament/backend/src/vulkan/utils/Conversion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,17 +14,13 @@ * limitations under the License. */ -#include "VulkanUtility.h" +#include "vulkan/utils/Conversion.h" -#include -#include #include #include "private/backend/BackendUtils.h" -using namespace bluevk; - -namespace filament::backend { +namespace filament::backend::fvkutils { VkFormat getVkFormat(ElementType type, bool normalized, bool integer) { using ElementType = ElementType; @@ -235,12 +231,6 @@ VkFormat getVkFormat(TextureFormat format) { } } -// Converts PixelBufferDescriptor format + type pair into a VkFormat. -// -// NOTE: This function only returns formats that support VK_FORMAT_FEATURE_BLIT_SRC_BIT as per -// "Required Format Support" in the Vulkan specification. These are the only formats that can be -// used for format conversion. If the requested format does not support this feature, then -// VK_FORMAT_UNDEFINED is returned. VkFormat getVkFormat(PixelDataFormat format, PixelDataType type) { if (type == PixelDataType::USHORT_565) return VK_FORMAT_R5G6B5_UNORM_PACK16; if (type == PixelDataType::UINT_2_10_10_10_REV) return VK_FORMAT_A2B10G10R10_UNORM_PACK32; @@ -284,10 +274,6 @@ VkFormat getVkFormat(PixelDataFormat format, PixelDataType type) { return VK_FORMAT_UNDEFINED; } -// Converts an SRGB Vulkan format identifier into its corresponding canonical UNORM format. If the -// given format is not an SRGB format, it is returned unmodified. This function is useful when -// determining if blit-based conversion is needed, since SRGB is orthogonal to the actual bit layout -// of color components. VkFormat getVkFormatLinear(VkFormat format) { switch (format) { case VK_FORMAT_R8_SRGB: return VK_FORMAT_R8_UNORM; @@ -328,8 +314,6 @@ VkFormat getVkFormatLinear(VkFormat format) { return format; } -// See also FTexture::computeTextureDataSize, which takes a public-facing Texture format rather -// than a driver-level Texture format, and can account for a specified byte alignment. uint32_t getBytesPerPixel(TextureFormat format) { return (uint32_t) getFormatSize(format); } @@ -611,48 +595,4 @@ VkShaderStageFlags getShaderStageFlags(ShaderStageFlags stageFlags) { return flags; } -bool equivalent(const VkRect2D& a, const VkRect2D& b) { - // These are all integers so there's no need for an epsilon. - return a.extent.width == b.extent.width && a.extent.height == b.extent.height && - a.offset.x == b.offset.x && a.offset.y == b.offset.y; -} - -bool equivalent(const VkExtent2D& a, const VkExtent2D& b) { - return a.height == b.height && a.width == b.width; -} - -VkImageAspectFlags getImageAspect(VkFormat format) { - switch (format) { - case VK_FORMAT_D16_UNORM_S8_UINT: - case VK_FORMAT_D24_UNORM_S8_UINT: - case VK_FORMAT_D32_SFLOAT_S8_UINT: - return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; - case VK_FORMAT_D16_UNORM: - case VK_FORMAT_X8_D24_UNORM_PACK32: - case VK_FORMAT_D32_SFLOAT: - return VK_IMAGE_ASPECT_DEPTH_BIT; - case VK_FORMAT_S8_UINT: - return VK_IMAGE_ASPECT_STENCIL_BIT; - default: - return VK_IMAGE_ASPECT_COLOR_BIT; - } -} - -bool isVkDepthFormat(VkFormat format) { - return (getImageAspect(format) & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; -} - -bool isVkStencilFormat(VkFormat format) { - return (getImageAspect(format) & VK_IMAGE_ASPECT_STENCIL_BIT) != 0; -} - -static uint32_t mostSignificantBit(uint32_t x) { return 1ul << (31ul - utils::clz(x)); } - -uint8_t reduceSampleCount(uint8_t sampleCount, VkSampleCountFlags mask) { - if (sampleCount & mask) { - return sampleCount; - } - return mostSignificantBit((sampleCount - 1) & mask); -} - -} // namespace filament::backend +} // namespace filament::backend::fvkutils diff --git a/filament/backend/src/vulkan/utils/Conversion.h b/filament/backend/src/vulkan/utils/Conversion.h new file mode 100644 index 0000000000..10f5b5ad0d --- /dev/null +++ b/filament/backend/src/vulkan/utils/Conversion.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TNT_FILAMENT_BACKEND_VULKAN_UTILS_CONVERSION_H +#define TNT_FILAMENT_BACKEND_VULKAN_UTILS_CONVERSION_H + +#include + +#include // for getFormatSize() + +#include + +// Methods for converting Filament types to Vulkan types + +namespace filament::backend::fvkutils { + +VkFormat getVkFormat(ElementType type, bool normalized, bool integer); +VkFormat getVkFormat(TextureFormat format); + +// Converts PixelBufferDescriptor format + type pair into a VkFormat. +// NOTE: This function only returns formats that support VK_FORMAT_FEATURE_BLIT_SRC_BIT as per +// "Required Format Support" in the Vulkan specification. These are the only formats that can be +// used for format conversion. If the requested format does not support this feature, then +// VK_FORMAT_UNDEFINED is returned. +VkFormat getVkFormat(PixelDataFormat format, PixelDataType type); + +// Converts an SRGB Vulkan format identifier into its corresponding canonical UNORM format. If the +// given format is not an SRGB format, it is returned unmodified. This function is useful when +// determining if blit-based conversion is needed, since SRGB is orthogonal to the actual bit layout +// of color components. +VkFormat getVkFormatLinear(VkFormat format); + +// See also FTexture::computeTextureDataSize, which takes a public-facing Texture format rather +// than a driver-level Texture format, and can account for a specified byte alignment. +uint32_t getBytesPerPixel(TextureFormat format); + +VkCompareOp getCompareOp(SamplerCompareFunc func); +VkBlendFactor getBlendFactor(BlendFunction mode); +VkCullModeFlags getCullMode(CullingMode mode); +VkFrontFace getFrontFace(bool inverseFrontFaces); +PixelDataType getComponentType(VkFormat format); +uint32_t getComponentCount(VkFormat format); +VkComponentMapping getSwizzleMap(TextureSwizzle const swizzle[4]); +VkShaderStageFlags getShaderStageFlags(ShaderStageFlags stageFlags); + +inline VkImageViewType getViewType(SamplerType target) { + switch (target) { + case SamplerType::SAMPLER_CUBEMAP: + return VK_IMAGE_VIEW_TYPE_CUBE; + case SamplerType::SAMPLER_2D_ARRAY: + return VK_IMAGE_VIEW_TYPE_2D_ARRAY; + case SamplerType::SAMPLER_CUBEMAP_ARRAY: + return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; + case SamplerType::SAMPLER_3D: + return VK_IMAGE_VIEW_TYPE_3D; + default: + return VK_IMAGE_VIEW_TYPE_2D; + } +} + +}// namespace filament::backend::fvkutils + +#endif// TNT_FILAMENT_BACKEND_VULKAN_UTILS_CONVERSION_H diff --git a/filament/backend/src/vulkan/VulkanUtility.h b/filament/backend/src/vulkan/utils/Definitions.h similarity index 70% rename from filament/backend/src/vulkan/VulkanUtility.h rename to filament/backend/src/vulkan/utils/Definitions.h index 33be80d3fa..157eb4c40f 100644 --- a/filament/backend/src/vulkan/VulkanUtility.h +++ b/filament/backend/src/vulkan/utils/Definitions.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * -* Licensed under the Apache License, Version 2.0 (the "License"); + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * @@ -14,82 +14,17 @@ * limitations under the License. */ -#ifndef TNT_FILAMENT_BACKEND_VULKANUTILITY_H -#define TNT_FILAMENT_BACKEND_VULKANUTILITY_H - -#include +#ifndef TNT_FILAMENT_BACKEND_VULKAN_UTILS_DEFINITIONS_H +#define TNT_FILAMENT_BACKEND_VULKAN_UTILS_DEFINITIONS_H #include #include #include -#include +// Definitions for common types used across classes. -namespace filament::backend { - -VkFormat getVkFormat(ElementType type, bool normalized, bool integer); -VkFormat getVkFormat(TextureFormat format); -VkFormat getVkFormat(PixelDataFormat format, PixelDataType type); -VkFormat getVkFormatLinear(VkFormat format); -uint32_t getBytesPerPixel(TextureFormat format); -VkCompareOp getCompareOp(SamplerCompareFunc func); -VkBlendFactor getBlendFactor(BlendFunction mode); -VkCullModeFlags getCullMode(CullingMode mode); -VkFrontFace getFrontFace(bool inverseFrontFaces); -PixelDataType getComponentType(VkFormat format); -uint32_t getComponentCount(VkFormat format); -VkComponentMapping getSwizzleMap(TextureSwizzle const swizzle[4]); -VkShaderStageFlags getShaderStageFlags(ShaderStageFlags stageFlags); - -bool equivalent(const VkRect2D& a, const VkRect2D& b); -bool equivalent(const VkExtent2D& a, const VkExtent2D& b); -bool isVkDepthFormat(VkFormat format); -bool isVkStencilFormat(VkFormat format); - -VkImageAspectFlags getImageAspect(VkFormat format); -uint8_t reduceSampleCount(uint8_t sampleCount, VkSampleCountFlags mask); - -// Helper function for the vkEnumerateX methods. These methods have the format of -// VkResult vkEnumerateX(InputType1 arg1, InputTyp2 arg2, ..., uint32_t* size, -// OutputType* output_arg) -// Instead of macros and explicitly listing the template params, Variadic Template was also -// considered, but because the "variadic" part of the vk methods (i.e. the inputs) are before the -// non-variadic parts, this breaks the template type matching logic. Hence, we use a macro approach -// here. -#define EXPAND_ENUM(...) \ - uint32_t size = 0; \ - VkResult result = func(__VA_ARGS__, nullptr); \ - FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "enumerate size error"; \ - utils::FixedCapacityVector ret(size); \ - result = func(__VA_ARGS__, ret.data()); \ - FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "enumerate error"; \ - return std::move(ret); - -#define EXPAND_ENUM_NO_ARGS() EXPAND_ENUM(&size) -#define EXPAND_ENUM_ARGS(...) EXPAND_ENUM(__VA_ARGS__, &size) - -template -utils::FixedCapacityVector enumerate(VKAPI_ATTR VkResult (*func)(uint32_t*, OutType*)) { - EXPAND_ENUM_NO_ARGS(); -} - -template -utils::FixedCapacityVector enumerate( - VKAPI_ATTR VkResult (*func)(InType, uint32_t*, OutType*), InType inData) { - EXPAND_ENUM_ARGS(inData); -} - -template -utils::FixedCapacityVector enumerate( - VKAPI_ATTR VkResult (*func)(InTypeA, InTypeB, uint32_t*, OutType*), InTypeA inDataA, - InTypeB inDataB) { - EXPAND_ENUM_ARGS(inDataA, inDataB); -} - -#undef EXPAND_ENUM -#undef EXPAND_ENUM_NO_ARGS -#undef EXPAND_ENUM_ARGS +namespace filament::backend::fvkutils { // Useful shorthands using VkFormatList = utils::FixedCapacityVector; @@ -406,128 +341,6 @@ constexpr VkFormat ALL_VK_FORMATS[] = { VK_FORMAT_R16G16_S10_5_NV, }; -// An Array that will be statically fixed in capacity, but the "size" (as in user added elements) is -// variable. Note that this class is movable. -template -class CappedArray { -private: - using FixedSizeArray = std::array; - -public: - using const_iterator = typename FixedSizeArray::const_iterator; - using iterator = typename FixedSizeArray::iterator; - - CappedArray() = default; - - // Delete copy constructor/assignment. - CappedArray(CappedArray const& rhs) = delete; - CappedArray& operator=(CappedArray& rhs) = delete; - - CappedArray(CappedArray&& rhs) noexcept { - this->swap(rhs); - } - - CappedArray& operator=(CappedArray&& rhs) noexcept { - this->swap(rhs); - return *this; - } - - inline ~CappedArray() { - clear(); - } - - inline const_iterator begin() const { - if (mInd == 0) { - return mArray.cend(); - } - return mArray.cbegin(); - } - - inline const_iterator end() const { - if (mInd > 0 && mInd < CAPACITY) { - return mArray.begin() + mInd; - } - return mArray.cend(); - } - - inline iterator begin() { - if (mInd == 0) { - return mArray.end(); - } - return mArray.begin(); - } - - inline iterator end() { - if (mInd > 0 && mInd < CAPACITY) { - return mArray.begin() + mInd; - } - return mArray.end(); - } - - inline T back() { - assert_invariant(mInd > 0); - return *(mArray.begin() + mInd); - } - - inline void pop_back() { - assert_invariant(mInd > 0); - mInd--; - } - - inline const_iterator find(T item) { - return std::find(begin(), end(), item); - } - - inline void insert(T item) { - assert_invariant(mInd < CAPACITY); - mArray[mInd++] = item; - } - - inline void erase(T item) { - PANIC_PRECONDITION("CappedArray::erase should not be called"); - } - - inline void clear() { - if (mInd == 0) { - return; - } - mInd = 0; - } - - inline T& operator[](uint16_t ind) { - return mArray[ind]; - } - - inline T const& operator[](uint16_t ind) const { - return mArray[ind]; - } - - inline uint32_t size() const { - return mInd; - } - - T* data() { - return mArray.data(); - } - - T const* data() const { - return mArray.data(); - } - - bool operator==(CappedArray const& b) const { - return this->mArray == b.mArray; - } - -private: - void swap(CappedArray& rhs) { - std::swap(mArray, rhs.mArray); - std::swap(mInd, rhs.mInd); - } - - FixedSizeArray mArray; - uint32_t mInd = 0; -}; - using UniformBufferBitmask = utils::bitset64; using SamplerBitmask = utils::bitset64; @@ -550,7 +363,6 @@ static constexpr uint8_t getFragmentStageShift() noexcept { // We have at most 4 descriptor sets. This is to indicate which ones are active. using DescriptorSetMask = utils::bitset8; +} // namespace filament::backend::fvkutils -} // namespace filament::backend - -#endif // TNT_FILAMENT_BACKEND_VULKANUTILITY_H +#endif // TNT_FILAMENT_BACKEND_VULKAN_UTILS_DEFINITIONS_H diff --git a/filament/backend/src/vulkan/utils/Helper.h b/filament/backend/src/vulkan/utils/Helper.h new file mode 100644 index 0000000000..0ae3cf5a1c --- /dev/null +++ b/filament/backend/src/vulkan/utils/Helper.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * +* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TNT_FILAMENT_BACKEND_VULKAN_UTILS_HELPER_H +#define TNT_FILAMENT_BACKEND_VULKAN_UTILS_HELPER_H + +#include + +#include +#include + +#include + +#include + +namespace filament::backend::fvkutils { + +inline bool equivalent(const VkRect2D& a, const VkRect2D& b) { + // These are all integers so there's no need for an epsilon. + return a.extent.width == b.extent.width && a.extent.height == b.extent.height && + a.offset.x == b.offset.x && a.offset.y == b.offset.y; +} + +inline bool equivalent(const VkExtent2D& a, const VkExtent2D& b) { + return a.height == b.height && a.width == b.width; +} + +// Helper function for the vkEnumerateX methods. These methods have the format of +// VkResult vkEnumerateX(InputType1 arg1, InputTyp2 arg2, ..., uint32_t* size, +// OutputType* output_arg) +// Instead of macros and explicitly listing the template params, Variadic Template was also +// considered, but because the "variadic" part of the vk methods (i.e. the inputs) are before the +// non-variadic parts, this breaks the template type matching logic. Hence, we use a macro approach +// here. +#define EXPAND_ENUM(...) \ + uint32_t size = 0; \ + VkResult result = func(__VA_ARGS__, nullptr); \ + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "enumerate size error"; \ + utils::FixedCapacityVector ret(size); \ + result = func(__VA_ARGS__, ret.data()); \ + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "enumerate error"; \ + return std::move(ret); + +#define EXPAND_ENUM_NO_ARGS() EXPAND_ENUM(&size) +#define EXPAND_ENUM_ARGS(...) EXPAND_ENUM(__VA_ARGS__, &size) + +template +utils::FixedCapacityVector enumerate(VKAPI_ATTR VkResult (*func)(uint32_t*, OutType*)) { + EXPAND_ENUM_NO_ARGS(); +} + +template +utils::FixedCapacityVector enumerate( + VKAPI_ATTR VkResult (*func)(InType, uint32_t*, OutType*), InType inData) { + EXPAND_ENUM_ARGS(inData); +} + +template +utils::FixedCapacityVector enumerate( + VKAPI_ATTR VkResult (*func)(InTypeA, InTypeB, uint32_t*, OutType*), InTypeA inDataA, + InTypeB inDataB) { + EXPAND_ENUM_ARGS(inDataA, inDataB); +} + +#undef EXPAND_ENUM +#undef EXPAND_ENUM_NO_ARGS +#undef EXPAND_ENUM_ARGS + +} // namespace filament::backend::fvkutils + +#endif // TNT_FILAMENT_BACKEND_VULKAN_UTILS_HELPER_H diff --git a/filament/backend/src/vulkan/VulkanImageUtility.cpp b/filament/backend/src/vulkan/utils/Image.cpp similarity index 87% rename from filament/backend/src/vulkan/VulkanImageUtility.cpp rename to filament/backend/src/vulkan/utils/Image.cpp index 415eb305ca..fb160fc4b0 100644 --- a/filament/backend/src/vulkan/VulkanImageUtility.cpp +++ b/filament/backend/src/vulkan/utils/Image.cpp @@ -14,9 +14,9 @@ * limitations under the License. */ -#include "VulkanImageUtility.h" +#include "vulkan/utils/Image.h" -#include "VulkanTexture.h" +#include "vulkan/VulkanTexture.h" #include #include @@ -26,7 +26,7 @@ using namespace bluevk; -namespace filament::backend::imgutil { +namespace filament::backend::fvkutils { namespace { @@ -159,7 +159,41 @@ bool transitionLayout(VkCommandBuffer cmdbuffer, return true; } -}// namespace filament::backend +VkImageAspectFlags getImageAspect(VkFormat format) { + switch (format) { + case VK_FORMAT_D16_UNORM_S8_UINT: + case VK_FORMAT_D24_UNORM_S8_UINT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: + return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + case VK_FORMAT_D16_UNORM: + case VK_FORMAT_X8_D24_UNORM_PACK32: + case VK_FORMAT_D32_SFLOAT: + return VK_IMAGE_ASPECT_DEPTH_BIT; + case VK_FORMAT_S8_UINT: + return VK_IMAGE_ASPECT_STENCIL_BIT; + default: + return VK_IMAGE_ASPECT_COLOR_BIT; + } +} + +bool isVkDepthFormat(VkFormat format) { + return (getImageAspect(format) & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; +} + +bool isVkStencilFormat(VkFormat format) { + return (getImageAspect(format) & VK_IMAGE_ASPECT_STENCIL_BIT) != 0; +} + +static uint32_t mostSignificantBit(uint32_t x) { return 1ul << (31ul - utils::clz(x)); } + +uint8_t reduceSampleCount(uint8_t sampleCount, VkSampleCountFlags mask) { + if (sampleCount & mask) { + return sampleCount; + } + return mostSignificantBit((sampleCount - 1) & mask); +} + +} // namespace filament::backend::fvkutils bool operator<(const VkImageSubresourceRange& a, const VkImageSubresourceRange& b) { if (a.aspectMask < b.aspectMask) return true; diff --git a/filament/backend/src/vulkan/VulkanImageUtility.h b/filament/backend/src/vulkan/utils/Image.h similarity index 84% rename from filament/backend/src/vulkan/VulkanImageUtility.h rename to filament/backend/src/vulkan/utils/Image.h index f8027d9697..fcd57ee331 100644 --- a/filament/backend/src/vulkan/VulkanImageUtility.h +++ b/filament/backend/src/vulkan/utils/Image.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef TNT_FILAMENT_BACKEND_VULKANIMAGEUTILITY_H -#define TNT_FILAMENT_BACKEND_VULKANIMAGEUTILITY_H +#ifndef TNT_FILAMENT_BACKEND_VULKAN_UTILS_IMAGE_H +#define TNT_FILAMENT_BACKEND_VULKAN_UTILS_IMAGE_H #include @@ -59,22 +59,7 @@ struct VulkanLayoutTransition { VkImageSubresourceRange subresources; }; -namespace imgutil { - -inline VkImageViewType getViewType(SamplerType target) { - switch (target) { - case SamplerType::SAMPLER_CUBEMAP: - return VK_IMAGE_VIEW_TYPE_CUBE; - case SamplerType::SAMPLER_2D_ARRAY: - return VK_IMAGE_VIEW_TYPE_2D_ARRAY; - case SamplerType::SAMPLER_CUBEMAP_ARRAY: - return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; - case SamplerType::SAMPLER_3D: - return VK_IMAGE_VIEW_TYPE_3D; - default: - return VK_IMAGE_VIEW_TYPE_2D; - } -} +namespace fvkutils { constexpr inline VkImageLayout getVkLayout(VulkanLayout layout) { switch (layout) { @@ -109,7 +94,15 @@ constexpr inline VkImageLayout getVkLayout(VulkanLayout layout) { // no transition necessary). bool transitionLayout(VkCommandBuffer cmdbuffer, VulkanLayoutTransition transition); -} // namespace imgutil +bool isVkDepthFormat(VkFormat format); + +bool isVkStencilFormat(VkFormat format); + +VkImageAspectFlags getImageAspect(VkFormat format); + +uint8_t reduceSampleCount(uint8_t sampleCount, VkSampleCountFlags mask); + +} // namespace fvkutils } // namespace filament::backend @@ -117,5 +110,4 @@ bool operator<(const VkImageSubresourceRange& a, const VkImageSubresourceRange& utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::VulkanLayout& layout); - -#endif // TNT_FILAMENT_BACKEND_VULKANIMAGEUTILITY_H +#endif // TNT_FILAMENT_BACKEND_VULKAN_UTILS_IMAGE_H diff --git a/filament/backend/src/vulkan/spirv/VulkanSpirvUtils.cpp b/filament/backend/src/vulkan/utils/Spirv.cpp similarity index 72% rename from filament/backend/src/vulkan/spirv/VulkanSpirvUtils.cpp rename to filament/backend/src/vulkan/utils/Spirv.cpp index 209745facd..a1c5933dd0 100644 --- a/filament/backend/src/vulkan/spirv/VulkanSpirvUtils.cpp +++ b/filament/backend/src/vulkan/utils/Spirv.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "VulkanSpirvUtils.h" +#include "vulkan/utils/Spirv.h" #include // UTILS_UNUSED_IN_RELEASE, UTILS_FALLTHROUGH #include // assert_invariant @@ -22,12 +22,11 @@ #include -#include -#include -#include #include +#include +#include -namespace filament::backend { +namespace filament::backend::fvkutils { namespace { @@ -99,7 +98,7 @@ void workaroundSpecConstant(Program::ShaderBlob const& blob, uint32_t const* data = (uint32_t*) blob.data(); uint32_t* outputData = output.data(); - std::memcpy(&outputData[0], &data[0], HEADER_SIZE * 4); + memcpy(&outputData[0], &data[0], HEADER_SIZE * 4); size_t outputCursor = HEADER_SIZE; for (uint32_t cursor = HEADER_SIZE, cursorEnd = dataSize; cursor < cursorEnd;) { @@ -147,61 +146,4 @@ void workaroundSpecConstant(Program::ShaderBlob const& blob, output.resize(outputCursor); } -std::tuple getProgramBindings(Program::ShaderBlob const& blob) { - std::unordered_map targetToSet, targetToBinding; - - constexpr size_t HEADER_SIZE = 5; - - size_t const dataSize = blob.size() / 4; - uint32_t const* data = (uint32_t*) blob.data(); - - for (uint32_t cursor = HEADER_SIZE, cursorEnd = dataSize; cursor < cursorEnd;) { - uint32_t const firstWord = data[cursor]; - uint32_t const wordCount = firstWord >> 16; - uint32_t const op = firstWord & 0x0000FFFF; - - switch(op) { - case spv::Op::OpDecorate: { - if (data[cursor + 2] == spv::Decoration::DecorationDescriptorSet) { - uint32_t const targetVar = data[cursor + 1]; - uint32_t const setId = data[cursor + 3]; - targetToSet[targetVar] = setId; - } else if (data[cursor + 2] == spv::Decoration::DecorationBinding) { - uint32_t const targetVar = data[cursor + 1]; - uint32_t const binding = data[cursor + 3]; - targetToBinding[targetVar] = binding; - } - break; - } - default: - break; - } - cursor += wordCount; - } - - constexpr uint32_t UBO = 0; - constexpr uint32_t SAMPLER = 1; - constexpr uint32_t IATTACHMENT = 2; - uint32_t ubo = 0, sampler = 0, inputAttachment = 0; - - for (auto const& [target, setId]: targetToSet) { - uint32_t const binding = targetToBinding[target]; - assert_invariant(binding < 32); - switch(setId) { - case UBO: - ubo |= (1 << binding); - break; - case SAMPLER: - sampler |= (1 << binding); - break; - case IATTACHMENT: - inputAttachment |= (1 << binding); - break; - default: - PANIC_POSTCONDITION("unexpected %d", (int) setId); - } - } - return {ubo, sampler, inputAttachment}; -} - -} // namespace filament::backend +} // namespace filament::backend::fvkutils diff --git a/filament/backend/src/vulkan/spirv/VulkanSpirvUtils.h b/filament/backend/src/vulkan/utils/Spirv.h similarity index 77% rename from filament/backend/src/vulkan/spirv/VulkanSpirvUtils.h rename to filament/backend/src/vulkan/utils/Spirv.h index 2a9f79a611..941c30a32d 100644 --- a/filament/backend/src/vulkan/spirv/VulkanSpirvUtils.h +++ b/filament/backend/src/vulkan/utils/Spirv.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef TNT_FILAMENT_BACKEND_VULKANSPIRVUTILS_H -#define TNT_FILAMENT_BACKEND_VULKANSPIRVUTILS_H +#ifndef TNT_FILAMENT_BACKEND_VULKAN_UTILS_SPIRV_H +#define TNT_FILAMENT_BACKEND_VULKAN_UTILS_SPIRV_H #include @@ -24,7 +24,7 @@ #include #include -namespace filament::backend { +namespace filament::backend::fvkutils { using SpecConstantValue = Program::SpecializationConstant::Type; @@ -44,8 +44,9 @@ void workaroundSpecConstant(Program::ShaderBlob const& blob, std::vector& output); // bindings for UBO, samplers, input attachment -std::tuple getProgramBindings(Program::ShaderBlob const& blob); +// This is no longer needed after the descriptor set refactor, but the code is good for reference. +// std::tuple getProgramBindings(Program::ShaderBlob const& blob); -} // namespace filament::backend +} // namespace filament::backend::fvkutils -#endif // TNT_FILAMENT_BACKEND_VULKANSPIRVUTILS_H +#endif // TNT_FILAMENT_BACKEND_VULKAN_UTILS_SPIRV_H diff --git a/filament/backend/src/vulkan/utils/StaticVector.h b/filament/backend/src/vulkan/utils/StaticVector.h new file mode 100644 index 0000000000..b9abf8f9f2 --- /dev/null +++ b/filament/backend/src/vulkan/utils/StaticVector.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * +* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TNT_FILAMENT_BACKEND_VULKAN_UTILS_STATICVECTOR_H +#define TNT_FILAMENT_BACKEND_VULKAN_UTILS_STATICVECTOR_H + +// An Array that will be statically fixed in capacity, but the "size" (as in user added elements) is +// variable. Note that this class is movable. + +#include + +#include + +namespace filament::backend::fvkutils { + +template +class StaticVector { +private: + using FixedSizeArray = std::array; + + static_assert(CAPACITY <= (1LL << (8 * sizeof(uint16_t)))); + +public: + using const_iterator = typename FixedSizeArray::const_iterator; + using iterator = typename FixedSizeArray::iterator; + + StaticVector() = default; + + // Delete copy constructor/assignment. + StaticVector(StaticVector const& rhs) = delete; + StaticVector& operator=(StaticVector& rhs) = delete; + + StaticVector(StaticVector&& rhs) noexcept { + std::swap(mSize, rhs.mSize); + std::swap(mArray, rhs.mArray); + } + + StaticVector& operator=(StaticVector&& rhs) noexcept { + std::swap(mSize, rhs.mSize); + std::swap(mArray, rhs.mArray); + return *this; + } + + inline ~StaticVector() { + clear(); + } + + inline const_iterator begin() const { + return mArray.cbegin(); + } + + inline const_iterator end() const { + assert_invariant(mSize <= CAPACITY); + return mArray.begin() + mSize; + } + + inline iterator begin() { + return mArray.begin(); + } + + inline iterator end() { + assert_invariant(mSize <= CAPACITY); + return mArray.begin() + mSize; + } + + inline T back() { + assert_invariant(mSize > 0); + return *(mArray.begin() + mSize); + } + + inline void pop_back() { + assert_invariant(mSize > 0); + mSize--; + } + + inline const_iterator find(T item) { + return std::find(begin(), end(), item); + } + + inline void push_back(T item) { + assert_invariant(mSize < CAPACITY); + mArray[mSize++] = item; + } + + inline void clear() { + mSize = 0; + } + + inline T& operator[](size_t index) { + assert_invariant(index < mSize); + return mArray[index]; + } + + inline T const& operator[](size_t index) const { + return mArray[index]; + } + + inline uint16_t size() const { + return mSize; + } + + T* data() { + return mArray.data(); + } + + T const* data() const { + return mArray.data(); + } + + bool operator==(StaticVector const& b) const { + return this->mArray == b.mArray && this->mSize == b.mSize; + } + +private: + FixedSizeArray mArray; + uint16_t mSize = 0; +}; + +} // namespace filament::backend::fvkutils + +#endif // TNT_FILAMENT_BACKEND_VULKAN_UTILS_STATICVECTOR_H