From 076e2f20ce80ef9ea6ccb351c2bfdc3b99ac8015 Mon Sep 17 00:00:00 2001 From: assiduous Date: Fri, 30 Oct 2020 14:18:45 -0700 Subject: A number of minor updates --- .../include/DescriptorPoolManager.hpp | 6 +- .../src/CommandPoolManager.cpp | 2 +- .../src/DescriptorPoolManager.cpp | 35 ++-- .../src/DeviceContextVkImpl.cpp | 201 +++++++++++---------- .../src/PipelineStateVkImpl.cpp | 4 +- .../GraphicsEngineVulkan/src/SwapChainVkImpl.cpp | 24 +-- .../src/VulkanTypeConversions.cpp | 13 +- 7 files changed, 148 insertions(+), 137 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.hpp b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.hpp index 41a8cac3..b60f3d89 100644 --- a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.hpp +++ b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.hpp @@ -165,9 +165,9 @@ protected: RenderDeviceVkImpl& m_DeviceVkImpl; const std::string m_PoolName; - std::vector m_PoolSizes; - const uint32_t m_MaxSets; - const bool m_AllowFreeing; + const std::vector m_PoolSizes; + const uint32_t m_MaxSets; + const bool m_AllowFreeing; std::mutex m_Mutex; std::deque m_Pools; diff --git a/Graphics/GraphicsEngineVulkan/src/CommandPoolManager.cpp b/Graphics/GraphicsEngineVulkan/src/CommandPoolManager.cpp index 6d0e1ab2..cf24d9ea 100644 --- a/Graphics/GraphicsEngineVulkan/src/CommandPoolManager.cpp +++ b/Graphics/GraphicsEngineVulkan/src/CommandPoolManager.cpp @@ -53,7 +53,7 @@ VulkanUtilities::CommandPoolWrapper CommandPoolManager::AllocateCommandPool(cons { std::lock_guard LockGuard{m_Mutex}; - auto& LogicalDevice = m_DeviceVkImpl.GetLogicalDevice(); + const auto& LogicalDevice = m_DeviceVkImpl.GetLogicalDevice(); VulkanUtilities::CommandPoolWrapper CmdPool; if (!m_CmdPools.empty()) diff --git a/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp b/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp index 6557ac6d..45045cea 100644 --- a/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp @@ -59,28 +59,16 @@ VulkanUtilities::DescriptorPoolWrapper DescriptorPoolManager::CreateDescriptorPo return m_DeviceVkImpl.GetLogicalDevice().CreateDescriptorPool(PoolCI, DebugName); } -DescriptorPoolManager::DescriptorPoolManager(RenderDeviceVkImpl& DeviceVkImpl, - std::string PoolName, - std::vector PoolSizes, - uint32_t MaxSets, - bool AllowFreeing) noexcept : - // clang-format off - m_DeviceVkImpl{DeviceVkImpl }, - m_PoolName {std::move(PoolName) }, - m_PoolSizes (std::move(PoolSizes)), - m_MaxSets {MaxSets }, - m_AllowFreeing{AllowFreeing } -// clang-format on +static std::vector PrunePoolSizes(RenderDeviceVkImpl& DeviceVkImpl, std::vector&& PoolSizes) { - const auto& Feats = m_DeviceVkImpl.GetLogicalDevice().GetEnabledExtFeatures(); - - for (auto iter = m_PoolSizes.begin(); iter != m_PoolSizes.end();) + const auto& Feats = DeviceVkImpl.GetLogicalDevice().GetEnabledExtFeatures(); + for (auto iter = PoolSizes.begin(); iter != PoolSizes.end();) { switch (iter->type) { case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: if (Feats.RayTracing.rayTracing == VK_FALSE) - iter = m_PoolSizes.erase(iter); + iter = PoolSizes.erase(iter); else ++iter; break; @@ -88,7 +76,22 @@ DescriptorPoolManager::DescriptorPoolManager(RenderDeviceVkImpl& D ++iter; } } + return PoolSizes; +} +DescriptorPoolManager::DescriptorPoolManager(RenderDeviceVkImpl& DeviceVkImpl, + std::string PoolName, + std::vector PoolSizes, + uint32_t MaxSets, + bool AllowFreeing) noexcept : + // clang-format off + m_DeviceVkImpl{DeviceVkImpl }, + m_PoolName {std::move(PoolName) }, + m_PoolSizes (PrunePoolSizes(DeviceVkImpl, std::move(PoolSizes))), + m_MaxSets {MaxSets }, + m_AllowFreeing{AllowFreeing } +// clang-format on +{ #ifdef DILIGENT_DEVELOPMENT m_AllocatedPoolCounter = 0; #endif diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 554352ad..69a3a1ba 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -2704,8 +2704,7 @@ void DeviceContextVkImpl::TransitionResourceStates(Uint32 BarrierCount, StateTra } VERIFY(Barrier.TransitionType == STATE_TRANSITION_TYPE_IMMEDIATE || Barrier.TransitionType == STATE_TRANSITION_TYPE_END, "Unexpected barrier type"); - RefCntAutoPtr pTexture{Barrier.pResource, IID_TextureVk}; - if (pTexture) + if (RefCntAutoPtr pTexture{Barrier.pResource, IID_TextureVk}) { VkImageSubresourceRange SubResRange; SubResRange.aspectMask = 0; @@ -2714,17 +2713,23 @@ void DeviceContextVkImpl::TransitionResourceStates(Uint32 BarrierCount, StateTra SubResRange.baseArrayLayer = Barrier.FirstArraySlice; SubResRange.layerCount = (Barrier.ArraySliceCount == REMAINING_ARRAY_SLICES) ? VK_REMAINING_ARRAY_LAYERS : Barrier.ArraySliceCount; TransitionTextureState(*pTexture, Barrier.OldState, Barrier.NewState, Barrier.UpdateResourceState, &SubResRange); - continue; } - - RefCntAutoPtr pBuffer{Barrier.pResource, IID_BufferVk}; - if (pBuffer) + else if (RefCntAutoPtr pBuffer{Barrier.pResource, IID_BufferVk}) { TransitionBufferState(*pBuffer, Barrier.OldState, Barrier.NewState, Barrier.UpdateResourceState); - continue; } - - UNEXPECTED("unsupported resource type"); + else if (RefCntAutoPtr pBLAS{Barrier.pResource, IID_BottomLevelAS}) + { + TransitionBLASState(*pBLAS, Barrier.OldState, Barrier.NewState, Barrier.UpdateResourceState); + } + else if (RefCntAutoPtr pTLAS{Barrier.pResource, IID_TopLevelAS}) + { + TransitionTLASState(*pTLAS, Barrier.OldState, Barrier.NewState, Barrier.UpdateResourceState); + } + else + { + UNEXPECTED("unsupported resource type"); + } } } @@ -2816,61 +2821,61 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs) for (Uint32 i = 0; i < Attribs.TriangleDataCount; ++i) { - auto& src = Attribs.pTriangleData[i]; - Uint32 j = pBLASVk->GetGeometryIndex(src.GeometryName); - auto& dst = Geometries.data()[j]; - auto& tri = dst.geometry.triangles; - auto& off = Offsets.data()[j]; + const auto& SrcTris = Attribs.pTriangleData[i]; + Uint32 GeoIdx = pBLASVk->GetGeometryIndex(SrcTris.GeometryName); + auto& vkGeo = Geometries[GeoIdx]; + auto& vkTris = vkGeo.geometry.triangles; + auto& off = Offsets[GeoIdx]; - if (j >= Geometries.size()) + if (GeoIdx >= Geometries.size()) { UNEXPECTED("Failed to find geometry by name"); continue; } - dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; - dst.pNext = nullptr; - dst.flags = GeometryFlagsToVkGeometryFlags(src.Flags); - dst.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; - tri.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR; - tri.pNext = nullptr; + vkGeo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; + vkGeo.pNext = nullptr; + vkGeo.flags = GeometryFlagsToVkGeometryFlags(SrcTris.Flags); + vkGeo.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; + vkTris.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR; + vkTris.pNext = nullptr; - auto* pVB = ValidatedCast(src.pVertexBuffer); - tri.vertexFormat = TypeToVkFormat(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16); - tri.vertexStride = src.VertexStride; - tri.vertexData.deviceAddress = pVB->GetVkDeviceAddress() + src.VertexOffset; + auto* const pVB = ValidatedCast(SrcTris.pVertexBuffer); + vkTris.vertexFormat = TypeToVkFormat(SrcTris.VertexValueType, SrcTris.VertexComponentCount, SrcTris.VertexValueType < VT_FLOAT16); + vkTris.vertexStride = SrcTris.VertexStride; + vkTris.vertexData.deviceAddress = pVB->GetVkDeviceAddress() + SrcTris.VertexOffset; - TransitionOrVerifyBufferState(*pVB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VkAccessFlagBits(0), OpName); + TransitionOrVerifyBufferState(*pVB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, static_cast(0), OpName); - if (src.pIndexBuffer) + if (SrcTris.pIndexBuffer) { - auto* pIB = ValidatedCast(src.pIndexBuffer); - tri.indexType = TypeToVkIndexType(src.IndexType); - tri.indexData.deviceAddress = pIB->GetVkDeviceAddress() + src.IndexOffset; - off.primitiveCount = src.IndexCount / 3; + auto* const pIB = ValidatedCast(SrcTris.pIndexBuffer); + vkTris.indexType = TypeToVkIndexType(SrcTris.IndexType); + vkTris.indexData.deviceAddress = pIB->GetVkDeviceAddress() + SrcTris.IndexOffset; + off.primitiveCount = SrcTris.IndexCount / 3; - TransitionOrVerifyBufferState(*pIB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VkAccessFlagBits(0), OpName); + TransitionOrVerifyBufferState(*pIB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, static_cast(0), OpName); } else { - tri.indexType = VK_INDEX_TYPE_NONE_KHR; - tri.indexData.deviceAddress = 0; - off.primitiveCount = src.VertexCount / 3; + vkTris.indexType = VK_INDEX_TYPE_NONE_KHR; + vkTris.indexData.deviceAddress = 0; + off.primitiveCount = SrcTris.VertexCount / 3; } - if (src.pTransformBuffer) + if (SrcTris.pTransformBuffer) { - VERIFY_EXPR(BLASDesc.pTriangles[j].AllowsTransforms); + VERIFY_EXPR(BLASDesc.pTriangles[GeoIdx].AllowsTransforms); - auto* pTB = ValidatedCast(src.pTransformBuffer); - tri.transformData.deviceAddress = pTB->GetVkDeviceAddress() + src.TransformBufferOffset; + auto* const pTB = ValidatedCast(SrcTris.pTransformBuffer); + vkTris.transformData.deviceAddress = pTB->GetVkDeviceAddress() + SrcTris.TransformBufferOffset; TransitionOrVerifyBufferState(*pTB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VkAccessFlagBits(0), OpName); } else { - VERIFY_EXPR(!BLASDesc.pTriangles[j].AllowsTransforms); - tri.transformData.deviceAddress = 0; + VERIFY_EXPR(!BLASDesc.pTriangles[GeoIdx].AllowsTransforms); + vkTris.transformData.deviceAddress = 0; } off.firstVertex = 0; @@ -2885,35 +2890,35 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs) for (Uint32 i = 0; i < Attribs.BoxDataCount; ++i) { - auto& src = Attribs.pBoxData[i]; - Uint32 j = pBLASVk->GetGeometryIndex(src.GeometryName); - auto& dst = Geometries.data()[j]; - auto& box = dst.geometry.aabbs; - auto& off = Offsets.data()[j]; + const auto& SrcBoxes = Attribs.pBoxData[i]; + Uint32 GeoIdx = pBLASVk->GetGeometryIndex(SrcBoxes.GeometryName); + auto& vkGeo = Geometries[GeoIdx]; + auto& vkAABBs = vkGeo.geometry.aabbs; + auto& off = Offsets[GeoIdx]; - if (j >= Geometries.size()) + if (GeoIdx >= Geometries.size()) { UNEXPECTED("Failed to find geometry by name"); continue; } - dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; - dst.pNext = nullptr; - dst.flags = GeometryFlagsToVkGeometryFlags(src.Flags); - dst.geometryType = VK_GEOMETRY_TYPE_AABBS_KHR; + vkGeo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; + vkGeo.pNext = nullptr; + vkGeo.flags = GeometryFlagsToVkGeometryFlags(SrcBoxes.Flags); + vkGeo.geometryType = VK_GEOMETRY_TYPE_AABBS_KHR; - auto* pBB = ValidatedCast(src.pBoxBuffer); - box.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR; - box.pNext = nullptr; - box.stride = src.BoxStride; - box.data.deviceAddress = pBB->GetVkDeviceAddress() + src.BoxOffset; + auto* const pBB = ValidatedCast(SrcBoxes.pBoxBuffer); + vkAABBs.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR; + vkAABBs.pNext = nullptr; + vkAABBs.stride = SrcBoxes.BoxStride; + vkAABBs.data.deviceAddress = pBB->GetVkDeviceAddress() + SrcBoxes.BoxOffset; TransitionOrVerifyBufferState(*pBB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VkAccessFlagBits(0), OpName); off.firstVertex = 0; off.transformOffset = 0; off.primitiveOffset = 0; - off.primitiveCount = src.BoxCount; + off.primitiveCount = SrcBoxes.BoxCount; } } @@ -2971,18 +2976,18 @@ void DeviceContextVkImpl::BuildTLAS(const TLASBuildAttribs& Attribs) for (Uint32 i = 0; i < Attribs.InstanceCount; ++i) { - auto& src = Attribs.pInstances[i]; - auto& dst = static_cast(pMappedInstances)[i]; - auto* pBLASVk = ValidatedCast(src.pBLAS); + const auto& Inst = Attribs.pInstances[i]; + auto& vkASInst = static_cast(pMappedInstances)[i]; + auto* const pBLASVk = ValidatedCast(Inst.pBLAS); - static_assert(sizeof(dst.transform) == sizeof(src.Transform), "size mismatch"); - std::memcpy(&dst.transform, src.Transform, sizeof(dst.transform)); + static_assert(sizeof(vkASInst.transform) == sizeof(Inst.Transform), "size mismatch"); + std::memcpy(&vkASInst.transform, Inst.Transform, sizeof(vkASInst.transform)); - dst.instanceCustomIndex = src.CustomId; - dst.instanceShaderBindingTableRecordOffset = pTLASVk->GetInstanceDesc(src.InstanceName).ContributionToHitGroupIndex; // AZ TODO: optimize - dst.mask = src.Mask; - dst.flags = InstanceFlagsToVkGeometryInstanceFlags(src.Flags); - dst.accelerationStructureReference = pBLASVk->GetVkDeviceAddress(); + vkASInst.instanceCustomIndex = Inst.CustomId; + vkASInst.instanceShaderBindingTableRecordOffset = pTLASVk->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex; // AZ TODO: optimize + vkASInst.mask = Inst.Mask; + vkASInst.flags = InstanceFlagsToVkGeometryInstanceFlags(Inst.Flags); + vkASInst.accelerationStructureReference = pBLASVk->GetVkDeviceAddress(); TransitionOrVerifyBLASState(*pBLASVk, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } @@ -2991,37 +2996,37 @@ void DeviceContextVkImpl::BuildTLAS(const TLASBuildAttribs& Attribs) } TransitionOrVerifyBufferState(*pInstancesVk, Attribs.InstanceBufferTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VkAccessFlagBits(0), OpName); - VkAccelerationStructureBuildGeometryInfoKHR Info = {}; - VkAccelerationStructureBuildOffsetInfoKHR Offset = {}; - VkAccelerationStructureBuildOffsetInfoKHR const* OffsetsPtr = &Offset; - VkAccelerationStructureGeometryKHR Geometry = {}; - VkAccelerationStructureGeometryKHR const* GeometriesPtr = &Geometry; - - Offset.primitiveCount = Attribs.InstanceCount; - - Geometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; - Geometry.pNext = nullptr; - Geometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR; - Geometry.flags = 0; - - auto& inst = Geometry.geometry.instances; - inst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR; - inst.pNext = nullptr; - inst.arrayOfPointers = VK_FALSE; - inst.data.deviceAddress = pInstancesVk->GetVkDeviceAddress() + Attribs.InstanceBufferOffset; - - Info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR; - Info.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; // type must be compatible with create info - Info.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(TLASDesc.Flags); // flags must be compatible with create info - Info.update = VK_FALSE; - Info.srcAccelerationStructure = VK_NULL_HANDLE; - Info.dstAccelerationStructure = pTLASVk->GetVkTLAS(); - Info.geometryArrayOfPointers = VK_FALSE; - Info.geometryCount = 1; - Info.ppGeometries = &GeometriesPtr; - Info.scratchData.deviceAddress = pScratchVk->GetVkDeviceAddress() + Attribs.ScratchBufferOffset; - - m_CommandBuffer.BuildAccelerationStructure(1, &Info, &OffsetsPtr); + VkAccelerationStructureBuildGeometryInfoKHR vkASBuildInfo = {}; + VkAccelerationStructureBuildOffsetInfoKHR vkASBuildOffset = {}; + VkAccelerationStructureBuildOffsetInfoKHR const* vkASBuildOffsetPtr = &vkASBuildOffset; + VkAccelerationStructureGeometryKHR vkASGeometry = {}; + VkAccelerationStructureGeometryKHR const* vkASGeometriesPtr = &vkASGeometry; + + vkASBuildOffset.primitiveCount = Attribs.InstanceCount; + + vkASGeometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; + vkASGeometry.pNext = nullptr; + vkASGeometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR; + vkASGeometry.flags = 0; + + auto& vkASInst = vkASGeometry.geometry.instances; + vkASInst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR; + vkASInst.pNext = nullptr; + vkASInst.arrayOfPointers = VK_FALSE; + vkASInst.data.deviceAddress = pInstancesVk->GetVkDeviceAddress() + Attribs.InstanceBufferOffset; + + vkASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR; + vkASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; // type must be compatible with create info + vkASBuildInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(TLASDesc.Flags); // flags must be compatible with create info + vkASBuildInfo.update = VK_FALSE; + vkASBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE; + vkASBuildInfo.dstAccelerationStructure = pTLASVk->GetVkTLAS(); + vkASBuildInfo.geometryArrayOfPointers = VK_FALSE; + vkASBuildInfo.geometryCount = 1; + vkASBuildInfo.ppGeometries = &vkASGeometriesPtr; + vkASBuildInfo.scratchData.deviceAddress = pScratchVk->GetVkDeviceAddress() + Attribs.ScratchBufferOffset; + + m_CommandBuffer.BuildAccelerationStructure(1, &vkASBuildInfo, &vkASBuildOffsetPtr); ++m_State.NumCommands; } diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 548a9cf3..36ca3a42 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -392,8 +392,8 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& Uint32 GroupIndex = 0; - std::array ShaderIndices = {}; - std::unordered_map UniqueShaders; + std::array ShaderIndices = {}; + std::unordered_map UniqueShaders; const auto ShaderToIndex = [&ShaderIndices, &UniqueShaders](const IShader* pShader) -> Uint32 { if (pShader != nullptr) diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp index 27be99fc..d32f9788 100644 --- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp @@ -425,20 +425,22 @@ void SwapChainVkImpl::CreateVulkanSwapChain() DEV_CHECK_ERR(m_SwapChainDesc.Usage != 0, "No swap chain usage flags defined"); static_assert(SWAP_CHAIN_USAGE_LAST == SWAP_CHAIN_USAGE_UNORDERED_ACCESS, "Please update this function to handle the new swapchain usage"); - for (Uint32 UsageBit = 1; UsageBit <= m_SwapChainDesc.Usage; UsageBit <<= 1) { - if ((m_SwapChainDesc.Usage & UsageBit) == 0) - continue; - - switch (static_cast(UsageBit)) + auto SCUsage = m_SwapChainDesc.Usage; + while (SCUsage != SWAP_CHAIN_USAGE_NONE) { - // clang-format off - case SWAP_CHAIN_USAGE_RENDER_TARGET: swapchain_ci.imageUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; break; - case SWAP_CHAIN_USAGE_SHADER_INPUT: swapchain_ci.imageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT; break; - case SWAP_CHAIN_USAGE_COPY_SOURCE: swapchain_ci.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; break; - case SWAP_CHAIN_USAGE_UNORDERED_ACCESS: swapchain_ci.imageUsage |= VK_IMAGE_USAGE_STORAGE_BIT; break; - default: UNEXPECTED("unknown swapchain usage flag"); + auto UsageBit = static_cast(1 << PlatformMisc::GetLSB(Uint32{SCUsage})); + switch (UsageBit) + { + // clang-format off + case SWAP_CHAIN_USAGE_RENDER_TARGET: swapchain_ci.imageUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; break; + case SWAP_CHAIN_USAGE_SHADER_INPUT: swapchain_ci.imageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT; break; + case SWAP_CHAIN_USAGE_COPY_SOURCE: swapchain_ci.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; break; + case SWAP_CHAIN_USAGE_UNORDERED_ACCESS: swapchain_ci.imageUsage |= VK_IMAGE_USAGE_STORAGE_BIT; break; // clang-format on + default: UNEXPECTED("unknown swapchain usage flag"); + } + SCUsage &= ~UsageBit; } } diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp index 40882b09..143042b8 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp @@ -1187,17 +1187,18 @@ static VkPipelineStageFlags ResourceStateFlagToVkPipelineStage(RESOURCE_STATE St } } -VkPipelineStageFlags ResourceStateFlagsToVkPipelineStageFlags(RESOURCE_STATE StateFlags, VkPipelineStageFlags ShaderStages) +VkPipelineStageFlags ResourceStateFlagsToVkPipelineStageFlags(RESOURCE_STATE StateFlags, VkPipelineStageFlags vkShaderStages) { VERIFY(Uint32{StateFlags} < (RESOURCE_STATE_MAX_BIT << 1), "Resource state flags are out of range"); - VkPipelineStageFlags Stages = 0; - for (Uint32 Bit = 1; Bit <= StateFlags; Bit <<= 1) + VkPipelineStageFlags vkPipelineStages = 0; + while (StateFlags != RESOURCE_STATE_UNKNOWN) { - if (StateFlags & Bit) - Stages |= ResourceStateFlagToVkPipelineStage(static_cast(Bit), ShaderStages); + auto StateBit = static_cast(1 << PlatformMisc::GetLSB(Uint32{StateFlags})); + vkPipelineStages |= ResourceStateFlagToVkPipelineStage(StateBit, vkShaderStages); + StateFlags &= ~StateBit; } - return Stages; + return vkPipelineStages; } -- cgit v1.2.3