summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-04-19 15:45:12 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-04-19 15:45:12 +0000
commit97d54dee1d0007285df88f73a2adc120aa835685 (patch)
tree1ffb64d82a5e60f844e5fc4e2edcf1c677fd844e /Graphics/GraphicsEngineVulkan
parentAdded image layout transitioning function (diff)
downloadDiligentCore-97d54dee1d0007285df88f73a2adc120aa835685.tar.gz
DiligentCore-97d54dee1d0007285df88f73a2adc120aa835685.zip
Working on vulkan image layout transitions
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h4
-rw-r--r--Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h6
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h14
-rw-r--r--Graphics/GraphicsEngineVulkan/interface/DeviceContextVk.h6
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp35
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp54
7 files changed, 93 insertions, 28 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
index 9652fafa..56ee55f5 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
@@ -86,9 +86,9 @@ public:
virtual void ExecuteCommandList(class ICommandList *pCommandList)override final;
-#if 0
- virtual void TransitionTextureState(ITexture *pTexture, Vk_RESOURCE_STATES State)override final;
+ virtual void TransitionImageLayout(ITexture *pTexture, VkImageLayout NewLayout)override final;
+#if 0
virtual void TransitionBufferState(IBuffer *pBuffer, Vk_RESOURCE_STATES State)override final;
///// Clears the state caches. This function is called once per frame
diff --git a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h
index 223ca9bd..7efce04b 100644
--- a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h
@@ -68,10 +68,8 @@ public:
virtual void Map( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags, MappedTextureSubresource &MappedData )override;
virtual void Unmap( IDeviceContext *pContext, Uint32 Subresource, MAP_TYPE MapType, Uint32 MapFlags )override;
-/*
- virtual IVkResource* GetVkTexture(){ return GetVkResource(); }
- */
- virtual void* GetNativeHandle()override final { return nullptr;/*GetVkTexture();*/ }
+ virtual VkImage GetVkImage(){ return m_VulkanImage; }
+ virtual void* GetNativeHandle()override final { return GetVkImage(); }
/*
virtual void SetVkResourceState(Vk_RESOURCE_STATES state)override final{ SetState(state); }
*/
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h
index c2fff6a2..9d800f48 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h
@@ -242,7 +242,6 @@ namespace VulkanUtilities
static void TransitionImageLayout(VkCommandBuffer CmdBuffer,
VkImage Image,
- VkImageAspectFlags AspectMask,
VkImageLayout OldLayout,
VkImageLayout NewLayout,
const VkImageSubresourceRange& SubresRange,
@@ -250,15 +249,20 @@ namespace VulkanUtilities
VkPipelineStageFlags DestStages);
void TransitionImageLayout(VkImage Image,
- VkImageAspectFlags AspectMask,
VkImageLayout OldLayout,
VkImageLayout NewLayout,
const VkImageSubresourceRange& SubresRange,
- VkPipelineStageFlags SrcStages,
- VkPipelineStageFlags DestStages)
+ VkPipelineStageFlags SrcStages = 0,
+ VkPipelineStageFlags DestStages = 0)
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
- TransitionImageLayout(m_VkCmdBuffer, Image, AspectMask, OldLayout, NewLayout, SubresRange, SrcStages, DestStages);
+ if(m_State.RenderPass != VK_NULL_HANDLE)
+ {
+ // Image layout transitions within a render pass execute
+ // dependencies between attachments
+ EndRenderPass();
+ }
+ TransitionImageLayout(m_VkCmdBuffer, Image, OldLayout, NewLayout, SubresRange, SrcStages, DestStages);
}
void FlushBarriers();
diff --git a/Graphics/GraphicsEngineVulkan/interface/DeviceContextVk.h b/Graphics/GraphicsEngineVulkan/interface/DeviceContextVk.h
index 9a283151..50ec9d75 100644
--- a/Graphics/GraphicsEngineVulkan/interface/DeviceContextVk.h
+++ b/Graphics/GraphicsEngineVulkan/interface/DeviceContextVk.h
@@ -40,11 +40,11 @@ class IDeviceContextVk : public IDeviceContext
{
public:
- /// Transitions internal D3D12 texture object to a specified state
+ /// Transitions internal vulkan image to a specified layout
/// \param [in] pTexture - texture to transition
- /// \param [in] State - D3D12 resource state this texture to transition to
- //virtual void TransitionTextureState(ITexture *pTexture, D3D12_RESOURCE_STATES State) = 0;
+ /// \param [in] NewLayout - Vulkan image layout this texture to transition to
+ virtual void TransitionImageLayout(ITexture *pTexture, VkImageLayout NewLayout) = 0;
/// Transitions internal D3D12 buffer object to a specified state
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index 22200917..42ded191 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -889,14 +889,41 @@ namespace Diligent
#endif
}
-#if 0
- void DeviceContextVkImpl::TransitionTextureState(ITexture *pTexture, Vk_RESOURCE_STATES State)
+
+ void DeviceContextVkImpl::TransitionImageLayout(ITexture *pTexture, VkImageLayout NewLayout)
{
VERIFY_EXPR(pTexture != nullptr);
- auto *pCmdCtx = RequestCmdContext();
- pCmdCtx->TransitionResource(ValidatedCast<ITextureVk>(pTexture), State);
+ auto pTextureVk = ValidatedCast<TextureVkImpl>(pTexture);
+ if(pTextureVk->GetLayout() != NewLayout)
+ {
+ EnsureVkCmdBuffer();
+
+ auto vkImg = pTextureVk->GetVkImage();
+ const auto& TexDesc = pTextureVk->GetDesc();
+ auto Fmt = TexDesc.Format;
+ const auto& FmtAttribs = GetTextureFormatAttribs(Fmt);
+ VkImageSubresourceRange SubresRange;
+ if (FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH)
+ SubresRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
+ else if (FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL)
+ {
+ // If image has a depth / stencil format with both depth and stencil components, then the
+ // aspectMask member of subresourceRange must include both VK_IMAGE_ASPECT_DEPTH_BIT and
+ // VK_IMAGE_ASPECT_STENCIL_BIT (6.7.3)
+ SubresRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+ }
+ else
+ SubresRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ SubresRange.baseArrayLayer = 0;
+ SubresRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
+ SubresRange.baseMipLevel = 0;
+ SubresRange.levelCount = VK_REMAINING_MIP_LEVELS;
+ m_CommandBuffer.TransitionImageLayout(vkImg, pTextureVk->GetLayout(), NewLayout, SubresRange);
+ pTextureVk->SetLayout(NewLayout);
+ }
}
+#if 0
void DeviceContextVkImpl::TransitionBufferState(IBuffer *pBuffer, Vk_RESOURCE_STATES State)
{
VERIFY_EXPR(pBuffer != nullptr);
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp
index 2c2f1bcd..47300c06 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp
@@ -155,6 +155,8 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk( const EngineVkAttribs& Crea
DeviceFeatures.depthClamp = VK_TRUE;
DeviceFeatures.independentBlend = VK_TRUE;
DeviceFeatures.samplerAnisotropy = VK_TRUE;
+ DeviceFeatures.geometryShader = VK_TRUE;
+ DeviceFeatures.tessellationShader= VK_TRUE;
DeviceCreateInfo.pEnabledFeatures = &DeviceFeatures; // NULL or a pointer to a VkPhysicalDeviceFeatures structure that contains
// boolean indicators of all the features to be enabled.
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp
index 3f5710a2..2f06cdb5 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp
@@ -145,7 +145,6 @@ static VkPipelineStageFlags PipelineStageFromAccessFlags(VkAccessFlags AccessFla
void VulkanCommandBuffer::TransitionImageLayout(VkCommandBuffer CmdBuffer,
VkImage Image,
- VkImageAspectFlags AspectMask,
VkImageLayout OldLayout,
VkImageLayout NewLayout,
const VkImageSubresourceRange& SubresRange,
@@ -164,7 +163,6 @@ void VulkanCommandBuffer::TransitionImageLayout(VkCommandBuffer CmdBuffer,
ImgBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // source queue family for a queue family ownership transfer.
ImgBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // destination queue family for a queue family ownership transfer.
ImgBarrier.image = Image;
- ImgBarrier.subresourceRange.aspectMask = AspectMask;
ImgBarrier.subresourceRange = SubresRange;
switch (OldLayout)
@@ -182,12 +180,12 @@ void VulkanCommandBuffer::TransitionImageLayout(VkCommandBuffer CmdBuffer,
// must only be used as a color or resolve attachment in a VkFramebuffer (11.4)
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
- ImgBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ ImgBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
break;
// must only be used as a depth/stencil attachment in a VkFramebuffer (11.4)
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
- ImgBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+ ImgBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
break;
// must only be used as a read-only depth/stencil attachment in a VkFramebuffer and/or as a read-only image in a shader (11.4)
@@ -249,11 +247,11 @@ void VulkanCommandBuffer::TransitionImageLayout(VkCommandBuffer CmdBuffer,
break;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
- ImgBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ ImgBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
- ImgBarrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+ ImgBarrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
break;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
@@ -296,14 +294,44 @@ void VulkanCommandBuffer::TransitionImageLayout(VkCommandBuffer CmdBuffer,
}
if(SrcStages == 0)
- SrcStages = PipelineStageFromAccessFlags(ImgBarrier.srcAccessMask);
+ {
+ if(ImgBarrier.srcAccessMask != 0)
+ {
+ SrcStages = PipelineStageFromAccessFlags(ImgBarrier.srcAccessMask);
+ }
+ else
+ {
+ // An execution dependency with only VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT in the source stage
+ // mask will effectively not wait for any prior commands to complete. (6.1.2)
+ SrcStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ }
+ }
if (DestStages == 0)
- DestStages = PipelineStageFromAccessFlags(ImgBarrier.dstAccessMask);
+ {
+ if(ImgBarrier.dstAccessMask != 0)
+ {
+ DestStages = PipelineStageFromAccessFlags(ImgBarrier.dstAccessMask);
+ }
+ else
+ {
+ // An execution dependency with only VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT in the destination
+ // stage mask will only prevent that stage from executing in subsequently submitted commands.
+ // As this stage does not perform any actual execution, this is not observable - in effect,
+ // it does not delay processing of subsequent commands. (6.1.2)
+ DestStages = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+ }
+ }
+
+ // Including a particular pipeline stage in the first synchronization scope of a command implicitly
+ // includes logically earlier pipeline stages in the synchronization scope. Similarly, the second
+ // synchronization scope includes logically later pipeline stages.
+ // However, note that access scopes are not affected in this way - only the precise stages specified
+ // are considered part of each access scope. (6.1.2)
vkCmdPipelineBarrier(CmdBuffer,
- SrcStages,
- DestStages,
+ SrcStages, // must not be 0
+ DestStages, // must not be 0
0, // a bitmask specifying how execution and memory dependencies are formed
0, // memoryBarrierCount
nullptr, // pMemoryBarriers
@@ -311,6 +339,12 @@ void VulkanCommandBuffer::TransitionImageLayout(VkCommandBuffer CmdBuffer,
nullptr, // pBufferMemoryBarriers
1,
&ImgBarrier);
+ // Each element of pMemoryBarriers, pBufferMemoryBarriers and pImageMemoryBarriers must not
+ // have any access flag included in its srcAccessMask member if that bit is not supported by
+ // any of the pipeline stages in srcStageMask.
+ // Each element of pMemoryBarriers, pBufferMemoryBarriers and pImageMemoryBarriers must not
+ // have any access flag included in its dstAccessMask member if that bit is not supported by any
+ // of the pipeline stages in dstStageMask (6.6)
}
void VulkanCommandBuffer::FlushBarriers()