summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-04-04 15:53:29 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-04-04 15:53:29 +0000
commita80f0e8f4f2f4b0809cbdcbdd71005fd0af69c56 (patch)
tree5f6cff52d8e09e6f5f9adcc68327477334d0d088 /Graphics/GraphicsEngineVulkan
parentRearranged some basic graphics types to reduce sizeof(PipelineStateDesc) from... (diff)
downloadDiligentCore-a80f0e8f4f2f4b0809cbdcbdd71005fd0af69c56.tar.gz
DiligentCore-a80f0e8f4f2f4b0809cbdcbdd71005fd0af69c56.zip
First implementation of buffer in Vulkan
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h16
-rw-r--r--Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h12
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h10
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h9
-rw-r--r--Graphics/GraphicsEngineVulkan/interface/BufferViewVk.h4
-rw-r--r--Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp4
-rw-r--r--Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp230
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp12
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp6
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp47
10 files changed, 247 insertions, 103 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h b/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h
index 3c6770ef..ff203851 100644
--- a/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h
@@ -42,19 +42,19 @@ public:
typedef BufferViewBase<IBufferViewVk> TBufferViewBase;
BufferViewVkImpl( IReferenceCounters *pRefCounters,
- IRenderDevice *pDevice,
- const BufferViewDesc& ViewDesc,
- class IBuffer *pBuffer,
- DescriptorHeapAllocation &&HandleAlloc,
- bool bIsDefaultView);
+ IRenderDevice *pDevice,
+ const BufferViewDesc& ViewDesc,
+ class IBuffer *pBuffer,
+ VkBufferView vkBuffView,
+ bool bIsDefaultView);
virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface );
- //virtual Vk_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle()override{return m_DescriptorHandle.GetCpuHandle();}
+ virtual VkBufferView GetVkBufferView()override final{return m_VkBuffView;}
protected:
- // Allocation in a CPU-only descriptor heap
- DescriptorHeapAllocation m_DescriptorHandle;
+
+ VkBufferView m_VkBuffView;
};
}
diff --git a/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h b/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h
index f4cc6c96..ba94b7b9 100644
--- a/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h
@@ -121,11 +121,11 @@ public:
*/
private:
virtual void CreateViewInternal( const struct BufferViewDesc &ViewDesc, IBufferView **ppView, bool bIsDefaultView )override;
-/*
- void CreateUAV( struct BufferViewDesc &UAVDesc, Vk_CPU_DESCRIPTOR_HANDLE UAVDescriptor );
- void CreateSRV( struct BufferViewDesc &SRVDesc, Vk_CPU_DESCRIPTOR_HANDLE SRVDescriptor );
- void CreateCBV( Vk_CPU_DESCRIPTOR_HANDLE CBVDescriptor );
- DescriptorHeapAllocation m_CBVDescriptorAllocation;
+
+ VkBufferView CreateUAV(struct BufferViewDesc &UAVDesc);
+ VkBufferView CreateSRV(struct BufferViewDesc &SRVDesc);
+ VkBufferView CreateCBV(struct BufferViewDesc &CBVDesc);
+ /* DescriptorHeapAllocation m_CBVDescriptorAllocation;
#ifdef _DEBUG
std::vector< std::pair<MAP_TYPE, Uint32>, STDAllocatorRawMem<std::pair<MAP_TYPE, Uint32>> > m_DbgMapType;
@@ -134,6 +134,8 @@ private:
friend class DeviceContextVkImpl;
// Array of dynamic allocations for every device context
std::vector<DynamicAllocation, STDAllocatorRawMem<DynamicAllocation> > m_DynamicData;*/
+ VkBuffer m_VkBuffer = VK_NULL_HANDLE;
+ VkDeviceMemory m_BufferMemory = VK_NULL_HANDLE;
};
}
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
index dc915d75..b2be3781 100644
--- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
@@ -96,14 +96,17 @@ public:
CommandContext* AllocateCommandContext(const Char *ID = "");
void CloseAndExecuteCommandContext(CommandContext *pCtx, bool DiscardStaleObjects);
void DisposeCommandContext(CommandContext*);
-
- void SafeReleaseVkObject(IVkObject* pObj);
+*/
+ void SafeReleaseVkBuffer(VkBuffer vkBuffer);
+
+/*
void FinishFrame(bool ReleaseAllResources);
virtual void FinishFrame()override final { FinishFrame(false); }
DynamicUploadHeap* RequestUploadHeap();
void ReleaseUploadHeap(DynamicUploadHeap* pUploadHeap);
*/
+
std::shared_ptr<VulkanUtilities::VulkanInstance> GetVulkanInstance(){return m_VulkanInstance;}
VulkanUtilities::VulkanPhysicalDevice &GetPhysicalDevice(){return *m_PhysicalDevice;}
@@ -174,8 +177,9 @@ private:
std::mutex m_ReleaseQueueMutex;
typedef std::pair<Uint64, CComPtr<IVkObject> > ReleaseQueueElemType;
std::deque< ReleaseQueueElemType, STDAllocatorRawMem<ReleaseQueueElemType> > m_VkObjReleaseQueue;
-
+#endif
std::mutex m_StaleObjectsMutex;
+#if 0
std::deque< ReleaseQueueElemType, STDAllocatorRawMem<ReleaseQueueElemType> > m_StaleVkObjects;
std::mutex m_UploadHeapMutex;
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h
index ccf06ec8..8b592720 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h
@@ -36,12 +36,15 @@ namespace VulkanUtilities
VkPhysicalDevice GetVkDeviceHandle()const{return m_VkDevice;}
bool IsExtensionSupported(const char *ExtensionName);
bool CheckPresentSupport(uint32_t queueFamilyIndex, VkSurfaceKHR VkSurface)const;
+
+ static constexpr uint32_t InvalidMemoryTypeIndex = static_cast<uint32_t>(-1);
+ uint32_t GetMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties);
private:
const VkPhysicalDevice m_VkDevice;
- VkPhysicalDeviceProperties m_Properties;
- VkPhysicalDeviceFeatures m_Features;
- VkPhysicalDeviceMemoryProperties m_MemoryProperties;
+ VkPhysicalDeviceProperties m_Properties = {};
+ VkPhysicalDeviceFeatures m_Features = {};
+ VkPhysicalDeviceMemoryProperties m_MemoryProperties = {};
std::vector<VkQueueFamilyProperties> m_QueueFamilyProperties;
std::vector<VkExtensionProperties> m_SupportedExtensions;
};
diff --git a/Graphics/GraphicsEngineVulkan/interface/BufferViewVk.h b/Graphics/GraphicsEngineVulkan/interface/BufferViewVk.h
index af95a79c..eca95c91 100644
--- a/Graphics/GraphicsEngineVulkan/interface/BufferViewVk.h
+++ b/Graphics/GraphicsEngineVulkan/interface/BufferViewVk.h
@@ -40,8 +40,8 @@ class IBufferViewVk : public IBufferView
{
public:
- /// Returns CPU descriptor handle of the buffer view.
- //virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() = 0;
+ /// Returns Vulkan buffer view object.
+ virtual VkBufferView GetVkBufferView() = 0;
};
}
diff --git a/Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp
index d8250600..ceb6f830 100644
--- a/Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp
@@ -31,10 +31,10 @@ BufferViewVkImpl::BufferViewVkImpl( IReferenceCounters *pRefCounters,
IRenderDevice *pDevice,
const BufferViewDesc& ViewDesc,
IBuffer *pBuffer,
- DescriptorHeapAllocation &&HandleAlloc,
+ VkBufferView vkBuffView,
bool bIsDefaultView ) :
TBufferViewBase( pRefCounters, pDevice, ViewDesc, pBuffer, bIsDefaultView ),
- m_DescriptorHandle( std::move(HandleAlloc) )
+ m_VkBuffView(vkBuffView)
{
}
diff --git a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp
index dde4f8de..5b6fddf4 100644
--- a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp
@@ -25,12 +25,12 @@
#include "BufferVkImpl.h"
#include "RenderDeviceVkImpl.h"
#include "DeviceContextVkImpl.h"
-//#include "VkTypeConversions.h"
+//#include "VulkanTypeConversions.h"
#include "BufferViewVkImpl.h"
#include "GraphicsAccessories.h"
-//#include "DXGITypeConversions.h"
#include "EngineMemory.h"
#include "StringTools.h"
+#include "VulkanUtilities/VulkanDebug.h"
namespace Diligent
{
@@ -47,7 +47,6 @@ BufferVkImpl :: BufferVkImpl(IReferenceCounters *pRefCounters,
m_DynamicData(BuffDesc.Usage == USAGE_DYNAMIC ? (1 + pRenderDeviceVk->GetNumDeferredContexts()) : 0, DynamicAllocation(), STD_ALLOCATOR_RAW_MEM(DynamicAllocation, GetRawAllocator(), "Allocator for vector<DynamicAllocation>"))
*/
{
-#if 0
#define LOG_BUFFER_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Buffer \"", BuffDesc.Name ? BuffDesc.Name : "", "\": ", ##__VA_ARGS__);
if( m_Desc.Usage == USAGE_STATIC && BuffData.pData == nullptr )
@@ -56,10 +55,6 @@ BufferVkImpl :: BufferVkImpl(IReferenceCounters *pRefCounters,
if( m_Desc.Usage == USAGE_DYNAMIC && BuffData.pData != nullptr )
LOG_BUFFER_ERROR_AND_THROW("Dynamic buffer must be initialized via Map()")
- Uint32 AlignmentMask = 1;
- if (m_Desc.BindFlags & BIND_UNIFORM_BUFFER)
- AlignmentMask = 255;
-
if (m_Desc.Usage == USAGE_CPU_ACCESSIBLE)
{
if (m_Desc.CPUAccessFlags != CPU_ACCESS_WRITE && m_Desc.CPUAccessFlags != CPU_ACCESS_READ)
@@ -69,75 +64,150 @@ BufferVkImpl :: BufferVkImpl(IReferenceCounters *pRefCounters,
{
if(BuffData.pData != nullptr )
LOG_BUFFER_ERROR_AND_THROW("CPU-writable staging buffers must be updated via map")
-
- AlignmentMask = Vk_TEXTURE_DATA_PITCH_ALIGNMENT - 1;
}
}
-
- if(AlignmentMask != 1)
- m_Desc.uiSizeInBytes = (m_Desc.uiSizeInBytes + AlignmentMask) & (~AlignmentMask);
if(m_Desc.Usage == USAGE_DYNAMIC && (m_Desc.BindFlags & (BIND_SHADER_RESOURCE|BIND_UNORDERED_ACCESS)) == 0)
{
+ UNSUPPORTED("Dynamic buffers are not yet implemented");
// Dynamic constant/vertex/index buffers are suballocated in the upload heap when Map() is called.
// Dynamic buffers with SRV or UAV flags need to be allocated in GPU-only memory
// Dynamic upload heap buffer is always in Vk_RESOURCE_STATE_GENERIC_READ state
-
+#if 0
m_UsageState = Vk_RESOURCE_STATE_GENERIC_READ;
VERIFY_EXPR(m_DynamicData.size() == 1 + pRenderDeviceVk->GetNumDeferredContexts());
+#endif
}
else
{
- Vk_RESOURCE_DESC VkBuffDesc = {};
- VkBuffDesc.Dimension = Vk_RESOURCE_DIMENSION_BUFFER;
- VkBuffDesc.Alignment = 0;
- VkBuffDesc.Width = m_Desc.uiSizeInBytes;
- VkBuffDesc.Height = 1;
- VkBuffDesc.DepthOrArraySize = 1;
- VkBuffDesc.MipLevels = 1;
- VkBuffDesc.Format = DXGI_FORMAT_UNKNOWN;
- VkBuffDesc.SampleDesc.Count = 1;
- VkBuffDesc.SampleDesc.Quality = 0;
- // Layout must be Vk_TEXTURE_LAYOUT_ROW_MAJOR, as buffer memory layouts are
- // understood by applications and row-major texture data is commonly marshaled through buffers.
- VkBuffDesc.Layout = Vk_TEXTURE_LAYOUT_ROW_MAJOR;
- VkBuffDesc.Flags = Vk_RESOURCE_FLAG_NONE;
- if( m_Desc.BindFlags & BIND_UNORDERED_ACCESS )
- VkBuffDesc.Flags |= Vk_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
- if( !(m_Desc.BindFlags & BIND_SHADER_RESOURCE) )
- VkBuffDesc.Flags |= Vk_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
-
- auto *pVkDevice = pRenderDeviceVk->GetVkDevice();
-
- Vk_HEAP_PROPERTIES HeapProps;
+ VkBufferCreateInfo VkBuffCI = {};
+ VkBuffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ VkBuffCI.pNext = nullptr;
+ VkBuffCI.flags = 0; // VK_BUFFER_CREATE_SPARSE_BINDING_BIT, VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT, VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
+ VkBuffCI.size = m_Desc.uiSizeInBytes;
+ VkBuffCI.usage =
+ VK_BUFFER_USAGE_TRANSFER_SRC_BIT | // The buffer can be used as the source of a transfer command
+ VK_BUFFER_USAGE_TRANSFER_DST_BIT; // The buffer can be used as the destination of a transfer command
+ if (m_Desc.BindFlags & BIND_UNORDERED_ACCESS)
+ VkBuffCI.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; // | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
+ if (m_Desc.BindFlags & BIND_SHADER_RESOURCE)
+ VkBuffCI.usage |= VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER | VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ if (m_Desc.BindFlags & BIND_VERTEX_BUFFER)
+ VkBuffCI.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ if (m_Desc.BindFlags & BIND_INDEX_BUFFER)
+ VkBuffCI.usage |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
+ if (m_Desc.BindFlags & BIND_INDIRECT_DRAW_ARGS)
+ VkBuffCI.usage |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
+ if (m_Desc.BindFlags & BIND_UNIFORM_BUFFER)
+ VkBuffCI.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; // | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
+
+ VkBuffCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; // sharing mode of the buffer when it will be accessed by multiple queue families.
+ VkBuffCI.queueFamilyIndexCount = 0; // number of entries in the pQueueFamilyIndices array
+ VkBuffCI.pQueueFamilyIndices = nullptr; // list of queue families that will access this buffer
+ // (ignored if sharingMode is not VK_SHARING_MODE_CONCURRENT).
+
+ auto vkDevice = pRenderDeviceVk->GetVkDevice();
+ auto err = vkCreateBuffer(vkDevice, &VkBuffCI, nullptr, &m_VkBuffer);
+ CHECK_VK_ERROR_AND_THROW(err, "Failed to create Vulkan buffer object");
+
+ VkMemoryRequirements MemReqs = {};
+ vkGetBufferMemoryRequirements(vkDevice, m_VkBuffer, &MemReqs);
+
+ VkMemoryAllocateInfo MemAlloc = {};
+ MemAlloc.pNext = nullptr;
+ MemAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ MemAlloc.allocationSize = MemReqs.size;
+
+ auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice();
+
+ VkMemoryPropertyFlags BufferMemoryFlags = 0;
if (m_Desc.Usage == USAGE_CPU_ACCESSIBLE)
- HeapProps.Type = m_Desc.CPUAccessFlags == CPU_ACCESS_READ ? Vk_HEAP_TYPE_READBACK : Vk_HEAP_TYPE_UPLOAD;
+ BufferMemoryFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
else
- HeapProps.Type = Vk_HEAP_TYPE_DEFAULT;
+ BufferMemoryFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
- if(HeapProps.Type == Vk_HEAP_TYPE_READBACK)
- m_UsageState = Vk_RESOURCE_STATE_COPY_DEST;
- else if(HeapProps.Type == Vk_HEAP_TYPE_UPLOAD)
- m_UsageState = Vk_RESOURCE_STATE_GENERIC_READ;
- HeapProps.CPUPageProperty = Vk_CPU_PAGE_PROPERTY_UNKNOWN;
- HeapProps.MemoryPoolPreference = Vk_MEMORY_POOL_UNKNOWN;
- HeapProps.CreationNodeMask = 1;
- HeapProps.VisibleNodeMask = 1;
+ // memoryTypeBits is a bitmask and contains one bit set for every supported memory type for the resource.
+ // Bit i is set if and only if the memory type i in the VkPhysicalDeviceMemoryProperties structure for the
+ // physical device is supported for the resource.
+ MemAlloc.memoryTypeIndex = PhysicalDevice.GetMemoryTypeIndex(MemReqs.memoryTypeBits, BufferMemoryFlags);
+ if(BufferMemoryFlags == VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
+ {
+ // There must be at least one memory type with the DEVICE_LOCAL_BIT bit set
+ VERIFY(MemAlloc.memoryTypeIndex != VulkanUtilities::VulkanPhysicalDevice::InvalidMemoryTypeIndex,
+ "Vulkan spec requires that memoryTypeBits member always contains "
+ "at least one bit set corresponding to a VkMemoryType with a propertyFlags that has the "
+ "VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT bit set (11.6)");
+ }
+ else if(MemAlloc.memoryTypeIndex != VulkanUtilities::VulkanPhysicalDevice::InvalidMemoryTypeIndex)
+ {
+ LOG_ERROR_AND_THROW("Failed to find suitable device memory type for a buffer");
+ }
- bool bInitializeBuffer = (BuffData.pData != nullptr && BuffData.DataSize > 0);
- if(bInitializeBuffer)
- m_UsageState = Vk_RESOURCE_STATE_COPY_DEST;
+ err = vkAllocateMemory(vkDevice, &MemAlloc, nullptr, &m_BufferMemory);
+ CHECK_VK_ERROR_AND_THROW(err, "Failed to allocate device local memory for a Vulkan buffer object");
- auto hr = pVkDevice->CreateCommittedResource( &HeapProps, Vk_HEAP_FLAG_NONE,
- &VkBuffDesc, m_UsageState, nullptr, __uuidof(m_pVkResource), reinterpret_cast<void**>(static_cast<IVkResource**>(&m_pVkResource)) );
- if(FAILED(hr))
- LOG_ERROR_AND_THROW("Failed to create Vk buffer");
+ err = vkBindBufferMemory(vkDevice, m_VkBuffer, m_BufferMemory, 0 /*offset*/);
+ CHECK_VK_ERROR_AND_THROW(err, "Failed to bind buffer memory");
+
+ bool bInitializeBuffer = (BuffData.pData != nullptr && BuffData.DataSize > 0);
+ //if(bInitializeBuffer)
+ // m_UsageState = Vk_RESOURCE_STATE_COPY_DEST;
if( *m_Desc.Name != 0)
- m_pVkResource->SetName(WidenString(m_Desc.Name).c_str());
+ VulkanUtilities::SetBufferName(vkDevice, m_VkBuffer, m_Desc.Name);
if( bInitializeBuffer )
{
+ VkBufferCreateInfo VkStaginBuffCI = VkBuffCI;
+ VkStaginBuffCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+
+ VkBuffer vkStagingBuffer = VK_NULL_HANDLE;
+ err = vkCreateBuffer(vkDevice, &VkStaginBuffCI, nullptr, &vkStagingBuffer);
+ CHECK_VK_ERROR_AND_THROW(err, "Failed to create staging buffer");
+
+ VulkanUtilities::SetBufferName(vkDevice, vkStagingBuffer, "Staging buffer");
+
+ VkMemoryRequirements StagingBufferMemReqs = {};
+ vkGetBufferMemoryRequirements(vkDevice, vkStagingBuffer, &StagingBufferMemReqs);
+
+ VkMemoryAllocateInfo StagingMemAlloc = {};
+ StagingMemAlloc.pNext = nullptr;
+ StagingMemAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ StagingMemAlloc.allocationSize = StagingBufferMemReqs.size;
+
+ // VK_MEMORY_PROPERTY_HOST_COHERENT_BIT bit specifies that the host cache management commands vkFlushMappedMemoryRanges
+ // and vkInvalidateMappedMemoryRanges are NOT needed to flush host writes to the device or make device writes visible
+ // to the host (10.2)
+ StagingMemAlloc.memoryTypeIndex = PhysicalDevice.GetMemoryTypeIndex(StagingBufferMemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+
+ VERIFY(StagingMemAlloc.memoryTypeIndex != VulkanUtilities::VulkanPhysicalDevice::InvalidMemoryTypeIndex,
+ "Vulkan spec requires that for a VkBuffer not created with the "
+ "VK_BUFFER_CREATE_SPARSE_BINDING_BIT bit set, the memoryTypeBits member always contains at least one bit set "
+ "corresponding to a VkMemoryType with a propertyFlags that has both the VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT bit "
+ "and the VK_MEMORY_PROPERTY_HOST_COHERENT_BIT bit set(11.6)");
+
+ VkDeviceMemory vkStagingBufferMemory = VK_NULL_HANDLE;
+ err = vkAllocateMemory(vkDevice, &StagingMemAlloc, nullptr, &vkStagingBufferMemory);
+ CHECK_VK_ERROR_AND_THROW(err, "Failed to allocate memory for a staging buffer object");
+
+ {
+ void *StagingData = nullptr;
+ err = vkMapMemory(vkDevice, vkStagingBufferMemory,
+ 0, // offset
+ StagingMemAlloc.allocationSize,
+ 0, // flags, reserved for future use
+ &StagingData);
+ CHECK_VK_ERROR_AND_THROW(err, "Failed to map staging memory");
+ memcpy(StagingData, BuffData.pData, BuffData.DataSize);
+ vkUnmapMemory(vkDevice, vkStagingBufferMemory);
+ }
+
+ err = vkBindBufferMemory(vkDevice, vkStagingBuffer, vkStagingBufferMemory, 0 /*offset*/);
+ CHECK_VK_ERROR_AND_THROW(err, "Failed to bind staging bufer memory");
+
+
+
+#if 0
Vk_HEAP_PROPERTIES UploadHeapProps;
UploadHeapProps.Type = Vk_HEAP_TYPE_UPLOAD;
UploadHeapProps.CPUPageProperty = Vk_CPU_PAGE_PROPERTY_UNKNOWN;
@@ -192,15 +262,15 @@ BufferVkImpl :: BufferVkImpl(IReferenceCounters *pRefCounters,
// until copy operation is complete. This must be done after
// submitting command list for execution!
pRenderDeviceVk->SafeReleaseVkObject(UploadBuffer);
+#endif
}
- if (m_Desc.BindFlags & BIND_UNIFORM_BUFFER)
- {
- m_CBVDescriptorAllocation = pRenderDeviceVk->AllocateDescriptor(Vk_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- CreateCBV(m_CBVDescriptorAllocation.GetCpuHandle());
- }
+ //if (m_Desc.BindFlags & BIND_UNIFORM_BUFFER)
+ //{
+ // m_CBVDescriptorAllocation = pRenderDeviceVk->AllocateDescriptor(Vk_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+ // CreateCBV(m_CBVDescriptorAllocation.GetCpuHandle());
+ //}
}
-#endif
}
@@ -270,11 +340,12 @@ BufferVkImpl :: BufferVkImpl(IReferenceCounters *pRefCounters,
}
BufferVkImpl :: ~BufferVkImpl()
{
-#if 0
// Vk object can only be destroyed when it is no longer used by the GPU
- auto *pDeviceVkImpl = ValidatedCast<RenderDeviceVkImpl>(GetDevice());
- pDeviceVkImpl->SafeReleaseVkObject(m_pVkResource);
-#endif
+ if(m_VkBuffer!=VK_NULL_HANDLE)
+ {
+ auto *pDeviceVkImpl = ValidatedCast<RenderDeviceVkImpl>(GetDevice());
+ pDeviceVkImpl->SafeReleaseVkBuffer(m_VkBuffer);
+ }
}
IMPLEMENT_QUERY_INTERFACE( BufferVkImpl, IID_BufferVk, TBufferBase )
@@ -412,7 +483,7 @@ void BufferVkImpl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, IBuff
VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" );
*ppView = nullptr;
-#if 0
+
try
{
auto *pDeviceVkImpl = ValidatedCast<RenderDeviceVkImpl>(GetDevice());
@@ -422,17 +493,15 @@ void BufferVkImpl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, IBuff
BufferViewDesc ViewDesc = OrigViewDesc;
if( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS )
{
- auto UAVHandleAlloc = pDeviceVkImpl->AllocateDescriptor(Vk_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- CreateUAV( ViewDesc, UAVHandleAlloc.GetCpuHandle() );
+ auto UAV = CreateUAV(ViewDesc);
*ppView = NEW_RC_OBJ(BuffViewAllocator, "BufferViewVkImpl instance", BufferViewVkImpl, bIsDefaultView ? this : nullptr)
- (GetDevice(), ViewDesc, this, std::move(UAVHandleAlloc), bIsDefaultView );
+ (GetDevice(), ViewDesc, this, UAV, bIsDefaultView );
}
else if( ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE )
{
- auto SRVHandleAlloc = pDeviceVkImpl->AllocateDescriptor(Vk_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- CreateSRV( ViewDesc, SRVHandleAlloc.GetCpuHandle() );
+ auto SRV = CreateSRV(ViewDesc);
*ppView = NEW_RC_OBJ(BuffViewAllocator, "BufferViewVkImpl instance", BufferViewVkImpl, bIsDefaultView ? this : nullptr)
- (GetDevice(), ViewDesc, this, std::move(SRVHandleAlloc), bIsDefaultView );
+ (GetDevice(), ViewDesc, this, SRV, bIsDefaultView );
}
if( !bIsDefaultView && *ppView )
@@ -443,42 +512,49 @@ void BufferVkImpl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, IBuff
const auto *ViewTypeName = GetBufferViewTypeLiteralName(OrigViewDesc.ViewType);
LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for buffer \"", m_Desc.Name, "\"" );
}
-#endif
}
-#if 0
-void BufferVkImpl::CreateUAV( BufferViewDesc &UAVDesc, Vk_CPU_DESCRIPTOR_HANDLE UAVDescriptor )
+
+VkBufferView BufferVkImpl::CreateUAV(BufferViewDesc &UAVDesc)
{
CorrectBufferViewDesc( UAVDesc );
-
+#if 0
Vk_UNORDERED_ACCESS_VIEW_DESC Vk_UAVDesc;
BufferViewDesc_to_Vk_UAV_DESC(m_Desc, UAVDesc, Vk_UAVDesc);
auto *pDeviceVk = static_cast<RenderDeviceVkImpl*>(GetDevice())->GetVkDevice();
pDeviceVk->CreateUnorderedAccessView( m_pVkResource, nullptr, &Vk_UAVDesc, UAVDescriptor );
+#endif
+ return VK_NULL_HANDLE;
}
-void BufferVkImpl::CreateSRV( struct BufferViewDesc &SRVDesc, Vk_CPU_DESCRIPTOR_HANDLE SRVDescriptor )
+VkBufferView BufferVkImpl::CreateSRV(BufferViewDesc &SRVDesc)
{
CorrectBufferViewDesc( SRVDesc );
-
+#if 0
Vk_SHADER_RESOURCE_VIEW_DESC Vk_SRVDesc;
BufferViewDesc_to_Vk_SRV_DESC(m_Desc, SRVDesc, Vk_SRVDesc);
auto *pDeviceVk = static_cast<RenderDeviceVkImpl*>(GetDevice())->GetVkDevice();
pDeviceVk->CreateShaderResourceView( m_pVkResource, &Vk_SRVDesc, SRVDescriptor );
+#endif
+ return VK_NULL_HANDLE;
}
-void BufferVkImpl::CreateCBV(Vk_CPU_DESCRIPTOR_HANDLE CBVDescriptor)
+VkBufferView BufferVkImpl::CreateCBV(BufferViewDesc &CBVDesc)
{
+#if 0
Vk_CONSTANT_BUFFER_VIEW_DESC Vk_CBVDesc;
Vk_CBVDesc.BufferLocation = m_pVkResource->GetGPUVirtualAddress();
Vk_CBVDesc.SizeInBytes = m_Desc.uiSizeInBytes;
auto *pDeviceVk = static_cast<RenderDeviceVkImpl*>(GetDevice())->GetVkDevice();
pDeviceVk->CreateConstantBufferView( &Vk_CBVDesc, CBVDescriptor );
+#endif
+ return VK_NULL_HANDLE;
}
+#if 0
#ifdef _DEBUG
void BufferVkImpl::DbgVerifyDynamicAllocation(Uint32 ContextId)
{
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp
index 6edde2bc..36118793 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp
@@ -154,7 +154,8 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk( const EngineVkAttribs& Crea
// boolean indicators of all the features to be enabled.
std::vector<const char*> DeviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
- if (PhysicalDevice->IsExtensionSupported(VK_EXT_DEBUG_MARKER_EXTENSION_NAME))
+ const bool DebugMarkersSupported = PhysicalDevice->IsExtensionSupported(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
+ if (DebugMarkersSupported && CreationAttribs.EnableValidation)
{
DeviceExtensions.push_back(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
}
@@ -166,13 +167,20 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk( const EngineVkAttribs& Crea
auto res = vkCreateDevice(PhysicalDevice->GetVkDeviceHandle(), &DeviceCreateInfo, Instance->GetVkAllocator(), &VulkanDevice);
CHECK_VK_ERROR_AND_THROW(res, "Failed to create logical device");
+ if (CreationAttribs.EnableValidation)
+ {
+ if(DebugMarkersSupported)
+ VulkanUtilities::SetupDebugMarkers(VulkanDevice);
+ else
+ LOG_INFO_MESSAGE("Debug marker extensions is not found on the system");
+ }
+
VkQueue Queue = VK_NULL_HANDLE;
vkGetDeviceQueue(VulkanDevice,
QueueInfo.queueFamilyIndex, // Index of the queue family to which the queue belongs
0, // Index within this queue family of the queue to retrieve
&Queue);
VERIFY_EXPR(Queue != VK_NULL_HANDLE);
-
RefCntAutoPtr<CommandQueueVkImpl> pCmdQueueVk;
auto &RawMemAllocator = GetRawAllocator();
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index cb6f9403..53e28f9a 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -354,16 +354,20 @@ CommandContext* RenderDeviceVkImpl::AllocateCommandContext(const Char *ID)
return ret;
}
+#endif
-void RenderDeviceVkImpl::SafeReleaseVkObject(IVkObject* pObj)
+void RenderDeviceVkImpl::SafeReleaseVkBuffer(VkBuffer vkBuffer)
{
// When Vk object is released, it is first moved into the
// stale objects list. The list is moved into a release queue
// when the next command list is executed.
std::lock_guard<std::mutex> LockGuard(m_StaleObjectsMutex);
+#if 0
m_StaleVkObjects.emplace_back( m_NextCmdListNumber, CComPtr<IVkObject>(pObj) );
+#endif
}
+#if 0
void RenderDeviceVkImpl::DiscardStaleVkObjects(Uint64 CmdListNumber, Uint64 FenceValue)
{
// Only discard these stale objects that were released before CmdListNumber
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
index 1c4d08a7..0ccb1a80 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
@@ -135,4 +135,51 @@ namespace VulkanUtilities
vkGetPhysicalDeviceSurfaceSupportKHR(m_VkDevice, queueFamilyIndex, VkSurface, &PresentSupport);
return PresentSupport == VK_TRUE;
}
+
+
+ // This function is used to find a device memory type that supports all the property flags we request
+ // Params:
+ // * memoryTypeBitsRequirement - a bitmask that contains one bit set for every supported memory type for
+ // the resource. Bit i is set if and only if the memory type i in the
+ // VkPhysicalDeviceMemoryProperties structure for the physical device is
+ // supported for the resource.
+ // * requiredProperties - required memory properties (device local, host visible, etc.)
+ uint32_t VulkanPhysicalDevice::GetMemoryTypeIndex(uint32_t memoryTypeBitsRequirement,
+ VkMemoryPropertyFlags requiredProperties)
+ {
+ // Iterate over all memory types available for the device
+ // For each pair of elements X and Y returned in memoryTypes, X must be placed at a lower index position than Y if:
+ // * either the set of bit flags of X is a strict subset of the set of bit flags of Y.
+ // * or the propertyFlags members of X and Y are equal, and X belongs to a memory heap with greater performance
+
+ for (uint32_t memoryIndex = 0; memoryIndex < m_MemoryProperties.memoryTypeCount; memoryIndex++)
+ {
+ // Each memory type returned by vkGetPhysicalDeviceMemoryProperties must have its propertyFlags set
+ // to one of the following values:
+ // * 0
+ // * HOST_VISIBLE_BIT | HOST_COHERENT_BIT
+ // * HOST_VISIBLE_BIT | HOST_CACHED_BIT
+ // * HOST_VISIBLE_BIT | HOST_CACHED_BIT | HOST_COHERENT_BIT
+ // * DEVICE_LOCAL_BIT
+ // * DEVICE_LOCAL_BIT | HOST_VISIBLE_BIT | HOST_COHERENT_BIT
+ // * DEVICE_LOCAL_BIT | HOST_VISIBLE_BIT | HOST_CACHED_BIT
+ // * DEVICE_LOCAL_BIT | HOST_VISIBLE_BIT | HOST_CACHED_BIT | HOST_COHERENT_BIT
+ // * DEVICE_LOCAL_BIT | LAZILY_ALLOCATED_BIT
+ //
+ // There must be at least one memory type with both the HOST_VISIBLE_BIT and HOST_COHERENT_BIT bits set
+ // There must be at least one memory type with the DEVICE_LOCAL_BIT bit set
+
+ const uint32_t memoryTypeBit = (1 << memoryIndex);
+ const bool isRequiredMemoryType = (memoryTypeBitsRequirement & memoryTypeBit) != 0;
+ if(isRequiredMemoryType)
+ {
+ const VkMemoryPropertyFlags properties = m_MemoryProperties.memoryTypes[memoryIndex].propertyFlags;
+ const bool hasRequiredProperties = (properties & requiredProperties) == requiredProperties;
+
+ if (hasRequiredProperties)
+ return memoryIndex;
+ }
+ }
+ return InvalidMemoryTypeIndex;
+ }
}