summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-04-19 05:26:22 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-04-19 05:26:22 +0000
commit401ddeeee1b072f69c808c42d5dc2e078a4a10ea (patch)
treeac9c2fe392c13aed7d4b0e965b96d6eb94a64d45 /Graphics/GraphicsEngineVulkan
parentWorking on Device context Vulkan implementation: implemented setting viewport... (diff)
downloadDiligentCore-401ddeeee1b072f69c808c42d5dc2e078a4a10ea.tar.gz
DiligentCore-401ddeeee1b072f69c808c42d5dc2e078a4a10ea.zip
Added image layout transitioning function
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/CMakeLists.txt1
-rw-r--r--Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.h8
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h8
-rw-r--r--Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h7
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h74
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp64
-rw-r--r--Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp22
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp321
8 files changed, 432 insertions, 73 deletions
diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt
index 322f90b3..a340fedd 100644
--- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt
+++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt
@@ -88,6 +88,7 @@ set(SRC
)
set(VULKAN_UTILS_SRC
+ src/VulkanUtilities/VulkanCommandBuffer.cpp
src/VulkanUtilities/VulkanCommandBufferPool.cpp
src/VulkanUtilities/VulkanDebug.cpp
src/VulkanUtilities/VulkanFencePool.cpp
diff --git a/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.h b/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.h
index d42700d8..645218dc 100644
--- a/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.h
@@ -24,7 +24,7 @@
#pragma once
/// \file
-/// Declaration of Diligent::CommandListD3D12Impl class
+/// Declaration of Diligent::CommandListVkImpl class
#include "CommandListBase.h"
@@ -32,17 +32,17 @@ namespace Diligent
{
/// Implementation of the Diligent::ICommandList interface
-class CommandListD3D12Impl : public CommandListBase<ICommandList>
+class CommandListVkImpl : public CommandListBase<ICommandList>
{
public:
typedef CommandListBase<ICommandList> TCommandListBase;
- CommandListD3D12Impl(IReferenceCounters *pRefCounters, IRenderDevice *pDevice, class CommandContext* pCmdContext) :
+ CommandListVkImpl(IReferenceCounters *pRefCounters, IRenderDevice *pDevice, class CommandContext* pCmdContext) :
TCommandListBase(pRefCounters, pDevice),
m_pCmdContext(pCmdContext)
{
}
- ~CommandListD3D12Impl()
+ ~CommandListVkImpl()
{
VERIFY(m_pCmdContext == nullptr, "Destroying command list that was never executed");
}
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
index 4564b331..9652fafa 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
@@ -113,7 +113,7 @@ public:
Uint32 GetContextId()const{return m_ContextId;}
#endif
- size_t GetNumCommandsInCtx()const { return m_NumCommandsInCurCtx; }
+ size_t GetNumCommandsInCtx()const { return m_State.NumCommands; }
private:
void CommitRenderPassAndFramebuffer();
@@ -124,7 +124,6 @@ private:
void CommitViewports();
void CommitScissorRects();
- void Flush(bool RequestNewCmdCtx);
#if 0
friend class SwapChainVkImpl;
#endif
@@ -133,6 +132,7 @@ private:
VulkanUtilities::VulkanCommandBuffer m_CommandBuffer;
+ const Uint32 m_NumCommandsToFlush = 192;
struct ContextState
{
/// Flag indicating if currently committed vertex buffers are up to date
@@ -140,10 +140,10 @@ private:
/// Flag indicating if currently committed index buffer is up to date
bool CommittedIBUpToDate = false;
+
+ Uint32 NumCommands = 0;
}m_State;
- Uint32 m_NumCommandsInCurCtx = 0;
- const Uint32 m_NumCommandsToFlush = 192;
#if 0
CComPtr<IVkResource> m_CommittedVkIndexBuffer;
VALUE_TYPE m_CommittedIBFormat = VT_UNDEFINED;
diff --git a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h
index ac10e686..223ca9bd 100644
--- a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h
@@ -96,9 +96,13 @@ public:
{
return m_TexArraySRV.GetCpuHandle();
}
+*/
+
+ void SetLayout(VkImageLayout NewLayout){ m_CurrentLayout = NewLayout;}
+ VkImageLayout GetLayout()const{return m_CurrentLayout;}
protected:
-*/
+
void CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView )override;
//void PrepareVkInitData(const TextureData &InitData, Uint32 NumSubresources, std::vector<Vk_SUBRESOURCE_DATA> &VkInitData);
@@ -114,6 +118,7 @@ protected:
*/
VulkanUtilities::ImageWrapper m_VulkanImage;
VulkanUtilities::DeviceMemoryWrapper m_ImageMemory;
+ VkImageLayout m_CurrentLayout = VK_IMAGE_LAYOUT_UNDEFINED;
};
}
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h
index 9af47e44..c2fff6a2 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h
@@ -24,6 +24,7 @@
#pragma once
#include "vulkan.h"
+#include "DebugUtilities.h"
namespace VulkanUtilities
{
@@ -83,60 +84,60 @@ namespace VulkanUtilities
);
}
- void Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
+ void Draw(uint32_t VertexCount, uint32_t InstanceCount, uint32_t FirstVertex, uint32_t FirstInstance)
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDraw() must be called inside render pass (19.3)");
VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound");
- vkCmdDraw(m_VkCmdBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
+ vkCmdDraw(m_VkCmdBuffer, VertexCount, InstanceCount, FirstVertex, FirstInstance);
}
- void DrawIndexed(uint32_t indexCount,uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
+ void DrawIndexed(uint32_t IndexCount,uint32_t InstanceCount, uint32_t FirstIndex, int32_t VertexOffset, uint32_t FirstInstance)
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawIndexed() must be called inside render pass (19.3)");
VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound");
VERIFY(m_State.IndexBuffer != VK_NULL_HANDLE, "No index buffer bound");
- vkCmdDrawIndexed(m_VkCmdBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
+ vkCmdDrawIndexed(m_VkCmdBuffer, IndexCount, InstanceCount, FirstIndex, VertexOffset, FirstInstance);
}
- void DrawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
+ void DrawIndirect(VkBuffer Buffer, VkDeviceSize Offset, uint32_t DrawCount, uint32_t Stride)
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawIndirect() must be called inside render pass (19.3)");
VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound");
- vkCmdDrawIndirect(m_VkCmdBuffer, buffer, offset, drawCount, stride);
+ vkCmdDrawIndirect(m_VkCmdBuffer, Buffer, Offset, DrawCount, Stride);
}
- void DrawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
+ void DrawIndexedIndirect(VkBuffer Buffer, VkDeviceSize Offset, uint32_t DrawCount, uint32_t Stride)
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawIndirect() must be called inside render pass (19.3)");
VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound");
VERIFY(m_State.IndexBuffer != VK_NULL_HANDLE, "No index buffer bound");
- vkCmdDrawIndexedIndirect(m_VkCmdBuffer, buffer, offset, drawCount, stride);
+ vkCmdDrawIndexedIndirect(m_VkCmdBuffer, Buffer, Offset, DrawCount, Stride);
}
- void Dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
+ void Dispatch(uint32_t GroupCountX, uint32_t GroupCountY, uint32_t GroupCountZ)
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
VERIFY(m_State.RenderPass == VK_NULL_HANDLE, "vkCmdDispatch() must be called outside of render pass (27)");
VERIFY(m_State.ComputePipeline != VK_NULL_HANDLE, "No compute pipeline bound");
- vkCmdDispatch(m_VkCmdBuffer, groupCountX, groupCountY, groupCountZ);
+ vkCmdDispatch(m_VkCmdBuffer, GroupCountX, GroupCountY, GroupCountZ);
}
- void DispatchIndirect(VkBuffer buffer, VkDeviceSize offset)
+ void DispatchIndirect(VkBuffer Buffer, VkDeviceSize Offset)
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
VERIFY(m_State.RenderPass == VK_NULL_HANDLE, "vkCmdDispatchIndirect() must be called outside of render pass (27)");
VERIFY(m_State.ComputePipeline != VK_NULL_HANDLE, "No compute pipeline bound");
- vkCmdDispatchIndirect(m_VkCmdBuffer, buffer, offset);
+ vkCmdDispatchIndirect(m_VkCmdBuffer, Buffer, Offset);
}
void BeginRenderPass(VkRenderPass RenderPass, VkFramebuffer Framebuffer, uint32_t FramebufferWidth, uint32_t FramebufferHeight)
@@ -206,39 +207,62 @@ namespace VulkanUtilities
}
}
- void SetViewports(uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports)
+ void SetViewports(uint32_t FirstViewport, uint32_t ViewportCount, const VkViewport* pViewports)
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
- vkCmdSetViewport(m_VkCmdBuffer, firstViewport, viewportCount, pViewports);
+ vkCmdSetViewport(m_VkCmdBuffer, FirstViewport, ViewportCount, pViewports);
}
- void SetScissorRects(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors)
+ void SetScissorRects(uint32_t FirstScissor, uint32_t ScissorCount, const VkRect2D* pScissors)
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
- vkCmdSetScissor(m_VkCmdBuffer, firstScissor, scissorCount, pScissors);
+ vkCmdSetScissor(m_VkCmdBuffer, FirstScissor, ScissorCount, pScissors);
}
- void SetStencilReference(uint32_t reference)
+ void SetStencilReference(uint32_t Reference)
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
- vkCmdSetStencilReference(m_VkCmdBuffer, VK_STENCIL_FRONT_AND_BACK, reference);
+ vkCmdSetStencilReference(m_VkCmdBuffer, VK_STENCIL_FRONT_AND_BACK, Reference);
}
- void SetBlendConstants(const float blendConstants[4])
+ void SetBlendConstants(const float BlendConstants[4])
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
- vkCmdSetBlendConstants(m_VkCmdBuffer, blendConstants);
+ vkCmdSetBlendConstants(m_VkCmdBuffer, BlendConstants);
}
- void BindIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
+ void BindIndexBuffer(VkBuffer Buffer, VkDeviceSize Offset, VkIndexType IndexType)
{
VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
- vkCmdBindIndexBuffer(m_VkCmdBuffer, buffer, offset, indexType);
- m_State.IndexBuffer = buffer;
- m_State.IndexBufferOffset = offset;
- m_State.IndexType = indexType;
+ vkCmdBindIndexBuffer(m_VkCmdBuffer, Buffer, Offset, IndexType);
+ m_State.IndexBuffer = Buffer;
+ m_State.IndexBufferOffset = Offset;
+ m_State.IndexType = IndexType;
}
+ static void TransitionImageLayout(VkCommandBuffer CmdBuffer,
+ VkImage Image,
+ VkImageAspectFlags AspectMask,
+ VkImageLayout OldLayout,
+ VkImageLayout NewLayout,
+ const VkImageSubresourceRange& SubresRange,
+ VkPipelineStageFlags SrcStages,
+ VkPipelineStageFlags DestStages);
+
+ void TransitionImageLayout(VkImage Image,
+ VkImageAspectFlags AspectMask,
+ VkImageLayout OldLayout,
+ VkImageLayout NewLayout,
+ const VkImageSubresourceRange& SubresRange,
+ VkPipelineStageFlags SrcStages,
+ VkPipelineStageFlags DestStages)
+ {
+ VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE);
+ TransitionImageLayout(m_VkCmdBuffer, Image, AspectMask, OldLayout, NewLayout, SubresRange, SrcStages, DestStages);
+ }
+
+ void FlushBarriers();
+
void SetVkCmdBuffer(VkCommandBuffer VkCmdBuffer)
{
m_VkCmdBuffer = VkCmdBuffer;
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index d144f115..22200917 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -39,12 +39,8 @@ namespace Diligent
DeviceContextVkImpl::DeviceContextVkImpl( IReferenceCounters *pRefCounters, RenderDeviceVkImpl *pDeviceVkImpl, bool bIsDeferred, const EngineVkAttribs &Attribs, Uint32 ContextId) :
TDeviceContextBase(pRefCounters, pDeviceVkImpl, bIsDeferred),
//m_pUploadHeap(pDeviceVkImpl->RequestUploadHeap() ),
- m_NumCommandsInCurCtx(0),
m_NumCommandsToFlush(bIsDeferred ? std::numeric_limits<decltype(m_NumCommandsToFlush)>::max() : Attribs.NumCommandsToFlushCmdBuffer),
- /*m_pCurrCmdCtx(pDeviceVkImpl->AllocateCommandContext()),
- m_CommittedIBFormat(VT_UNDEFINED),
- m_CommittedVkIndexDataStartOffset(0),
- m_MipsGenerator(pDeviceVkImpl->GetVkDevice()),
+ /*m_MipsGenerator(pDeviceVkImpl->GetVkDevice()),
m_CmdListAllocator(GetRawAllocator(), sizeof(CommandListVkImpl), 64 ),
m_ContextId(ContextId),*/
m_CmdPool(pDeviceVkImpl->GetLogicalDevice().GetSharedPtr(), pDeviceVkImpl->GetCmdQueue()->GetQueueFamilyIndex(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)
@@ -83,10 +79,10 @@ namespace Diligent
}
else
{
- if (m_NumCommandsInCurCtx != 0)
+ if (m_State.NumCommands != 0)
LOG_WARNING_MESSAGE("Flusing outstanding commands from the device context being destroyed. This may result in synchronization errors");
- Flush(false);
+ Flush();
}
}
@@ -96,7 +92,7 @@ namespace Diligent
{
// Make sure that the number of commands in the context is at least one,
// so that the context cannot be disposed by Flush()
- m_NumCommandsInCurCtx = m_NumCommandsInCurCtx != 0 ? m_NumCommandsInCurCtx : 1;
+ m_State.NumCommands = m_State.NumCommands != 0 ? m_State.NumCommands : 1;
if (m_CommandBuffer.GetVkCmdBuffer() == VK_NULL_HANDLE)
{
auto pDeviceVkImpl = m_pDevice.RawPtr<RenderDeviceVkImpl>();
@@ -126,9 +122,9 @@ namespace Diligent
}
// Never flush deferred context!
- if (!m_bIsDeferred && m_NumCommandsInCurCtx >= m_NumCommandsToFlush)
+ if (!m_bIsDeferred && m_State.NumCommands >= m_NumCommandsToFlush)
{
- Flush(true);
+ Flush();
}
auto *pPipelineStateVk = ValidatedCast<PipelineStateVkImpl>(pPipelineState);
@@ -433,7 +429,7 @@ namespace Diligent
GraphCtx.Draw(DrawAttribs.NumVertices, DrawAttribs.NumInstances, DrawAttribs.StartVertexLocation, DrawAttribs.FirstInstanceLocation );
}
#endif
- ++m_NumCommandsInCurCtx;
+ ++m_State.NumCommands;
}
void DeviceContextVkImpl::DispatchCompute( const DispatchComputeAttribs &DispatchAttrs )
@@ -491,7 +487,7 @@ namespace Diligent
else
ComputeCtx.Dispatch(DispatchAttrs.ThreadGroupCountX, DispatchAttrs.ThreadGroupCountY, DispatchAttrs.ThreadGroupCountZ);
#endif
- ++m_NumCommandsInCurCtx;
+ ++m_State.NumCommands;
}
void DeviceContextVkImpl::ClearDepthStencil( ITextureView *pView, Uint32 ClearFlags, float fDepth, Uint8 Stencil )
@@ -525,7 +521,7 @@ namespace Diligent
// Viewport and scissor settings are not applied??
RequestCmdContext()->AsGraphicsContext().ClearDepthStencil( pDSVVk, VkClearFlags, fDepth, Stencil );
#endif
- ++m_NumCommandsInCurCtx;
+ ++m_State.NumCommands;
}
void DeviceContextVkImpl::ClearRenderTarget( ITextureView *pView, const float *RGBA )
@@ -561,17 +557,19 @@ namespace Diligent
// Viewport and scissor settings are not applied??
RequestCmdContext()->AsGraphicsContext().ClearRenderTarget( pVkRTV, RGBA );
#endif
- ++m_NumCommandsInCurCtx;
+ ++m_State.NumCommands;
}
- void DeviceContextVkImpl::Flush(bool RequestNewCmdCtx)
+ void DeviceContextVkImpl::Flush()
{
+ VERIFY(!m_bIsDeferred, "Flush() should only be called for immediate contexts");
+
auto pDeviceVkImpl = m_pDevice.RawPtr<RenderDeviceVkImpl>();
auto vkCmdBuff = m_CommandBuffer.GetVkCmdBuffer();
if(vkCmdBuff != VK_NULL_HANDLE )
{
VERIFY(!m_bIsDeferred, "Deferred contexts cannot execute command lists directly");
- if (m_NumCommandsInCurCtx != 0)
+ if (m_State.NumCommands != 0)
{
//m_pCurrCmdCtx->FlushResourceBarriers();
pDeviceVkImpl->ExecuteCommandBuffer(vkCmdBuff, true);
@@ -579,20 +577,10 @@ namespace Diligent
DisposeVkCmdBuffer();
}
- m_NumCommandsInCurCtx = 0;
-
- if(RequestNewCmdCtx)
- EnsureVkCmdBuffer();
-
+ m_State.NumCommands = 0;
m_pPipelineState.Release();
}
- void DeviceContextVkImpl::Flush()
- {
- VERIFY(!m_bIsDeferred, "Flush() should only be called for immediate contexts");
- Flush(true);
- }
-
void DeviceContextVkImpl::SetVertexBuffers( Uint32 StartSlot, Uint32 NumBuffersSet, IBuffer **ppBuffers, Uint32 *pStrides, Uint32 *pOffsets, Uint32 Flags )
{
TDeviceContextBase::SetVertexBuffers( StartSlot, NumBuffersSet, ppBuffers, pStrides, pOffsets, Flags );
@@ -601,7 +589,7 @@ namespace Diligent
void DeviceContextVkImpl::InvalidateState()
{
- if (m_NumCommandsInCurCtx != 0)
+ if (m_State.NumCommands != 0)
LOG_WARNING_MESSAGE("Invalidating context that has outstanding commands in it. Call Flush() to submit commands for execution");
TDeviceContextBase::InvalidateState();
@@ -630,7 +618,7 @@ namespace Diligent
VkViewports[vp].maxDepth = m_Viewports[vp].MaxDepth;
}
EnsureVkCmdBuffer();
- // TODO: reinterpret_cast m_Viewports to m_Viewports?
+ // TODO: reinterpret_cast m_Viewports to VkViewports?
m_CommandBuffer.SetViewports(0, m_NumViewports, VkViewports);
}
@@ -744,7 +732,7 @@ namespace Diligent
auto *pVkBuff = pBuffVk->GetVkBuffer(DstBuffDataStartByteOffset, m_ContextId);
VERIFY(DstBuffDataStartByteOffset == 0, "Dst buffer must not be suballocated");
pCmdCtx->GetCommandList()->CopyBufferRegion( pVkBuff, DstOffset + DstBuffDataStartByteOffset, Allocation.pBuffer, Allocation.Offset, NumBytes);
- ++m_NumCommandsInCurCtx;
+ ++m_State.NumCommands;
}
void DeviceContextVkImpl::UpdateBufferRegion(BufferVkImpl *pBuffVk, const void *pData, Uint64 DstOffset, Uint64 NumBytes)
@@ -772,7 +760,7 @@ namespace Diligent
size_t SrcDataStartByteOffset;
auto *pVkSrcBuff = pSrcBuffVk->GetVkBuffer(SrcDataStartByteOffset, m_ContextId);
pCmdCtx->GetCommandList()->CopyBufferRegion( pVkDstBuff, DstOffset + DstDataStartByteOffset, pVkSrcBuff, SrcOffset+SrcDataStartByteOffset, NumBytes);
- ++m_NumCommandsInCurCtx;
+ ++m_State.NumCommands;
}
void DeviceContextVkImpl::CopyTextureRegion(TextureVkImpl *pSrcTexture, Uint32 SrcSubResIndex, const Vk_BOX *pVkSrcBox,
@@ -793,7 +781,7 @@ namespace Diligent
SrcLocation.SubresourceIndex = SrcSubResIndex;
pCmdCtx->GetCommandList()->CopyTextureRegion( &DstLocation, DstX, DstY, DstZ, &SrcLocation, pVkSrcBox);
- ++m_NumCommandsInCurCtx;
+ ++m_State.NumCommands;
}
void DeviceContextVkImpl::CopyTextureRegion(IBuffer *pSrcBuffer, Uint32 SrcStride, Uint32 SrcDepthStride, class TextureVkImpl *pTextureVk, Uint32 DstSubResIndex, const Box &DstBox)
@@ -848,7 +836,7 @@ namespace Diligent
static_cast<UINT>( DstBox.MinZ ),
&SrcLocation, &VkSrcBox);
- ++m_NumCommandsInCurCtx;
+ ++m_State.NumCommands;
if (StateTransitionRequired)
{
@@ -862,7 +850,7 @@ namespace Diligent
#if 0
auto *pCtx = RequestCmdContext();
m_MipsGenerator.GenerateMips(m_pDevice.RawPtr<RenderDeviceVkImpl>(), pTexView, *pCtx);
- ++m_NumCommandsInCurCtx;
+ ++m_State.NumCommands;
#endif
}
@@ -873,7 +861,11 @@ namespace Diligent
(m_pDevice, m_pCurrCmdCtx) );
pCmdListVk->QueryInterface( IID_CommandList, reinterpret_cast<IObject**>(ppCommandList) );
m_pCurrCmdCtx = nullptr;
- Flush(true);
+ //Flush();
+
+ m_CommandBuffer.Reset();
+ m_State = ContextState{};
+ m_pPipelineState.Release();
InvalidateState();
#endif
@@ -888,7 +880,7 @@ namespace Diligent
}
#if 0
// First execute commands in this context
- Flush(true);
+ Flush();
InvalidateState();
diff --git a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
index e573e406..7b4dfecf 100644
--- a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
@@ -121,19 +121,35 @@ TextureVkImpl :: TextureVkImpl(IReferenceCounters *pRefCounters,
ImageCI.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
if (m_Desc.BindFlags & BIND_RENDER_TARGET)
- ImageCI.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ {
+ // VK_IMAGE_USAGE_TRANSFER_DST_BIT is required for vkCmdClearColorImage()
+ ImageCI.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ }
if (m_Desc.BindFlags & BIND_DEPTH_STENCIL)
- ImageCI.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ {
+ // VK_IMAGE_USAGE_TRANSFER_DST_BIT is required for vkCmdClearDepthStencilImage()
+ ImageCI.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ }
if ((m_Desc.BindFlags & BIND_UNORDERED_ACCESS) || (m_Desc.MiscFlags & MISC_TEXTURE_FLAG_GENERATE_MIPS))
+ {
ImageCI.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
+ }
if (m_Desc.BindFlags & BIND_SHADER_RESOURCE)
+ {
ImageCI.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
+ }
ImageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
ImageCI.queueFamilyIndexCount = 0;
ImageCI.pQueueFamilyIndices = nullptr;
- ImageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ // initialLayout must be either VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED (11.4)
+ // If it is VK_IMAGE_LAYOUT_PREINITIALIZED, then the image data can be preinitialized by the host
+ // while using this layout, and the transition away from this layout will preserve that data.
+ // If it is VK_IMAGE_LAYOUT_UNDEFINED, then the contents of the data are considered to be undefined,
+ // and the transition away from this layout is not guaranteed to preserve that data.
+ m_CurrentLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ ImageCI.initialLayout = m_CurrentLayout;
#if 0
Desc.Flags = Vk_RESOURCE_FLAG_NONE;
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp
new file mode 100644
index 00000000..3f5710a2
--- /dev/null
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp
@@ -0,0 +1,321 @@
+/* Copyright 2015-2018 Egor Yusov
+*
+* 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
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+*
+* In no event and under no legal theory, whether in tort (including negligence),
+* contract, or otherwise, unless required by applicable law (such as deliberate
+* and grossly negligent acts) or agreed to in writing, shall any Contributor be
+* liable for any damages, including any direct, indirect, special, incidental,
+* or consequential damages of any character arising as a result of this License or
+* out of the use or inability to use the software (including but not limited to damages
+* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+* all other commercial damages or losses), even if such Contributor has been advised
+* of the possibility of such damages.
+*/
+#include <sstream>
+
+#include "VulkanUtilities/VulkanCommandBuffer.h"
+
+namespace VulkanUtilities
+{
+
+static VkPipelineStageFlags PipelineStageFromAccessFlags(VkAccessFlags AccessFlags)
+{
+ // 6.1.3
+ VkPipelineStageFlags Stages = 0;
+
+ while(AccessFlags != 0)
+ {
+ VkAccessFlagBits AccessFlag = static_cast<VkAccessFlagBits>( AccessFlags & (~(AccessFlags-1)));
+ VERIFY_EXPR( AccessFlag != 0 && (AccessFlag & (AccessFlag-1)) == 0 );
+ AccessFlags &= ~AccessFlag;
+
+ static constexpr VkPipelineStageFlags ALL_GRAPHICS_SHADER_STAGES_BITS =
+ VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
+ VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
+ VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
+ VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+
+ // An application MUST NOT specify an access flag in a synchronization command if it does not include a
+ // pipeline stage in the corresponding stage mask that is able to perform accesses of that type.
+ // A table that lists, for each access flag, which pipeline stages can perform that type of access is given in 6.1.3.
+ switch(AccessFlag)
+ {
+ // Read access to an indirect command structure read as part of an indirect drawing or dispatch command
+ case VK_ACCESS_INDIRECT_COMMAND_READ_BIT:
+ Stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
+ break;
+
+ // Read access to an index buffer as part of an indexed drawing command, bound by vkCmdBindIndexBuffer
+ case VK_ACCESS_INDEX_READ_BIT:
+ Stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
+ break;
+
+ // Read access to a vertex buffer as part of a drawing command, bound by vkCmdBindVertexBuffers
+ case VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT:
+ Stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
+ break;
+
+ // Read access to a uniform buffer
+ case VK_ACCESS_UNIFORM_READ_BIT:
+ Stages |= ALL_GRAPHICS_SHADER_STAGES_BITS | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ break;
+
+ // Read access to an input attachment within a render pass during fragment shading
+ case VK_ACCESS_INPUT_ATTACHMENT_READ_BIT:
+ Stages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ break;
+
+ // Read access to a storage buffer, uniform texel buffer, storage texel buffer, sampled image, or storage image
+ case VK_ACCESS_SHADER_READ_BIT:
+ Stages |= ALL_GRAPHICS_SHADER_STAGES_BITS | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ break;
+
+ // Write access to a storage buffer, storage texel buffer, or storage image
+ case VK_ACCESS_SHADER_WRITE_BIT:
+ Stages |= ALL_GRAPHICS_SHADER_STAGES_BITS | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ break;
+
+ // Read access to a color attachment, such as via blending, logic operations, or via certain subpass load operations
+ case VK_ACCESS_COLOR_ATTACHMENT_READ_BIT:
+ Stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ break;
+
+ // Write access to a color or resolve attachment during a render pass or via certain subpass load and store operations
+ case VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT:
+ Stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ break;
+
+ // Read access to a depth/stencil attachment, via depth or stencil operations or via certain subpass load operations
+ case VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT:
+ Stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
+ break;
+
+ // Write access to a depth/stencil attachment, via depth or stencil operations or via certain subpass load and store operations
+ case VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT:
+ Stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
+ break;
+
+ // Read access to an image or buffer in a copy operation
+ case VK_ACCESS_TRANSFER_READ_BIT:
+ Stages |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ break;
+
+ // Write access to an image or buffer in a clear or copy operation
+ case VK_ACCESS_TRANSFER_WRITE_BIT:
+ Stages |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ break;
+
+ // Read access by a host operation. Accesses of this type are not performed through a resource, but directly on memory
+ case VK_ACCESS_HOST_READ_BIT:
+ Stages |= VK_PIPELINE_STAGE_HOST_BIT;
+ break;
+
+ // Write access by a host operation. Accesses of this type are not performed through a resource, but directly on memory
+ case VK_ACCESS_HOST_WRITE_BIT:
+ Stages |= VK_PIPELINE_STAGE_HOST_BIT;
+ break;
+
+ // Read access via non-specific entities. When included in a destination access mask, makes all available writes
+ // visible to all future read accesses on entities known to the Vulkan device
+ case VK_ACCESS_MEMORY_READ_BIT:
+ break;
+
+ // Write access via non-specific entities. hen included in a source access mask, all writes that are performed
+ // by entities known to the Vulkan device are made available. When included in a destination access mask, makes
+ // all available writes visible to all future write accesses on entities known to the Vulkan device.
+ case VK_ACCESS_MEMORY_WRITE_BIT:
+ break;
+
+ default:
+ UNEXPECTED("Unknown memory access flag");
+ }
+ }
+ return Stages;
+}
+
+void VulkanCommandBuffer::TransitionImageLayout(VkCommandBuffer CmdBuffer,
+ VkImage Image,
+ VkImageAspectFlags AspectMask,
+ VkImageLayout OldLayout,
+ VkImageLayout NewLayout,
+ const VkImageSubresourceRange& SubresRange,
+ VkPipelineStageFlags SrcStages,
+ VkPipelineStageFlags DestStages)
+{
+ VERIFY_EXPR(CmdBuffer != VK_NULL_HANDLE);
+
+ VkImageMemoryBarrier ImgBarrier = {};
+ ImgBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ ImgBarrier.pNext = nullptr;
+ ImgBarrier.srcAccessMask = 0;
+ ImgBarrier.dstAccessMask = 0;
+ ImgBarrier.oldLayout = OldLayout;
+ ImgBarrier.newLayout = NewLayout;
+ 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)
+ {
+ // does not support device access. This layout must only be used as the initialLayout member
+ // of VkImageCreateInfo or VkAttachmentDescription, or as the oldLayout in an image transition.
+ // When transitioning out of this layout, the contents of the memory are not guaranteed to be preserved (11.4)
+ case VK_IMAGE_LAYOUT_UNDEFINED:
+ break;
+
+ // supports all types of device access
+ case VK_IMAGE_LAYOUT_GENERAL:
+ UNEXPECTED("General layout is not recommended");
+ break;
+
+ // 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;
+ 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;
+ 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)
+ case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
+ ImgBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
+ break;
+
+ // must only be used as a read-only image in a shader (which can be read as a sampled image,
+ // combined image/sampler and/or input attachment) (11.4)
+ case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
+ ImgBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ break;
+
+ // must only be used as a source image of a transfer command (11.4)
+ case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
+ ImgBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+ break;
+
+ // must only be used as a destination image of a transfer command (11.4)
+ case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
+ ImgBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ break;
+
+ // does not support device access. This layout must only be used as the initialLayout member
+ // of VkImageCreateInfo or VkAttachmentDescription, or as the oldLayout in an image transition.
+ // When transitioning out of this layout, the contents of the memory are preserved. (11.4)
+ case VK_IMAGE_LAYOUT_PREINITIALIZED:
+ ImgBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
+ break;
+
+ case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
+ ImgBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
+ break;
+
+ case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
+ ImgBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
+ break;
+
+ case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
+ ImgBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
+ break;
+
+ default:
+ UNEXPECTED("Unexpected image layout");
+ break;
+ }
+
+
+ switch (NewLayout)
+ {
+ case VK_IMAGE_LAYOUT_UNDEFINED:
+ UNEXPECTED("The new layout used in a transition must not be VK_IMAGE_LAYOUT_UNDEFINED. "
+ "This layout must only be used as the initialLayout member of VkImageCreateInfo "
+ "or VkAttachmentDescription, or as the oldLayout in an image transition. (11.4)");
+ break;
+
+ case VK_IMAGE_LAYOUT_GENERAL:
+ UNEXPECTED("General layout is not recommended due to inefficiency");
+ break;
+
+ case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
+ ImgBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ break;
+
+ case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
+ ImgBarrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+ break;
+
+ case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
+ ImgBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
+ break;
+
+ case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
+ ImgBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
+ break;
+
+ case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
+ ImgBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+ break;
+
+ case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
+ ImgBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ break;
+
+ case VK_IMAGE_LAYOUT_PREINITIALIZED:
+ UNEXPECTED("The new layout used in a transition must not be VK_IMAGE_LAYOUT_PREINITIALIZED. "
+ "This layout must only be used as the initialLayout member of VkImageCreateInfo "
+ "or VkAttachmentDescription, or as the oldLayout in an image transition. (11.4)");
+ break;
+
+ case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
+ ImgBarrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
+ break;
+
+ case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
+ ImgBarrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
+ break;
+
+ case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
+ ImgBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
+ break;
+
+ default:
+ UNEXPECTED("Unexpected image layout");
+ break;
+ }
+
+ if(SrcStages == 0)
+ SrcStages = PipelineStageFromAccessFlags(ImgBarrier.srcAccessMask);
+
+ if (DestStages == 0)
+ DestStages = PipelineStageFromAccessFlags(ImgBarrier.dstAccessMask);
+
+ vkCmdPipelineBarrier(CmdBuffer,
+ SrcStages,
+ DestStages,
+ 0, // a bitmask specifying how execution and memory dependencies are formed
+ 0, // memoryBarrierCount
+ nullptr, // pMemoryBarriers
+ 0, // bufferMemoryBarrierCount
+ nullptr, // pBufferMemoryBarriers
+ 1,
+ &ImgBarrier);
+}
+
+void VulkanCommandBuffer::FlushBarriers()
+{
+
+}
+
+}