summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-11-18 21:07:09 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-11-18 21:07:09 +0000
commita55206ac29c47ca2765040a7339468f7b6a530c7 (patch)
tree85ab32d391623c16bee8e19ad1cbb4f722f2f8d8 /Graphics/GraphicsEngineVulkan
parentUpdated comment (diff)
downloadDiligentCore-a55206ac29c47ca2765040a7339468f7b6a530c7.tar.gz
DiligentCore-a55206ac29c47ca2765040a7339468f7b6a530c7.zip
Added explicit resource state transitions to the API; implemented in D3D12
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h1
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h6
-rw-r--r--Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h1
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h3
-rw-r--r--Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h44
-rw-r--r--Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp5
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp12
-rw-r--r--Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp3
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp123
12 files changed, 176 insertions, 28 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h b/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h
index 397a4198..da856b3c 100644
--- a/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h
@@ -59,6 +59,7 @@ public:
FixedBlockMemoryAllocator& BuffViewObjMemAllocator,
class RenderDeviceVkImpl* pDeviceVk,
const BufferDesc& BuffDesc,
+ RESOURCE_STATE InitialState,
VkBuffer vkBuffer);
~BufferVkImpl();
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
index eff4aff2..9ba4ca8f 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
@@ -161,6 +161,8 @@ public:
virtual void FinishFrame()override final;
+ virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers)override final;
+
VkDescriptorSet AllocateDynamicDescriptorSet(VkDescriptorSetLayout SetLayout)
{
// Descriptor pools are externally synchronized, meaning that the application must not allocate
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
index 48cbc677..da87afd5 100644
--- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
@@ -76,7 +76,7 @@ public:
virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData& Data, ITexture** ppTexture)override final;
- void CreateTexture(const TextureDesc& TexDesc, VkImage vkImgHandle, class TextureVkImpl** ppTexture);
+ void CreateTexture(const TextureDesc& TexDesc, VkImage vkImgHandle, RESOURCE_STATE InitialState, class TextureVkImpl** ppTexture);
virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler** ppSampler)override final;
@@ -84,9 +84,9 @@ public:
virtual VkDevice GetVkDevice()override final{ return m_LogicalVkDevice->GetVkDevice();}
- virtual void CreateTextureFromVulkanImage(VkImage vkImage, const TextureDesc& TexDesc, ITexture** ppTexture)override final;
+ virtual void CreateTextureFromVulkanImage(VkImage vkImage, const TextureDesc& TexDesc, RESOURCE_STATE InitialState, ITexture** ppTexture)override final;
- virtual void CreateBufferFromVulkanResource(VkBuffer vkBuffer, const BufferDesc& BuffDesc, IBuffer** ppBuffer)override final;
+ virtual void CreateBufferFromVulkanResource(VkBuffer vkBuffer, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer)override final;
// Idles the GPU
void IdleGPU();
diff --git a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h
index c4fdcdc5..df416323 100644
--- a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h
@@ -56,6 +56,7 @@ public:
FixedBlockMemoryAllocator& TexViewObjAllocator,
class RenderDeviceVkImpl* pDeviceVk,
const TextureDesc& TexDesc,
+ RESOURCE_STATE InitialState,
VkImage VkImageHandle);
~TextureVkImpl();
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h
index cfd1bc12..49bd0810 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h
@@ -58,4 +58,7 @@ VkSamplerMipmapMode FilterTypeToVkMipmapMode(FILTER_TYPE FilterType);
VkSamplerAddressMode AddressModeToVkAddressMode(TEXTURE_ADDRESS_MODE AddressMode);
VkBorderColor BorderColorToVkBorderColor(const Float32 BorderColor[]);
+VkAccessFlags ResourceStateFlagsToVkAccessFlags(RESOURCE_STATE StateFlags);
+VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag);
+
}
diff --git a/Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h b/Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h
index 58cc5bc7..3a356bf6 100644
--- a/Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h
+++ b/Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h
@@ -55,33 +55,41 @@ public:
/// Creates a texture object from native Vulkan image
- /// \param [in] vkImage - Vulkan image handle
- /// \param [in] TexDesc - Texture description. Vulkan provides no means to retrieve any
- /// image properties from the image handle, so complete texture
- /// description must be provided
- /// \param [out] ppTexture - Address of the memory location where the pointer to the
- /// texture interface will be stored.
- /// The function calls AddRef(), so that the new object will contain
- /// one refernce.
+ /// \param [in] vkImage - Vulkan image handle
+ /// \param [in] TexDesc - Texture description. Vulkan provides no means to retrieve any
+ /// image properties from the image handle, so complete texture
+ /// description must be provided
+ /// \param [in] InitialState - Initial texture state. See Diligent::RESOURCE_STATE.
+ /// \param [out] ppTexture - Address of the memory location where the pointer to the
+ /// texture interface will be stored.
+ /// The function calls AddRef(), so that the new object will contain
+ /// one refernce.
/// \note Created texture object does not take ownership of the Vulkan image and will not
/// destroy it once released. The application must not destroy the image while it is
/// in use by the engine.
- virtual void CreateTextureFromVulkanImage(VkImage vkImage, const TextureDesc& TexDesc, ITexture** ppTexture) = 0;
+ virtual void CreateTextureFromVulkanImage(VkImage vkImage,
+ const TextureDesc& TexDesc,
+ RESOURCE_STATE InitialState,
+ ITexture** ppTexture) = 0;
/// Creates a buffer object from native Vulkan resource
- /// \param [in] vkBuffer - Vulkan buffer handle
- /// \param [in] BuffDesc - Buffer description. Vulkan provides no means to retrieve any
- /// buffer properties from the buffer handle, so complete buffer
- /// description must be provided
- /// \param [out] ppBuffer - Address of the memory location where the pointer to the
- /// buffer interface will be stored.
- /// The function calls AddRef(), so that the new object will contain
- /// one reference.
+ /// \param [in] vkBuffer - Vulkan buffer handle
+ /// \param [in] BuffDesc - Buffer description. Vulkan provides no means to retrieve any
+ /// buffer properties from the buffer handle, so complete buffer
+ /// description must be provided
+ /// \param [in] InitialState - Initial buffer state. See Diligent::RESOURCE_STATE.
+ /// \param [out] ppBuffer - Address of the memory location where the pointer to the
+ /// buffer interface will be stored.
+ /// The function calls AddRef(), so that the new object will contain
+ /// one reference.
/// \note Created buffer object does not take ownership of the Vulkan buffer and will not
/// destroy it once released. The application must not destroy Vulkan buffer while it is
/// in use by the engine.
- virtual void CreateBufferFromVulkanResource(VkBuffer vkBuffer, const BufferDesc& BuffDesc, IBuffer** ppBuffer) = 0;
+ virtual void CreateBufferFromVulkanResource(VkBuffer vkBuffer,
+ const BufferDesc& BuffDesc,
+ RESOURCE_STATE InitialState,
+ IBuffer** ppBuffer) = 0;
};
}
diff --git a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp
index e5563c5d..c6ed186f 100644
--- a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp
@@ -264,6 +264,7 @@ BufferVkImpl :: BufferVkImpl(IReferenceCounters* pRefCounters,
FixedBlockMemoryAllocator& BuffViewObjMemAllocator,
RenderDeviceVkImpl* pRenderDeviceVk,
const BufferDesc& BuffDesc,
+ RESOURCE_STATE InitialState,
VkBuffer vkBuffer) :
TBufferBase(pRefCounters, BuffViewObjMemAllocator, pRenderDeviceVk, BuffDesc, false),
m_AccessFlags(0),
@@ -273,6 +274,7 @@ BufferVkImpl :: BufferVkImpl(IReferenceCounters* pRefCounters,
m_DynamicAllocations(STD_ALLOCATOR_RAW_MEM(VulkanDynamicAllocation, GetRawAllocator(), "Allocator for vector<VulkanDynamicAllocation>")),
m_VulkanBuffer(vkBuffer)
{
+ SetState(InitialState);
}
BufferVkImpl :: ~BufferVkImpl()
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index 83128316..a08517e4 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -1519,4 +1519,9 @@ namespace Diligent
#endif
return DynAlloc;
}
+
+ void DeviceContextVkImpl::TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers)
+ {
+
+ }
}
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index 89d5f912..2d807d62 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -399,12 +399,12 @@ void RenderDeviceVkImpl::CreatePipelineState(const PipelineStateDesc &PipelineDe
}
-void RenderDeviceVkImpl :: CreateBufferFromVulkanResource(VkBuffer vkBuffer, const BufferDesc& BuffDesc, IBuffer** ppBuffer)
+void RenderDeviceVkImpl :: CreateBufferFromVulkanResource(VkBuffer vkBuffer, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer)
{
CreateDeviceObject("buffer", BuffDesc, ppBuffer,
[&]()
{
- BufferVkImpl* pBufferVk( NEW_RC_OBJ(m_BufObjAllocator, "BufferVkImpl instance", BufferVkImpl)(m_BuffViewObjAllocator, this, BuffDesc, vkBuffer ) );
+ BufferVkImpl* pBufferVk( NEW_RC_OBJ(m_BufObjAllocator, "BufferVkImpl instance", BufferVkImpl)(m_BuffViewObjAllocator, this, BuffDesc, InitialState, vkBuffer ) );
pBufferVk->QueryInterface( IID_Buffer, reinterpret_cast<IObject**>(ppBuffer) );
pBufferVk->CreateDefaultViews();
OnCreateDeviceObject( pBufferVk );
@@ -441,12 +441,12 @@ void RenderDeviceVkImpl :: CreateShader(const ShaderCreationAttribs &ShaderCreat
}
-void RenderDeviceVkImpl::CreateTextureFromVulkanImage(VkImage vkImage, const TextureDesc& TexDesc, ITexture** ppTexture)
+void RenderDeviceVkImpl::CreateTextureFromVulkanImage(VkImage vkImage, const TextureDesc& TexDesc, RESOURCE_STATE InitialState, ITexture** ppTexture)
{
CreateDeviceObject( "texture", TexDesc, ppTexture,
[&]()
{
- TextureVkImpl* pTextureVk = NEW_RC_OBJ(m_TexObjAllocator, "TextureVkImpl instance", TextureVkImpl)(m_TexViewObjAllocator, this, TexDesc, vkImage );
+ TextureVkImpl* pTextureVk = NEW_RC_OBJ(m_TexObjAllocator, "TextureVkImpl instance", TextureVkImpl)(m_TexViewObjAllocator, this, TexDesc, InitialState, vkImage );
pTextureVk->QueryInterface( IID_Texture, reinterpret_cast<IObject**>(ppTexture) );
pTextureVk->CreateDefaultViews();
@@ -456,12 +456,12 @@ void RenderDeviceVkImpl::CreateTextureFromVulkanImage(VkImage vkImage, const Tex
}
-void RenderDeviceVkImpl::CreateTexture(const TextureDesc& TexDesc, VkImage vkImgHandle, class TextureVkImpl **ppTexture)
+void RenderDeviceVkImpl::CreateTexture(const TextureDesc& TexDesc, VkImage vkImgHandle, RESOURCE_STATE InitialState, class TextureVkImpl **ppTexture)
{
CreateDeviceObject( "texture", TexDesc, ppTexture,
[&]()
{
- TextureVkImpl* pTextureVk = NEW_RC_OBJ(m_TexObjAllocator, "TextureVkImpl instance", TextureVkImpl)(m_TexViewObjAllocator, this, TexDesc, std::move(vkImgHandle));
+ TextureVkImpl* pTextureVk = NEW_RC_OBJ(m_TexObjAllocator, "TextureVkImpl instance", TextureVkImpl)(m_TexViewObjAllocator, this, TexDesc, InitialState, std::move(vkImgHandle));
pTextureVk->QueryInterface( IID_TextureVk, reinterpret_cast<IObject**>(ppTexture) );
}
);
diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp
index f5c11b14..9a5bed10 100644
--- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp
@@ -376,7 +376,7 @@ void SwapChainVkImpl::InitBuffersAndViews()
BackBufferDesc.MipLevels = 1;
RefCntAutoPtr<TextureVkImpl> pBackBufferTex;
- m_pRenderDevice.RawPtr<RenderDeviceVkImpl>()->CreateTexture(BackBufferDesc, swapchainImages[i], &pBackBufferTex);
+ m_pRenderDevice.RawPtr<RenderDeviceVkImpl>()->CreateTexture(BackBufferDesc, swapchainImages[i], RESOURCE_STATE_UNDEFINED, &pBackBufferTex);
TextureViewDesc RTVDesc;
RTVDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET;
diff --git a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
index 50cdbb02..fb11548b 100644
--- a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
@@ -439,11 +439,14 @@ TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters,
FixedBlockMemoryAllocator& TexViewObjAllocator,
RenderDeviceVkImpl* pDeviceVk,
const TextureDesc& TexDesc,
+ RESOURCE_STATE InitialState,
VkImage VkImageHandle) :
TTextureBase(pRefCounters, TexViewObjAllocator, pDeviceVk, TexDesc),
m_VulkanImage(VkImageHandle)
{
+ SetState(InitialState);
}
+
IMPLEMENT_QUERY_INTERFACE( TextureVkImpl, IID_TextureVk, TTextureBase )
void TextureVkImpl::CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView )
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
index 673c8eea..75c23615 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
@@ -26,6 +26,7 @@
#include <array>
#include "VulkanTypeConversions.h"
+#include "PlatformMisc.h"
namespace Diligent
{
@@ -1098,4 +1099,126 @@ VkBorderColor BorderColorToVkBorderColor(const Float32 BorderColor[])
return vkBorderColor;
}
+
+static VkAccessFlags ResourceStateFlagToVkAccessFlags(RESOURCE_STATE StateFlag)
+{
+ // Currently not used:
+ //VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
+ //VK_ACCESS_HOST_READ_BIT
+ //VK_ACCESS_HOST_WRITE_BIT
+ //VK_ACCESS_MEMORY_READ_BIT
+ //VK_ACCESS_MEMORY_WRITE_BIT
+ //VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT
+ //VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT
+ //VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT
+ //VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX
+ //VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX
+ //VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT
+ //VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV
+ //VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NVX
+ //VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NVX
+
+ static_assert(RESOURCE_STATE_MAX_BIT == 0x8000, "This function must be updated to handle new resource state flag");
+ VERIFY((StateFlag & (StateFlag-1)) == 0, "Only single bit must be set");
+ switch(StateFlag)
+ {
+ case RESOURCE_STATE_UNDEFINED: return 0;
+ case RESOURCE_STATE_VERTEX_BUFFER: return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
+ case RESOURCE_STATE_CONSTANT_BUFFER: return VK_ACCESS_UNIFORM_READ_BIT;
+ case RESOURCE_STATE_INDEX_BUFFER: return VK_ACCESS_INDEX_READ_BIT;
+ case RESOURCE_STATE_RENDER_TARGET: return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ case RESOURCE_STATE_UNORDERED_ACCESS: return VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
+ case RESOURCE_STATE_DEPTH_WRITE: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+ case RESOURCE_STATE_DEPTH_READ: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
+ case RESOURCE_STATE_SHADER_RESOURCE: return VK_ACCESS_SHADER_READ_BIT;
+ case RESOURCE_STATE_STREAM_OUT: return VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT;
+ case RESOURCE_STATE_INDIRECT_ARGUMENT: return VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
+ case RESOURCE_STATE_COPY_DEST: return VK_ACCESS_TRANSFER_WRITE_BIT;
+ case RESOURCE_STATE_COPY_SOURCE: return VK_ACCESS_TRANSFER_READ_BIT;
+ case RESOURCE_STATE_RESOLVE_DEST: return VK_ACCESS_MEMORY_READ_BIT;
+ case RESOURCE_STATE_RESOLVE_SOURCE: return VK_ACCESS_MEMORY_WRITE_BIT;
+ case RESOURCE_STATE_PRESENT: return VK_ACCESS_MEMORY_READ_BIT;
+
+ default:
+ UNEXPECTED("Unexpected resource state flag");
+ return 0;
+ }
+}
+
+class StateFlagBitPosToVkAccessFlags
+{
+public:
+ StateFlagBitPosToVkAccessFlags()
+ {
+ static_assert( (1 << MaxFlagBitPos) == RESOURCE_STATE_MAX_BIT, "This function must be updated to handle new resource state flag");
+ for (Uint32 bit=0; bit < MaxFlagBitPos; ++bit)
+ {
+ FlagBitPosToVkAccessFlagsMap[bit] = ResourceStateFlagToVkAccessFlags(static_cast<RESOURCE_STATE>(1<<bit));
+ }
+ }
+
+ VkAccessFlags operator()(Uint32 BitPos)const
+ {
+ VERIFY(BitPos <= MaxFlagBitPos, "Resource state flag bit position (", BitPos, ") exceeds max bit position (", MaxFlagBitPos, ")");
+ return FlagBitPosToVkAccessFlagsMap[BitPos];
+ }
+
+private:
+ static constexpr Uint32 MaxFlagBitPos = 15;
+ std::array<VkAccessFlags, MaxFlagBitPos + 1> FlagBitPosToVkAccessFlagsMap;
+};
+
+
+VkAccessFlags ResourceStateFlagsToVkAccessFlags(RESOURCE_STATE StateFlags)
+{
+ VERIFY(StateFlags < (RESOURCE_STATE_MAX_BIT<<1), "Resource state flags are out of range");
+ static const StateFlagBitPosToVkAccessFlags BitPosToAccessFlags;
+ VkAccessFlags AccessFlags = 0;
+ Uint32 Bits = StateFlags;
+ while(Bits != 0)
+ {
+ auto lsb = PlatformMisc::GetLSB(Bits);
+ AccessFlags |= BitPosToAccessFlags(lsb);
+ Bits &= ~(1<<lsb);
+ }
+ return AccessFlags;
+}
+
+
+VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag)
+{
+ // Currently not used:
+ //VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
+ //VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
+ //VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV
+ //VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
+ //VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
+
+ static_assert(RESOURCE_STATE_MAX_BIT == 0x8000, "This function must be updated to handle new resource state flag");
+ VERIFY((StateFlag & (StateFlag-1)) == 0, "Only single bit must be set");
+ switch(StateFlag)
+ {
+ case RESOURCE_STATE_UNDEFINED: return VK_IMAGE_LAYOUT_UNDEFINED;
+ case RESOURCE_STATE_VERTEX_BUFFER: UNEXPECTED("Invalid resource state"); return VK_IMAGE_LAYOUT_UNDEFINED;
+ case RESOURCE_STATE_CONSTANT_BUFFER: UNEXPECTED("Invalid resource state"); return VK_IMAGE_LAYOUT_UNDEFINED;
+ case RESOURCE_STATE_INDEX_BUFFER: UNEXPECTED("Invalid resource state"); return VK_IMAGE_LAYOUT_UNDEFINED;
+ case RESOURCE_STATE_RENDER_TARGET: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ case RESOURCE_STATE_UNORDERED_ACCESS: return VK_IMAGE_LAYOUT_GENERAL;
+ case RESOURCE_STATE_DEPTH_WRITE: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ case RESOURCE_STATE_DEPTH_READ: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
+ case RESOURCE_STATE_SHADER_RESOURCE: return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ case RESOURCE_STATE_STREAM_OUT: UNEXPECTED("Invalid resource state"); return VK_IMAGE_LAYOUT_UNDEFINED;
+ case RESOURCE_STATE_INDIRECT_ARGUMENT: UNEXPECTED("Invalid resource state"); return VK_IMAGE_LAYOUT_UNDEFINED;
+ case RESOURCE_STATE_COPY_DEST: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ case RESOURCE_STATE_COPY_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ case RESOURCE_STATE_RESOLVE_DEST: UNSUPPORTED("Not currently implemented"); return VK_IMAGE_LAYOUT_UNDEFINED;
+ case RESOURCE_STATE_RESOLVE_SOURCE: UNSUPPORTED("Not currently implemented"); return VK_IMAGE_LAYOUT_UNDEFINED;
+ case RESOURCE_STATE_PRESENT: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+
+ default:
+ UNEXPECTED("Unexpected resource state flag");
+ return VK_IMAGE_LAYOUT_UNDEFINED;
+ }
+}
+
}